+
+ type_bases = list;
+
+ return base.ResolveBaseTypes (out base_class);
+ }
+
+ protected override string GetVariableMangledName (LocalInfo local_info)
+ {
+ return "<" + local_info.Name + ">__" + local_name_idx++.ToString ();
+ }
+
+ protected override bool DoDefineMembers ()
+ {
+ DefineIteratorMembers ();
+ return base.DoDefineMembers ();
+ }
+
+ void DefineIteratorMembers ()
+ {
+ pc_field = AddCompilerGeneratedField ("$PC", TypeManager.system_int32_expr);
+ 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 IteratorMethod (this, 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));
+ }
+ }
+ }
+
+ protected override void EmitHoistedParameters (EmitContext ec, IList<HoistedParameter> hoisted)
+ {
+ base.EmitHoistedParameters (ec, hoisted);
+ base.EmitHoistedParameters (ec, hoisted_params_copy);
+ }
+
+ void Define_Current (bool is_generic)
+ {
+ TypeExpr type;
+
+ MemberName name = new MemberName (QualifiedAliasMember.GlobalAlias, "System", null, Location);
+ name = new MemberName (name, "Collections", Location);
+
+ if (is_generic) {
+ name = new MemberName (name, "Generic", Location);
+ name = new MemberName (name, "IEnumerator", generic_args, Location);
+ type = iterator_type_expr;
+ } else {
+ name = new MemberName (name, "IEnumerator");
+ type = TypeManager.system_object_expr;
+ }
+
+ name = new MemberName (name, "Current", Location);
+
+ ToplevelBlock get_block = new ToplevelBlock (Compiler, Location);
+ get_block.AddStatement (new Return (new DynamicFieldExpr (CurrentField, Location), Location));
+
+ Accessor getter = new Accessor (get_block, 0, null, null, Location);
+
+ Property current = new Property (
+ this, type, Modifiers.DEBUGGER_HIDDEN, name, null, getter, null, false);
+ AddProperty (current);
+ }
+
+ void Define_Reset ()
+ {
+ Method reset = new Method (
+ this, null, TypeManager.system_void_expr,
+ Modifiers.PUBLIC | Modifiers.DEBUGGER_HIDDEN,
+ new MemberName ("Reset", Location),
+ ParametersCompiled.EmptyReadOnlyParameters, null);
+ AddMethod (reset);
+
+ reset.Block = new ToplevelBlock (Compiler, Location);
+
+ TypeSpec ex_type = TypeManager.CoreLookupType (Compiler, "System", "NotSupportedException", MemberKind.Class, true);
+ if (ex_type == null)
+ return;
+
+ reset.Block.AddStatement (new Throw (new New (new TypeExpression (ex_type, Location), null, Location), Location));