protected override Expression DoResolve(ResolveContext ec)
        {
            var ctx = CreateBlockContext(ec);

            Block.Resolve(ctx);

            //
            // Explicit return is required for Task<T> state machine
            //
            var task_storey = storey as AsyncTaskStorey;

            if (task_storey == null || (task_storey.ReturnType != null && !task_storey.ReturnType.IsGenericTask))
            {
                ctx.CurrentBranching.CurrentUsageVector.Goto();
            }

            ctx.EndFlowBranching();

            if (!ec.IsInProbingMode)
            {
                var move_next = new StateMachineMethod(storey, this, new TypeExpression(ReturnType, loc), Modifiers.PUBLIC, new MemberName("MoveNext", loc));
                move_next.Block.AddStatement(new MoveNextBodyStatement(this));
                storey.AddEntryMethod(move_next);
            }

            eclass = ExprClass.Value;
            return(this);
        }
Пример #2
0
        protected override bool DoDefineMembers()
        {
            current_field   = AddCompilerGeneratedField("$current", iterator_type_expr);
            disposing_field = AddCompilerGeneratedField("$disposing", new TypeExpression(Compiler.BuiltinTypes.Bool, Location));

            if (hoisted_params != null)
            {
                //
                // Iterators are independent, each GetEnumerator call has to
                // create same enumerator therefore we have to keep original values
                // around for re-initialization
                //
                // TODO: Do it for assigned/modified parameters only
                //
                hoisted_params_copy = new List <HoistedParameter> (hoisted_params.Count);
                foreach (HoistedParameter hp in hoisted_params)
                {
                    hoisted_params_copy.Add(new HoistedParameter(hp, "<$>" + hp.Field.Name));
                }
            }

            if (generic_enumerator_type != null)
            {
                Define_Current(true);
            }

            Define_Current(false);
            new DisposeMethod(this);
            Define_Reset();

            if (Iterator.IsEnumerable)
            {
                FullNamedExpression explicit_iface = new TypeExpression(Compiler.BuiltinTypes.IEnumerable, Location);
                var name = new MemberName("GetEnumerator", null, explicit_iface, Location);

                if (generic_enumerator_type != null)
                {
                    Method get_enumerator = new StateMachineMethod(this, null, enumerator_type, 0, name);

                    explicit_iface = new GenericTypeExpr(Module.PredefinedTypes.IEnumerableGeneric.Resolve(), generic_args, Location);
                    name           = new MemberName("GetEnumerator", null, explicit_iface, Location);
                    Method gget_enumerator = new GetEnumeratorMethod(this, generic_enumerator_type, name);

                    //
                    // Just call generic GetEnumerator implementation
                    //
                    get_enumerator.Block.AddStatement(
                        new Return(new Invocation(new DynamicMethodGroupExpr(gget_enumerator, Location), null), Location));

                    AddMethod(get_enumerator);
                    AddMethod(gget_enumerator);
                }
                else
                {
                    AddMethod(new GetEnumeratorMethod(this, enumerator_type, name));
                }
            }

            return(base.DoDefineMembers());
        }
Пример #3
0
        public void AddEntryMethod(StateMachineMethod method)
        {
            if (this.method != null)
            {
                throw new InternalErrorException();
            }

            this.method = method;
            Members.Add(method);
        }
Пример #4
0
        protected override Expression DoResolve(ResolveContext rc)
        {
            var bc  = (BlockContext)rc;
            var ctx = CreateBlockContext(bc);

            Block.Resolve(ctx);

            if (!rc.IsInProbingMode)
            {
                var move_next = new StateMachineMethod(storey, this, new TypeExpression(ReturnType, loc), Modifiers.PUBLIC, new MemberName("MoveNext", loc), 0);
                move_next.Block.AddStatement(new MoveNextBodyStatement(this));
                storey.AddEntryMethod(move_next);
            }

            bc.AssignmentInfoOffset = ctx.AssignmentInfoOffset;
            eclass = ExprClass.Value;
            return(this);
        }
Пример #5
0
 public GetEnumeratorStatement(IteratorStorey host, StateMachineMethod host_method)
 {
     this.host        = host;
     this.host_method = host_method;
     loc = host_method.Location;
 }
Пример #6
0
        protected override bool DoDefineMembers()
        {
            current_field = AddCompilerGeneratedField("$current", iterator_type_expr);

            if (hoisted_params != null)
            {
                //
                // Iterators are independent, each GetEnumerator call has to
                // create same enumerator therefore we have to keep original values
                // around for re-initialization
                //
                // TODO: Do it for assigned/modified parameters only
                //
                hoisted_params_copy = new List <HoistedParameter> (hoisted_params.Count);
                foreach (HoistedParameter hp in hoisted_params)
                {
                    hoisted_params_copy.Add(new HoistedParameter(hp, "<$>" + hp.Field.Name));
                }
            }

            if (generic_enumerator_type != null)
            {
                Define_Current(true);
            }

            Define_Current(false);
            new DisposeMethod(this);
            Define_Reset();

            if (Iterator.IsEnumerable)
            {
                MemberName name = new MemberName(QualifiedAliasMember.GlobalAlias, "System", null, Location);
                name = new MemberName(name, "Collections", Location);
                name = new MemberName(name, "IEnumerable", Location);
                name = new MemberName(name, "GetEnumerator", Location);

                if (generic_enumerator_type != null)
                {
                    Method get_enumerator = new StateMachineMethod(this, null, enumerator_type, 0, name);

                    name = new MemberName(name.Left.Left, "Generic", Location);
                    name = new MemberName(name, "IEnumerable", generic_args, Location);
                    name = new MemberName(name, "GetEnumerator", Location);
                    Method gget_enumerator = new GetEnumeratorMethod(this, generic_enumerator_type, name);

                    //
                    // Just call generic GetEnumerator implementation
                    //
                    get_enumerator.Block.AddStatement(
                        new Return(new Invocation(new DynamicMethodGroupExpr(gget_enumerator, Location), null), Location));

                    AddMethod(get_enumerator);
                    AddMethod(gget_enumerator);
                }
                else
                {
                    AddMethod(new GetEnumeratorMethod(this, enumerator_type, name));
                }
            }

            return(base.DoDefineMembers());
        }