2009-08-13 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / mcs / anonymous.cs
index 50e81258268acf53216a47d13226cce37ab425fa..fed1f93bccd7a6b455189f083b9c4e8ae58c5a6b 100644 (file)
@@ -312,7 +312,7 @@ namespace Mono.CSharp {
                                storey_type_expr = new TypeExpression (TypeBuilder, Location);
                        }
 
-                       Expression e = new New (storey_type_expr, new ArrayList (0), Location).Resolve (ec);
+                       Expression e = new New (storey_type_expr, null, Location).Resolve (ec);
                        e.Emit (ec);
 
                        Instance = new LocalTemporary (storey_type_expr.Type);
@@ -508,7 +508,7 @@ namespace Mono.CSharp {
                                Type t = MutateGenericType (method.DeclaringType);
                                if (t != method.DeclaringType) {
                                        method = (MethodInfo) TypeManager.DropGenericMethodArguments (method);
-                                       if (method.Module == CodeGen.Module.Builder)
+                                       if (method.Module == Module.Builder)
                                                method = TypeBuilder.GetMethod (t, method);
                                        else
                                                method = (MethodInfo) MethodInfo.GetMethodFromHandle (method.MethodHandle, t.TypeHandle);
@@ -534,7 +534,7 @@ namespace Mono.CSharp {
                                Type t = MutateGenericType (ctor.DeclaringType);
                                if (t != ctor.DeclaringType) {
                                        ctor = (ConstructorInfo) TypeManager.DropGenericMethodArguments (ctor);
-                                       if (ctor.Module == CodeGen.Module.Builder)
+                                       if (ctor.Module == Module.Builder)
                                                return TypeBuilder.GetConstructor (t, ctor);
                                                
                                        return (ConstructorInfo) ConstructorInfo.GetMethodFromHandle (ctor.MethodHandle, t.TypeHandle);
@@ -550,8 +550,11 @@ namespace Mono.CSharp {
                        if (TypeManager.IsGenericType (field.DeclaringType)) {
                                Type t = MutateGenericType (field.DeclaringType);
                                if (t != field.DeclaringType) {
-                                       // TODO: It should throw on imported types
-                                       return TypeBuilder.GetField (t, field);
+                                       field = TypeManager.DropGenericTypeArguments (field.DeclaringType).GetField (field.Name, TypeManager.AllMembers);
+                                       if (field.Module == Module.Builder)
+                                               return TypeBuilder.GetField (t, field);
+
+                                       return FieldInfo.GetFieldFromHandle (field.FieldHandle, t.TypeHandle);                                          
                                }
                        }
 #endif
@@ -561,12 +564,10 @@ namespace Mono.CSharp {
 #if GMCS_SOURCE
                protected Type MutateArrayType (Type array)
                {
-                       int rank = array.GetArrayRank ();
                        Type element = TypeManager.GetElementType (array);
-                       if (element.IsArray)
-                               throw new NotImplementedException ();
-
-                       if (TypeManager.IsGenericParameter (element)) {
+                       if (element.IsArray) {
+                               element = MutateArrayType (element);
+                       } else if (TypeManager.IsGenericParameter (element)) {
                                element = MutateGenericArgument (element);
                        } else if (TypeManager.IsGenericType (element)) {
                                element = MutateGenericType (element);
@@ -574,6 +575,10 @@ namespace Mono.CSharp {
                                return array;
                        }
 
+                       int rank = array.GetArrayRank ();
+                       if (rank == 1)
+                               return element.MakeArrayType ();
+
                        return element.MakeArrayType (rank);
                }
 
@@ -586,7 +591,7 @@ namespace Mono.CSharp {
                        for (int i = 0; i < t_args.Length; ++i)
                                t_args [i] = MutateType (t_args [i]);
 
-                       return type.GetGenericTypeDefinition ().MakeGenericType (t_args);
+                       return TypeManager.DropGenericTypeArguments (type).MakeGenericType (t_args);
                }
 #endif
 
@@ -709,7 +714,10 @@ namespace Mono.CSharp {
                        }
 
                        if (inner_access == null) {
-                               inner_access = new FieldExpr (field.FieldBuilder, field.Location);
+                               inner_access = field.Parent.MemberName.IsGeneric ?
+                                       new FieldExpr (field.FieldBuilder, field.Parent.CurrentType, field.Location) :
+                                       new FieldExpr (field.FieldBuilder, field.Location);
+                                                       
                                inner_access.InstanceExpression = storey.GetStoreyInstanceExpression (ec);
                                inner_access.Resolve (ec);
                                cached_inner_access.Add (ec.CurrentAnonymousMethod, inner_access);
@@ -851,11 +859,11 @@ namespace Mono.CSharp {
 
                public virtual bool HasExplicitParameters {
                        get {
-                               return Parameters != Parameters.Undefined;
+                               return Parameters != ParametersCompiled.Undefined;
                        }
                }
                
-               public Parameters Parameters {
+               public ParametersCompiled Parameters {
                        get { return Block.Parameters; }
                }
 
@@ -865,8 +873,10 @@ namespace Mono.CSharp {
                //
                public bool ImplicitStandardConversionExists (EmitContext ec, Type delegate_type)
                {
-                       using (ec.Set (EmitContext.Flags.ProbingMode)) {
-                               return Compatible (ec, delegate_type) != null;
+                       using (ec.With (EmitContext.Flags.InferReturnType, false)) {
+                               using (ec.Set (EmitContext.Flags.ProbingMode)) {
+                                       return Compatible (ec, delegate_type) != null;
+                               }
                        }
                }
 
@@ -875,7 +885,6 @@ namespace Mono.CSharp {
                        if (TypeManager.IsDelegateType (delegate_type))
                                return delegate_type;
 
-#if GMCS_SOURCE
                        if (TypeManager.DropGenericTypeArguments (delegate_type) == TypeManager.expression_type) {
                                delegate_type = TypeManager.GetTypeArguments (delegate_type) [0];
                                if (TypeManager.IsDelegateType (delegate_type))
@@ -885,7 +894,6 @@ namespace Mono.CSharp {
                                        GetSignatureForError (), TypeManager.CSharpName (delegate_type));
                                return null;
                        }
-#endif
 
                        Report.Error (1660, loc, "Cannot convert `{0}' to non-delegate type `{1}'",
                                      GetSignatureForError (), TypeManager.CSharpName (delegate_type));
@@ -970,16 +978,12 @@ namespace Mono.CSharp {
                                return false;
 
                        if (!TypeManager.IsDelegateType (delegate_type)) {
-#if GMCS_SOURCE
                                if (TypeManager.DropGenericTypeArguments (delegate_type) != TypeManager.expression_type)
                                        return false;
 
-                               delegate_type = delegate_type.GetGenericArguments () [0];
+                               delegate_type = TypeManager.GetTypeArguments (delegate_type) [0];
                                if (!TypeManager.IsDelegateType (delegate_type))
                                        return false;
-#else
-                               return false;
-#endif
                        }
                        
                        AParametersCollection d_params = TypeManager.GetDelegateParameters (delegate_type);
@@ -1004,15 +1008,12 @@ namespace Mono.CSharp {
                {
                        AnonymousMethodBody am;
                        using (ec.Set (EmitContext.Flags.ProbingMode | EmitContext.Flags.InferReturnType)) {
-                               am = CompatibleMethod (ec, tic, GetType (), delegate_type);
+                               am = CompatibleMethod (ec, tic, InternalType.Arglist, delegate_type);
                        }
                        
                        if (am == null)
                                return null;
 
-                       if (am.ReturnType == TypeManager.null_type)
-                               am.ReturnType = null;
-
                        return am.ReturnType;
                }
 
@@ -1062,6 +1063,8 @@ namespace Mono.CSharp {
                                        compatibles.Add (type, am == null ? EmptyExpression.Null : am);
 
                                return am;
+                       } catch (CompletionResult){
+                               throw;
                        } catch (Exception e) {
                                throw new InternalErrorException (e, loc);
                        }
@@ -1078,11 +1081,11 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               protected virtual Parameters ResolveParameters (EmitContext ec, TypeInferenceContext tic, Type delegate_type)
+               protected virtual ParametersCompiled ResolveParameters (EmitContext ec, TypeInferenceContext tic, Type delegate_type)
                {
                        AParametersCollection delegate_parameters = TypeManager.GetDelegateParameters (delegate_type);
 
-                       if (Parameters == Parameters.Undefined) {
+                       if (Parameters == ParametersCompiled.Undefined) {
                                //
                                // We provide a set of inaccessible parameters
                                //
@@ -1103,7 +1106,7 @@ namespace Mono.CSharp {
                                                delegate_parameters.FixedParameters [i].ModFlags, null, loc);
                                }
 
-                               return Parameters.CreateFullyResolved (fixedpars, delegate_parameters.Types);
+                               return ParametersCompiled.CreateFullyResolved (fixedpars, delegate_parameters.Types);
                        }
 
                        if (!VerifyExplicitParameters (delegate_type, delegate_parameters, ec.IsInProbingMode)) {
@@ -1131,7 +1134,7 @@ namespace Mono.CSharp {
                        // anywhere', we depend on special conversion
                        // rules.
                        // 
-                       type = TypeManager.anonymous_method_type;
+                       type = InternalType.AnonymousMethod;
 
                        if ((Parameters != null) && !Parameters.Resolve (ec))
                                return null;
@@ -1164,7 +1167,7 @@ namespace Mono.CSharp {
 
                protected AnonymousMethodBody CompatibleMethod (EmitContext ec, TypeInferenceContext tic, Type return_type, Type delegate_type)
                {
-                       Parameters p = ResolveParameters (ec, tic, delegate_type);
+                       ParametersCompiled p = ResolveParameters (ec, tic, delegate_type);
                        if (p == null)
                                return null;
 
@@ -1177,7 +1180,7 @@ namespace Mono.CSharp {
                        return anonymous;
                }
 
-               protected virtual AnonymousMethodBody CompatibleMethodFactory (Type return_type, Type delegate_type, Parameters p, ToplevelBlock b)
+               protected virtual AnonymousMethodBody CompatibleMethodFactory (Type return_type, Type delegate_type, ParametersCompiled p, ToplevelBlock b)
                {
                        return new AnonymousMethodBody (p, b, return_type, delegate_type, loc);
                }
@@ -1204,7 +1207,7 @@ namespace Mono.CSharp {
                        public AnonymousMethodMethod (DeclSpace parent, AnonymousExpression am, AnonymousMethodStorey storey,
                                                          GenericMethod generic, TypeExpr return_type,
                                                          int mod, string real_name, MemberName name,
-                                                         Parameters parameters)
+                                                         ParametersCompiled parameters)
                                : base (parent, generic, return_type, mod | Modifiers.COMPILER_GENERATED,
                                                name, parameters, null)
                        {
@@ -1304,8 +1307,10 @@ namespace Mono.CSharp {
 
                        IDisposable aec_dispose = null;
                        EmitContext.Flags flags = 0;
-                       if (ec.InferReturnType)
+                       if (ec.InferReturnType) {
                                flags |= EmitContext.Flags.InferReturnType;
+                               aec.ReturnTypeInference = new TypeInferenceContext ();
+                       }
 
                        if (ec.IsInProbingMode)
                                flags |= EmitContext.Flags.ProbingMode;
@@ -1323,8 +1328,10 @@ namespace Mono.CSharp {
                        bool unreachable;
                        bool res = aec.ResolveTopBlock (ec, Block, Block.Parameters, null, out unreachable);
 
-                       if (ec.InferReturnType)
-                               ReturnType = aec.ReturnType;
+                       if (ec.InferReturnType) {
+                               aec.ReturnTypeInference.FixAllTypes ();
+                               ReturnType = aec.ReturnTypeInference.InferredTypeArguments [0];
+                       }
 
                        if (aec_dispose != null) {
                                aec_dispose.Dispose ();
@@ -1350,7 +1357,7 @@ namespace Mono.CSharp {
 
        public class AnonymousMethodBody : AnonymousExpression
        {
-               protected readonly Parameters parameters;
+               protected readonly ParametersCompiled parameters;
                AnonymousMethodStorey storey;
 
                AnonymousMethodMethod method;
@@ -1358,7 +1365,7 @@ namespace Mono.CSharp {
 
                static int unique_id;
 
-               public AnonymousMethodBody (Parameters parameters,
+               public AnonymousMethodBody (ParametersCompiled parameters,
                                        ToplevelBlock block, Type return_type, Type delegate_type,
                                        Location loc)
                        : base (block, return_type, loc)
@@ -1535,7 +1542,6 @@ namespace Mono.CSharp {
                        }
 
                        MethodInfo delegate_method = method.MethodBuilder;
-#if GMCS_SOURCE
                        if (storey != null && storey.MemberName.IsGeneric) {
                                Type t = storey.Instance.Type;
                                
@@ -1549,9 +1555,13 @@ namespace Mono.CSharp {
                                        t = storey.GetGenericStorey ().MutateType (t);
                                }
 
+#if GMCS_SOURCE
                                delegate_method = TypeBuilder.GetMethod (t, delegate_method);
-                       }
+#else
+                               throw new NotSupportedException ();
 #endif
+                       }
+
                        ig.Emit (OpCodes.Ldftn, delegate_method);
 
                        ConstructorInfo constructor_method = Delegate.GetConstructor (ec.ContainerType, type);
@@ -1606,7 +1616,7 @@ namespace Mono.CSharp {
        //
        public class AnonymousTypeClass : CompilerGeneratedClass
        {
-               sealed class AnonymousParameters : Parameters
+               sealed class AnonymousParameters : ParametersCompiled
                {
                        public AnonymousParameters (params Parameter[] parameters)
                                : base (parameters)
@@ -1634,8 +1644,8 @@ namespace Mono.CSharp {
 
                public static AnonymousTypeClass Create (TypeContainer parent, ArrayList parameters, Location loc)
                {
-                       if (RootContext.Version <= LanguageVersion.ISO_2)
-                               Report.FeatureIsNotAvailable (loc, "anonymous types");
+                       if (RootContext.MetadataCompatibilityVersion < MetadataVersion.v2)
+                               Report.FeatureIsNotSupported (loc, "anonymous types");
 
                        string name = ClassNamePrefix + types_counter++;
 
@@ -1723,11 +1733,11 @@ namespace Mono.CSharp {
 
                        Method equals = new Method (this, null, TypeManager.system_boolean_expr,
                                Modifiers.PUBLIC | Modifiers.OVERRIDE | Modifiers.DEBUGGER_HIDDEN, new MemberName ("Equals", loc),
-                               Mono.CSharp.Parameters.CreateFullyResolved (new Parameter (null, "obj", 0, null, loc), TypeManager.object_type), null);
+                               Mono.CSharp.ParametersCompiled.CreateFullyResolved (new Parameter (null, "obj", 0, null, loc), TypeManager.object_type), null);
 
                        Method tostring = new Method (this, null, TypeManager.system_string_expr,
                                Modifiers.PUBLIC | Modifiers.OVERRIDE | Modifiers.DEBUGGER_HIDDEN, new MemberName ("ToString", loc),
-                               Mono.CSharp.Parameters.EmptyReadOnlyParameters, null);
+                               Mono.CSharp.ParametersCompiled.EmptyReadOnlyParameters, null);
 
                        ToplevelBlock equals_block = new ToplevelBlock (equals.Parameters, loc);
                        TypeExpr current_type;
@@ -1754,14 +1764,14 @@ namespace Mono.CSharp {
                                                new TypeArguments (new SimpleName (TypeParameters [i].Name, loc)), loc),
                                                "Default", loc);
 
-                               ArrayList arguments_equal = new ArrayList (2);
+                               Arguments arguments_equal = new Arguments (2);
                                arguments_equal.Add (new Argument (new MemberAccess (new This (f.Location), f.Name)));
                                arguments_equal.Add (new Argument (new MemberAccess (other_variable, f.Name)));
 
                                Expression field_equal = new Invocation (new MemberAccess (equality_comparer,
                                        "Equals", loc), arguments_equal);
 
-                               ArrayList arguments_hashcode = new ArrayList (1);
+                               Arguments arguments_hashcode = new Arguments (1);
                                arguments_hashcode.Add (new Argument (new MemberAccess (new This (f.Location), f.Name)));
                                Expression field_hashcode = new Invocation (new MemberAccess (equality_comparer,
                                        "GetHashCode", loc), arguments_hashcode);
@@ -1805,9 +1815,10 @@ namespace Mono.CSharp {
 
                        //
                        // Equals (object obj) override
-                       //
+                       //              
+                       LocalVariableReference other_variable_assign = new LocalVariableReference (equals_block, "other", loc);
                        equals_block.AddStatement (new StatementExpression (
-                               new SimpleAssign (other_variable,
+                               new SimpleAssign (other_variable_assign,
                                        new As (equals_block.GetParameterReference ("obj", loc),
                                                current_type, loc), loc)));
 
@@ -1826,7 +1837,7 @@ namespace Mono.CSharp {
                        Method hashcode = new Method (this, null, TypeManager.system_int32_expr,
                                Modifiers.PUBLIC | Modifiers.OVERRIDE | Modifiers.DEBUGGER_HIDDEN,
                                new MemberName ("GetHashCode", loc),
-                               Mono.CSharp.Parameters.EmptyReadOnlyParameters, null);
+                               Mono.CSharp.ParametersCompiled.EmptyReadOnlyParameters, null);
 
                        //
                        // Modified FNV with good avalanche behavior and uniform
@@ -1848,8 +1859,9 @@ namespace Mono.CSharp {
 
                        hashcode_block.AddVariable (TypeManager.system_int32_expr, "hash", loc);
                        LocalVariableReference hash_variable = new LocalVariableReference (hashcode_block, "hash", loc);
+                       LocalVariableReference hash_variable_assign = new LocalVariableReference (hashcode_block, "hash", loc);
                        hashcode_block.AddStatement (new StatementExpression (
-                               new SimpleAssign (hash_variable, rs_hashcode)));
+                               new SimpleAssign (hash_variable_assign, rs_hashcode)));
 
                        hashcode_block.AddStatement (new StatementExpression (
                                new CompoundAssign (Binary.Operator.Addition, hash_variable,