remove experimental code in #if false .. #endif
[mono.git] / mcs / mcs / anonymous.cs
index 1dc3671764ed507307a38f926e0bfe595850862b..8504e0dbc956bc9f5652d72c8f677c2f90ca4fe4 100644 (file)
@@ -113,7 +113,8 @@ namespace Mono.CSharp {
                        //
                        
                        TypeBuilder current_type = ec.TypeContainer.TypeBuilder;
-                       TypeBuilder type_host = Scope == null ? current_type : Scope.ScopeTypeBuilder;
+                       TypeBuilder type_host = (Scope == null ) // || Scope.ScopeTypeBuilder == null)
+                               ? current_type : Scope.ScopeTypeBuilder;
 
                        if (current_type == null)
                                throw new Exception ("The current_type is null");
@@ -122,8 +123,9 @@ namespace Mono.CSharp {
                                throw new Exception ("Type host is null");
                        
                        if (current_type == type_host && ec.IsStatic){
-                               if (ec.IsStatic)
+                               if (ec.IsStatic){
                                        method_modifiers |= Modifiers.STATIC;
+                               }
                                current_type = null;
                        } 
 
@@ -133,7 +135,6 @@ namespace Mono.CSharp {
                                method_modifiers, false, new MemberName ("<#AnonymousMethod>" + anonymous_method_count++),
                                Parameters, null, loc);
                        method.Block = Block;
-
                        
                        //
                        // Swap the TypeBuilder while we define the method, then restore
@@ -164,7 +165,7 @@ namespace Mono.CSharp {
                        //
 
                        invoke_mb = (MethodInfo) Delegate.GetInvokeMethod (ec, delegate_type, loc);
-                       ParameterData invoke_pd = Invocation.GetParameterData (invoke_mb);
+                       ParameterData invoke_pd = TypeManager.GetParameterData (invoke_mb);
 
                        //
                        // If implicit parameters are set, then we must check for out in the parameters
@@ -274,13 +275,14 @@ namespace Mono.CSharp {
                                ec.TypeContainer, ec.DeclSpace, loc, null,
                                invoke_mb.ReturnType,
                                /* REVIEW */ (ec.InIterator ? Modifiers.METHOD_YIELDS : 0) |
-                               (ec.InUnsafe ? Modifiers.UNSAFE : 0),
+                               (ec.InUnsafe ? Modifiers.UNSAFE : 0) |
+                               (ec.IsStatic ? Modifiers.STATIC : 0),
                                /* No constructor */ false);
 
                        aec.CurrentAnonymousMethod = this;
                        ContainerAnonymousMethod = ec.CurrentAnonymousMethod;
                        ContainingBlock = ec.CurrentBlock;
-               
+
                        if (aec.ResolveTopBlock (ec, Block, amp, loc, out unreachable))
                                return new AnonymousDelegate (this, delegate_type, loc).Resolve (ec);
 
@@ -307,12 +309,17 @@ namespace Mono.CSharp {
                        // Adjust based on the computed state of the
                        // method from CreateMethodHost
                        
-                       if ((method_modifiers & Modifiers.STATIC) != 0)
-                               aec.IsStatic = true;
+                       aec.MethodIsStatic = (method_modifiers & Modifiers.STATIC) != 0;
                        
                        aec.EmitMeta (Block, amp);
                        aec.EmitResolvedTopBlock (Block, unreachable);
                }
+
+               public static void Error_AddressOfCapturedVar (string name, Location loc)
+               {
+                       Report.Error (1686, loc,
+                                     "Variable {0} is captured in an anonymous method and its address is also being taken: they are exclusive", name);
+               }
        }
 
        //
@@ -503,7 +510,6 @@ namespace Mono.CSharp {
                        if (ScopeTypeBuilder != null)
                                return;
                        
-                       ILGenerator ig = ec.ig;
                        TypeBuilder container = ec.TypeContainer.TypeBuilder;
 
                        ScopeTypeBuilder = container.DefineNestedType (
@@ -551,7 +557,7 @@ namespace Mono.CSharp {
 
                public void CloseTypes ()
                {
-                       RootContext.RegisterHelperClass (ScopeTypeBuilder);
+                       RootContext.RegisterCompilerGeneratedType (ScopeTypeBuilder);
                        foreach (ScopeInfo si in children)
                                si.CloseTypes ();
                }
@@ -584,7 +590,6 @@ namespace Mono.CSharp {
                                Hashtable captured_parameters = CaptureContext.captured_parameters;
                                
                                foreach (DictionaryEntry de in captured_parameters){
-                                       string name = (string) de.Key;
                                        CapturedParameter cp = (CapturedParameter) de.Value;
 
                                        ig.Emit (OpCodes.Ldloc, ScopeInstance);
@@ -594,6 +599,9 @@ namespace Mono.CSharp {
                        }
                        
                        if (ParentScope != null){
+                               if (!ParentScope.inited)
+                                       ParentScope.EmitInitScope (ec);
+                               
                                //
                                // Only emit initialization in our capturecontext world
                                //
@@ -646,7 +654,7 @@ namespace Mono.CSharp {
        public class CaptureContext {
                public static int count;
                public int cc_id;
-               Location loc;
+               public Location loc;
                
                //
                // Points to the toplevel block that owns this CaptureContext
@@ -654,6 +662,7 @@ namespace Mono.CSharp {
                ToplevelBlock toplevel_owner;
                Hashtable scopes = new Hashtable ();
                bool have_captured_vars = false;
+               bool referenced_this = false;
                ScopeInfo topmost = null;
 
                //
@@ -685,9 +694,7 @@ namespace Mono.CSharp {
                
                public override string ToString ()
                {
-                       ToplevelBlock parent = ParentToplevel;
                        StringBuilder sb = new StringBuilder ();
-
                        sb.Append ("[");
                        DoPath (sb, this);
                        sb.Append ("]");
@@ -900,7 +907,14 @@ namespace Mono.CSharp {
                        else
                                captured_fields [fe] = fe;
                }
-               
+
+               public void CaptureThis ()
+               {
+                       CaptureContext parent = ParentCaptureContext;
+                       if (parent != null)
+                               parent.CaptureThis ();
+                       referenced_this = true;
+               }
 
                public bool HaveCapturedVariables {
                        get {
@@ -939,15 +953,15 @@ namespace Mono.CSharp {
                        return false;
                }
 
-               public void EmitHelperClasses (EmitContext ec)
+               public void EmitAnonymousHelperClasses (EmitContext ec)
                {
                        if (topmost != null){
-                               topmost.NeedThis = HaveCapturedFields;
+                               topmost.NeedThis = HaveCapturedFields || referenced_this;
                                topmost.EmitScopeType (ec);
                        } 
                }
 
-               public void CloseHelperClasses ()
+               public void CloseAnonymousHelperClasses ()
                {
                        if (topmost != null)
                                topmost.CloseTypes ();
@@ -1005,8 +1019,13 @@ namespace Mono.CSharp {
                                cc.EmitParameterInstance (ec, name);
                                return;
                        }
-                       Block invocation_block = ec.CurrentBlock;
+                       
                        CapturedParameter par_info = (CapturedParameter) captured_parameters [name];
+                       if (par_info != null){
+                               // 
+                               // FIXME: implementing this.
+                               //
+                       }
                        ILGenerator ig = ec.ig;
 
                        ScopeInfo si;
@@ -1039,6 +1058,11 @@ namespace Mono.CSharp {
                        }
                        EmitParameterInstance (ec, name);
                        CapturedParameter par_info = (CapturedParameter) captured_parameters [name];
+                       if (par_info != null){
+                               // 
+                               // FIXME: implementing this.
+                               //
+                       }
                        ec.ig.Emit (OpCodes.Ldfld, par_info.FieldBuilder);
                }