2009-06-23 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / mcs / anonymous.cs
index ae6b973cafe7cd25536ab093ad4490de6314e774..b11557f31afc3bc858bd50a9cb67b2e431a49da0 100644 (file)
@@ -105,20 +105,18 @@ namespace Mono.CSharp {
                // be called first, otherwise _this_ will be initialized with 
                // uninitialized value.
                //
-               public sealed class ThisInitializer : Statement
+               sealed class ThisInitializer : Statement
                {
-                       readonly AnonymousMethodStorey storey;
+                       readonly HoistedThis hoisted_this;
 
-                       public ThisInitializer (AnonymousMethodStorey storey)
+                       public ThisInitializer (HoistedThis hoisted_this)
                        {
-                               this.storey = storey;
+                               this.hoisted_this = hoisted_this;
                        }
 
                        protected override void DoEmit (EmitContext ec)
                        {
-                               if (storey.hoisted_this != null) {
-                                       storey.hoisted_this.EmitHoistingAssignment (ec);
-                               }
+                               hoisted_this.EmitHoistingAssignment (ec);
                        }
 
                        protected override void CloneTo (CloneContext clonectx, Statement target)
@@ -301,7 +299,7 @@ namespace Mono.CSharp {
                                TypeArguments targs = new TypeArguments ();
 
                                if (tparams.Length < CountTypeParameters) {
-                                       TypeParameter[] parent_tparams = ec.DeclContainer.Parent.CurrentTypeParameters;
+                                       TypeParameter[] parent_tparams = ec.DeclContainer.Parent.PartialContainer.TypeParameters;
                                        for (int i = 0; i < parent_tparams.Length; ++i)
                                                targs.Add (new TypeParameterExpr (parent_tparams[i], Location));
                                }
@@ -353,7 +351,7 @@ namespace Mono.CSharp {
                        //
                        if (OriginalSourceBlock.Explicit.HasCapturedThis && !(Parent is AnonymousMethodStorey)) {
                                AddCapturedThisField (ec);
-                               hoisted_this.EmitHoistingAssignment (ec);
+                               OriginalSourceBlock.AddScopeStatement (new ThisInitializer (hoisted_this));
                        }
 
                        //
@@ -510,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);
@@ -536,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);
@@ -565,10 +563,9 @@ namespace Mono.CSharp {
                {
                        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);
@@ -588,7 +585,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
 
@@ -853,11 +850,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; }
                }
 
@@ -867,8 +864,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;
+                               }
                        }
                }
 
@@ -877,7 +876,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))
@@ -887,7 +885,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));
@@ -972,16 +969,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);
@@ -1012,6 +1005,7 @@ namespace Mono.CSharp {
                        if (am == null)
                                return null;
 
+                       // Stop referencing gmcs NullLiteral type
                        if (am.ReturnType == TypeManager.null_type)
                                am.ReturnType = null;
 
@@ -1064,6 +1058,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);
                        }
@@ -1080,11 +1076,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
                                //
@@ -1105,7 +1101,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)) {
@@ -1166,7 +1162,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;
 
@@ -1179,7 +1175,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);
                }
@@ -1206,7 +1202,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)
                        {
@@ -1352,7 +1348,7 @@ namespace Mono.CSharp {
 
        public class AnonymousMethodBody : AnonymousExpression
        {
-               protected readonly Parameters parameters;
+               protected readonly ParametersCompiled parameters;
                AnonymousMethodStorey storey;
 
                AnonymousMethodMethod method;
@@ -1360,7 +1356,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)
@@ -1537,7 +1533,6 @@ namespace Mono.CSharp {
                        }
 
                        MethodInfo delegate_method = method.MethodBuilder;
-#if GMCS_SOURCE
                        if (storey != null && storey.MemberName.IsGeneric) {
                                Type t = storey.Instance.Type;
                                
@@ -1551,9 +1546,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);
@@ -1608,7 +1607,7 @@ namespace Mono.CSharp {
        //
        public class AnonymousTypeClass : CompilerGeneratedClass
        {
-               sealed class AnonymousParameters : Parameters
+               sealed class AnonymousParameters : ParametersCompiled
                {
                        public AnonymousParameters (params Parameter[] parameters)
                                : base (parameters)
@@ -1636,8 +1635,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++;
 
@@ -1725,11 +1724,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;
@@ -1828,7 +1827,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