Fix warning.
[mono.git] / mcs / gmcs / statement.cs
index 9bd2c9cd21cbf1afddccf5548726cab817eabafc..fedda76d8578739d6b3a478625971df49edfc22b 100644 (file)
@@ -55,16 +55,7 @@ namespace Mono.CSharp {
 
                        return ok;
                }
-               
-               protected void CheckObsolete (Type type)
-               {
-                       ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (type);
-                       if (obsolete_attr == null)
-                               return;
-
-                       AttributeTester.Report_ObsoleteMessage (obsolete_attr, type.FullName, loc);
-               }
-               
+                               
                /// <summary>
                ///   Return value indicates whether all code paths emitted return.
                /// </summary>
@@ -1060,7 +1051,7 @@ namespace Mono.CSharp {
                                if (texpr == null)
                                        return false;
                                
-                               VariableType = texpr.Type;
+                               VariableType = texpr.ResolveType (ec);
                        }
 
                        if (VariableType == TypeManager.void_type) {
@@ -3292,7 +3283,7 @@ namespace Mono.CSharp {
                        public abstract void EmitExit (ILGenerator ig);
                }
 
-               class ExpressionEmitter: Emitter {
+               class ExpressionEmitter : Emitter {
                        public ExpressionEmitter (Expression converted, LocalInfo li) :
                                base (converted, li)
                        {
@@ -3314,7 +3305,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               class StringEmitter: Emitter {
+               class StringEmitter : Emitter {
                        LocalBuilder pinned_string;
                        Location loc;
 
@@ -3373,9 +3364,7 @@ namespace Mono.CSharp {
                        if (texpr == null)
                                return false;
 
-                       expr_type = texpr.Type;
-
-                       CheckObsolete (expr_type);
+                       expr_type = texpr.ResolveType (ec);
 
                        data = new Emitter [declarators.Count];
 
@@ -3434,6 +3423,11 @@ namespace Mono.CSharp {
                                        if (!TypeManager.VerifyUnManaged (child.Type, loc))
                                                return false;
 
+                                       if (!Convert.ImplicitConversionExists (ec, e, expr_type)) {
+                                               e.Error_ValueCannotBeConverted (e.Location, expr_type, false);
+                                               return false;
+                                       }
+
                                        data [i] = new ExpressionEmitter (e, vi);
                                        i++;
 
@@ -3552,7 +3546,7 @@ namespace Mono.CSharp {
                }
        }
        
-       public class Catch: Statement {
+       public class Catch : Statement {
                public readonly string Name;
                public readonly Block  Block;
 
@@ -3595,8 +3589,6 @@ namespace Mono.CSharp {
 
                                        type = te.ResolveType (ec);
 
-                                       CheckObsolete (type);
-
                                        if (type != TypeManager.exception_type && !type.IsSubclassOf (TypeManager.exception_type)){
                                                Error (155, "The type caught or thrown must be derived from System.Exception");
                                                return false;
@@ -3798,7 +3790,6 @@ namespace Mono.CSharp {
                ArrayList var_list;
                Expression expr;
                Type expr_type;
-               Expression conv;
                Expression [] resolved_vars;
                Expression [] converted_vars;
                ExpressionStatement [] assign;
@@ -3822,7 +3813,7 @@ namespace Mono.CSharp {
                        if (texpr == null)
                                return false;
 
-                       expr_type = texpr.Type;
+                       expr_type = texpr.ResolveType (ec);
 
                        //
                        // The type must be an IDisposable or an implicit conversion
@@ -3849,11 +3840,13 @@ namespace Mono.CSharp {
                                        continue;
                                }
 
-                               converted_vars [i] = Convert.ImplicitConversionRequired (
+                               converted_vars [i] = Convert.ImplicitConversion (
                                        ec, var, TypeManager.idisposable_type, loc);
 
-                               if (converted_vars [i] == null)
+                               if (converted_vars [i] == null) {
+                                       Error_IsNotConvertibleToIDisposable ();
                                        return false;
+                               }
 
                                i++;
                        }
@@ -3878,12 +3871,17 @@ namespace Mono.CSharp {
                        return true;
                }
 
+               void Error_IsNotConvertibleToIDisposable ()
+               {
+                       Report.Error (1674, loc, "`{0}': type used in a using statement must be implicitly convertible to `System.IDisposable'",
+                               TypeManager.CSharpName (expr_type));
+               }
+
                bool ResolveExpression (EmitContext ec)
                {
                        if (!TypeManager.ImplementsInterface (expr_type, TypeManager.idisposable_type)){
                                if (Convert.ImplicitConversion (ec, expr, TypeManager.idisposable_type, loc) == null) {
-                                       Report.Error (1674, loc, "`{0}': type used in a using statement must be implicitly convertible to `System.IDisposable'",
-                                               TypeManager.CSharpName (expr_type));
+                                       Error_IsNotConvertibleToIDisposable ();
                                        return false;
                                }
                        }
@@ -3974,10 +3972,8 @@ namespace Mono.CSharp {
                        //
                        ILGenerator ig = ec.ig;
                        local_copy = ig.DeclareLocal (expr_type);
-                       if (conv != null)
-                               conv.Emit (ec);
-                       else
-                               expr.Emit (ec);
+
+                       expr.Emit (ec);
                        ig.Emit (OpCodes.Stloc, local_copy);
 
                        if (emit_finally)
@@ -4132,6 +4128,12 @@ namespace Mono.CSharp {
 
                        Type var_type = texpr.Type;
 
+                       if (expr.eclass == ExprClass.MethodGroup || expr is AnonymousMethod) {
+                               Report.Error (446, expr.Location, "Foreach statement cannot operate on a `{0}'",
+                                       expr.ExprClassName);
+                               return false;
+                       }
+
                        //
                        // We need an instance variable.  Not sure this is the best
                        // way of doing this.
@@ -4141,7 +4143,7 @@ namespace Mono.CSharp {
                        //
                        if (!(expr.eclass == ExprClass.Variable || expr.eclass == ExprClass.Value ||
                              expr.eclass == ExprClass.PropertyAccess || expr.eclass == ExprClass.IndexerAccess)){
-                               collection.error1579 ();
+                               collection.Error_Enumerator ();
                                return false;
                        }
 
@@ -4323,6 +4325,7 @@ namespace Mono.CSharp {
                        MethodInfo move_next;
                        Type var_type, enumerator_type;
                        bool is_disposable;
+                       bool enumerator_found;
 
                        public CollectionForeach (Type var_type, Expression var,
                                                  Expression expr, Statement stmt, Location l)
@@ -4336,20 +4339,9 @@ namespace Mono.CSharp {
 
                        bool GetEnumeratorFilter (EmitContext ec, MethodInfo mi)
                        {
-                               Type [] args = TypeManager.GetArgumentTypes (mi);
-                               if (args != null){
-                                       if (args.Length != 0)
-                                               return false;
-                               }
-
-                               if (TypeManager.IsOverride (mi))
-                                       return false;
-                       
-                               // Check whether GetEnumerator is public
-                               if ((mi.Attributes & MethodAttributes.Public) != MethodAttributes.Public)
-                                       return false;
+                               Type return_type = mi.ReturnType;
 
-                               if ((mi.ReturnType == TypeManager.ienumerator_type) && (mi.DeclaringType == TypeManager.string_type))
+                               if ((return_type == TypeManager.ienumerator_type) && (mi.DeclaringType == TypeManager.string_type))
                                        //
                                        // Apply the same optimization as MS: skip the GetEnumerator
                                        // returning an IEnumerator, and use the one returning a 
@@ -4363,8 +4355,7 @@ namespace Mono.CSharp {
                                // with this `GetEnumerator'
                                //
 
-                               Type return_type = mi.ReturnType;
-                               if (mi.ReturnType == TypeManager.ienumerator_type ||
+                               if (return_type == TypeManager.ienumerator_type ||
                                    TypeManager.ienumerator_type.IsAssignableFrom (return_type) ||
                                    (!RootContext.StdLib && TypeManager.ImplementsInterface (return_type, TypeManager.ienumerator_type))) {
                                        //
@@ -4406,11 +4397,11 @@ namespace Mono.CSharp {
                                        // find if they support the GetEnumerator pattern.
                                        //
 
-                                       if (!FetchMoveNext (ec, return_type))
-                                               return false;
-
-                                       if (!FetchGetCurrent (ec, return_type))
+                                       if (TypeManager.HasElementType (return_type) || !FetchMoveNext (ec, return_type) || !FetchGetCurrent (ec, return_type)) {
+                                               Report.Error (202, loc, "foreach statement requires that the return type `{0}' of `{1}' must have a suitable public MoveNext method and public Current property",
+                                                       TypeManager.CSharpName (return_type), TypeManager.CSharpSignature (mi));
                                                return false;
+                                       }
                                }
 
                                enumerator_type = return_type;
@@ -4495,11 +4486,15 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       public void error1579 ()
+                       public void Error_Enumerator ()
                        {
+                               if (enumerator_found) {
+                                       return;
+                               }
+
                            Report.Error (1579, loc,
-                               "foreach statement cannot operate on variables of type `{0}' because it does not contain a definition for `GetEnumerator' or is not accessible",
-                               TypeManager.CSharpName (expr.Type));
+                                       "foreach statement cannot operate on variables of type `{0}' because it does not contain a definition for `GetEnumerator' or is not accessible",
+                                       TypeManager.CSharpName (expr.Type));
                        }
 
                        bool TryType (EmitContext ec, Type t)
@@ -4515,6 +4510,19 @@ namespace Mono.CSharp {
                                PropertyExpr tmp_get_cur = null;
                                Type tmp_enumerator_type = enumerator_type;
                                foreach (MethodInfo mi in mg.Methods) {
+                                       Type [] args = TypeManager.GetArgumentTypes (mi);
+                                       if (args != null && args.Length != 0)
+                                               continue;
+                       
+                                       // Check whether GetEnumerator is public
+                                       if ((mi.Attributes & MethodAttributes.Public) != MethodAttributes.Public)
+                                               continue;
+
+                                       if (TypeManager.IsOverride (mi))
+                                               continue;
+
+                                       enumerator_found = true;
+
                                        if (!GetEnumeratorFilter (ec, mi)) {
                                                continue;
                                        }
@@ -4590,7 +4598,7 @@ namespace Mono.CSharp {
                                is_disposable = true;
 
                                if (!ProbeCollectionType (ec, expr.Type)) {
-                                       error1579 ();
+                                       Error_Enumerator ();
                                        return false;
                                }