public HoistedLocalVariable (AnonymousMethodStorey storey, LocalVariable local, string name) : base (storey, name, local.Type) { }
public HoistedThis (AnonymousMethodStorey storey, Field field) : base (storey, field) { }
protected HoistedVariable (AnonymousMethodStorey storey, Field field) { this.storey = storey; this.field = field; }
public HoistedParameter (AnonymousMethodStorey scope, ParameterReference par) : base (scope, par.Name, par.Type) { this.parameter = par; }
// // Returns a field which holds referenced storey instance // Field GetReferencedStoreyField (AnonymousMethodStorey storey) { if (used_parent_storeys == null) return null; foreach (StoreyFieldPair sf in used_parent_storeys) { if (sf.Storey == storey) return sf.Field; } return null; }
protected HoistedVariable (AnonymousMethodStorey storey, string name, TypeSpec type) : this (storey, storey.AddCapturedVariable (name, type)) { }
public void SetNestedStoryParent (AnonymousMethodStorey parentStorey) { Parent = parentStorey; spec.IsGeneric = false; spec.DeclaringType = parentStorey.CurrentType; MemberName.TypeParameters = null; }
public void AddParentStoreyReference (EmitContext ec, AnonymousMethodStorey storey) { CheckMembersDefined (); if (used_parent_storeys == null) used_parent_storeys = new List<StoreyFieldPair> (); else if (used_parent_storeys.Exists (i => i.Storey == storey)) return; TypeExpr type_expr = storey.CreateStoreyTypeExpression (ec); Field f = AddCompilerGeneratedField ("<>f__ref$" + storey.ID, type_expr); used_parent_storeys.Add (new StoreyFieldPair (storey, f)); }
public StoreyFieldPair (AnonymousMethodStorey storey, Field field) { this.Storey = storey; this.Field = field; }
// // Creates a host for the anonymous method // AnonymousMethodMethod DoCreateMethodHost (EmitContext ec) { // // Anonymous method body can be converted to // // 1, an instance method in current scope when only `this' is hoisted // 2, a static method in current scope when neither `this' nor any variable is hoisted // 3, an instance method in compiler generated storey when any hoisted variable exists // Modifiers modifiers; TypeDefinition parent = null; var src_block = Block.Original.Explicit; if (src_block.HasCapturedVariable || src_block.HasCapturedThis) { parent = storey = FindBestMethodStorey (); if (storey == null) { var top_block = src_block.ParametersBlock.TopBlock; var sm = top_block.StateMachine; if (src_block.HasCapturedThis) { // // Remove hoisted 'this' request when simple instance method is // enough (no hoisted variables only 'this') // if (src_block.ParametersBlock.StateMachine == null) top_block.RemoveThisReferenceFromChildrenBlock (src_block); // // Special case where parent class is used to emit instance method // because currect storey is of value type (async host). We cannot // use ldftn on non-boxed instances either to share mutated state // if (sm != null && sm.Kind == MemberKind.Struct) { parent = sm.Parent.PartialContainer; } } // // For iterators we can host everything in one class // if (sm is IteratorStorey) parent = storey = sm; } modifiers = storey != null ? Modifiers.INTERNAL : Modifiers.PRIVATE; } else { if (ec.CurrentAnonymousMethod != null) parent = storey = ec.CurrentAnonymousMethod.Storey; modifiers = Modifiers.STATIC | Modifiers.PRIVATE; } if (parent == null) parent = ec.CurrentTypeDefinition.Parent.PartialContainer; string name = CompilerGeneratedContainer.MakeName (parent != storey ? block_name : null, "m", null, ec.Module.CounterAnonymousMethods++); MemberName member_name; if (storey == null && ec.CurrentTypeParameters != null) { var hoisted_tparams = ec.CurrentTypeParameters; var type_params = new TypeParameters (hoisted_tparams.Count); for (int i = 0; i < hoisted_tparams.Count; ++i) { type_params.Add (hoisted_tparams[i].CreateHoistedCopy (null)); } member_name = new MemberName (name, type_params, Location); } else { member_name = new MemberName (name, Location); } return new AnonymousMethodMethod (parent, this, storey, new TypeExpression (ReturnType, Location), modifiers, member_name, parameters); }
public AnonymousMethodMethod (TypeDefinition parent, AnonymousExpression am, AnonymousMethodStorey storey, TypeExpr return_type, Modifiers mod, MemberName name, ParametersCompiled parameters) : base (parent, return_type, mod | Modifiers.COMPILER_GENERATED, name, parameters, null) { this.AnonymousMethod = am; this.Storey = storey; Parent.PartialContainer.Members.Add (this); Block = new ToplevelBlock (am.block, parameters); }