2007-12-06 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / mcs / iterators.cs
index 1f0e9d66ad8038ffcffc16cf346f8359e240f5b4..678ca672fbbe781db1f3c822e1cba454006801b9 100644 (file)
@@ -100,6 +100,13 @@ namespace Mono.CSharp {
                {
                        ec.CurrentIterator.MarkYield (ec, expr, finally_blocks);
                }
+
+               protected override void CloneTo (CloneContext clonectx, Statement t)
+               {
+                       Yield target = (Yield) t;
+
+                       target.expr = expr.Clone (clonectx);
+               }
        }
 
        public class YieldBreak : Statement {
@@ -124,7 +131,7 @@ namespace Mono.CSharp {
                }
        }
 
-       public class IteratorHost : AnonymousMethodHost
+       public class IteratorHost : RootScopeInfo
        {
                public readonly Iterator Iterator;
 
@@ -137,8 +144,10 @@ namespace Mono.CSharp {
                TypeExpr enumerable_type;
                TypeArguments generic_args;
                TypeExpr generic_enumerator_type;
+#if GMCS_SOURCE                
                TypeExpr generic_enumerable_type;
-
+#endif
+               
                public IteratorHost (Iterator iterator)
                        : base (iterator.Container.Toplevel, iterator.Host, iterator.GenericMethod,
                                iterator.Location)
@@ -229,6 +238,27 @@ namespace Mono.CSharp {
                        return base.DoResolveMembers ();
                }
 
+               public void CaptureScopes ()
+               {
+                       Report.Debug (128, "DEFINE ITERATOR HOST", this, scopes);
+
+                       foreach (ScopeInfo si in scopes)
+                               CaptureScope (si);
+
+                       foreach (ScopeInfo si in scopes) {
+                               if (!si.Define ())
+                                       throw new InternalErrorException ();
+                               if (si.DefineType () == null)
+                                       throw new InternalErrorException ();
+                               if (!si.ResolveType ())
+                                       throw new InternalErrorException ();
+                               if (!si.ResolveMembers ())
+                                       throw new InternalErrorException ();
+                               if (!si.DefineMembers ())
+                                       throw new InternalErrorException ();
+                       }
+               }
+
                protected override bool DoDefineMembers ()
                {
                        if (!base.DoDefineMembers ())
@@ -285,7 +315,7 @@ namespace Mono.CSharp {
                        Accessor getter = new Accessor (get_block, 0, null, Location);
 
                        Property current = new Property (
-                               this, type, 0, false, name, null, getter, null);
+                               this, type, 0, false, name, null, getter, null, false);
                        AddProperty (current);
                }
 
@@ -311,12 +341,8 @@ namespace Mono.CSharp {
 
                ConstructorInfo GetInvalidOperationException ()
                {
-                       MethodGroupExpr mg = (MethodGroupExpr) Expression.MemberLookup (
-                               TypeBuilder, TypeManager.invalid_operation_exception_type,
-                               ".ctor", Location);
-                       if (mg == null)
-                               throw new InternalErrorException ();
-                       return (ConstructorInfo) mg.Methods [0];
+                       return TypeManager.GetConstructor (
+                               TypeManager.invalid_operation_exception_type, Type.EmptyTypes);
                }
 
                protected override ScopeInitializer CreateScopeInitializer ()
@@ -324,7 +350,7 @@ namespace Mono.CSharp {
                        return new IteratorHostInitializer (this);
                }
 
-               protected class IteratorHostInitializer : AnonymousMethodHostInitializer
+               protected class IteratorHostInitializer : RootScopeInitializer
                {
                        new public readonly IteratorHost Host;
                        protected Iterator.State state;
@@ -426,7 +452,7 @@ namespace Mono.CSharp {
 
                                        ce = TypeManager.int_interlocked_compare_exchange;
 
-                                       ec.CurrentBranching.CurrentUsageVector.Return ();
+                                       ec.CurrentBranching.CurrentUsageVector.Goto ();
                                        return true;
                                }
 
@@ -560,7 +586,7 @@ namespace Mono.CSharp {
 
                        public override bool Resolve (EmitContext ec)
                        {
-                               ec.CurrentBranching.CurrentUsageVector.Return ();
+                               ec.CurrentBranching.CurrentUsageVector.Goto ();
                                return true;
                        }
 
@@ -781,20 +807,28 @@ namespace Mono.CSharp {
                        point.Define (ig);
                }
 
+               public override string ContainerType {
+                       get { return "iterator"; }
+               }
+
                public override bool IsIterator {
                        get { return true; }
                }
 
-               public override AnonymousMethodHost RootScope {
+               public override RootScopeInfo RootScope {
+                       get { return IteratorHost; }
+               }
+
+               public override ScopeInfo Scope {
                        get { return IteratorHost; }
                }
 
                //
                // Our constructor
                //
-               public Iterator (IMethodData m_container, TypeContainer host, GenericMethod generic,
+               private Iterator (IMethodData m_container, DeclSpace host, GenericMethod generic,
                                 int modifiers, Type iterator_type, bool is_enumerable)
-                       : base (null, host, generic, m_container.ParameterInfo,
+                       : base (host, generic, m_container.ParameterInfo,
                                new ToplevelBlock (m_container.ParameterInfo, m_container.Location),
                                m_container.Block, TypeManager.bool_type, modifiers,
                                m_container.Location)
@@ -838,7 +872,7 @@ namespace Mono.CSharp {
                        return OriginalMethod.GetSignatureForError ();
                }
 
-               public override bool Resolve (EmitContext ec)
+               public override bool Define (EmitContext ec)
                {
                        Report.Debug (64, "RESOLVE ITERATOR", this, Container, Block);
 
@@ -871,7 +905,7 @@ namespace Mono.CSharp {
                                return false;
                        }
 
-                       if (!base.Resolve (ec))
+                       if (!base.Define (ec))
                                return false;
 
                        Report.Debug (64, "RESOLVE ITERATOR #1", this, method, method.Parent,
@@ -894,12 +928,21 @@ namespace Mono.CSharp {
 
                protected override Method DoCreateMethodHost (EmitContext ec)
                {
+                       Report.Debug (128, "CREATE METHOD HOST", this, IteratorHost);
+
+                       IteratorHost.CaptureScopes ();
+
                        return new AnonymousMethodMethod (
-                               this, null, TypeManager.system_boolean_expr,
+                               this, RootScope, null, TypeManager.system_boolean_expr,
                                Modifiers.PUBLIC, new MemberName ("MoveNext", Location),
                                Parameters.EmptyReadOnlyParameters);
                }
 
+               public override Expression Resolve (EmitContext ec)
+               {
+                       throw new NotSupportedException ();
+               }
+
                protected class MoveNextStatement : Statement {
                        Iterator iterator;
 
@@ -943,7 +986,7 @@ namespace Mono.CSharp {
                                if (Expr == null)
                                        return false;
 
-                               ec.CurrentBranching.CurrentUsageVector.Return ();
+                               ec.CurrentBranching.CurrentUsageVector.Goto ();
 
                                return true;
                        }
@@ -955,18 +998,22 @@ namespace Mono.CSharp {
                        }
                }
 
-               public static Iterator CreateIterator (IMethodData method, TypeContainer parent,
+               public static Iterator CreateIterator (IMethodData method, DeclSpace parent,
                                                       GenericMethod generic, int modifiers)
                {
                        bool is_enumerable;
                        Type iterator_type;
 
-                       if (!CheckType (method.ReturnType, out iterator_type, out is_enumerable)) {
+                       Type ret = method.ReturnType;
+                       if (ret == null)
+                               return null;
+
+                       if (!CheckType (ret, out iterator_type, out is_enumerable)) {
                                Report.Error (1624, method.Location,
                                              "The body of `{0}' cannot be an iterator block " +
                                              "because `{1}' is not an iterator interface type",
                                              method.GetSignatureForError (),
-                                             TypeManager.CSharpName (method.ReturnType));
+                                             TypeManager.CSharpName (ret));
                                return null;
                        }