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); }
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()); }
public void AddEntryMethod(StateMachineMethod method) { if (this.method != null) { throw new InternalErrorException(); } this.method = method; Members.Add(method); }
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); }
public GetEnumeratorStatement(IteratorStorey host, StateMachineMethod host_method) { this.host = host; this.host_method = host_method; loc = host_method.Location; }
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()); }