public override void MutateHoistedGenericType (AnonymousMethodStorey storey) { foreach (Argument a in arguments) a.Expr.MutateHoistedGenericType (storey); mg.MutateHoistedGenericType (storey); }
public override void MutateHoistedGenericType (AnonymousMethodStorey storey) { expr.MutateHoistedGenericType (storey); }
public HoistedLocalVariable (AnonymousMethodStorey storey, LocalVariable local, string name) : base (storey, name, local.Type) { }
protected HoistedVariable (AnonymousMethodStorey storey, Field field) { this.storey = storey; this.field = field; }
// // 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; }
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)); }
// // 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 sm = src_block.ParametersBlock.TopBlock.StateMachine; // // Remove hoisted this demand when simple instance method is enough (no hoisted variables only this) // if (src_block.HasCapturedThis && src_block.ParametersBlock.StateMachine == null) { src_block.ParametersBlock.TopBlock.RemoveThisReferenceFromChildrenBlock (src_block); // // Special case where parent class is used to emit instance method // because currect storey is of value type (async host) and we don't // want to create another childer storey to host this reference only // 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 void AddCapturedThisField (EmitContext ec, AnonymousMethodStorey parent) { TypeExpr type_expr = new TypeExpression (ec.CurrentType, Location); Field f = AddCompilerGeneratedField ("$this", type_expr); hoisted_this = new HoistedThis (this, f); initialize_hoisted_this = true; hoisted_this_parent = parent; }
public override void MutateHoistedGenericType (AnonymousMethodStorey storey) { if (InstanceExpression != null) InstanceExpression.MutateHoistedGenericType (storey); type = storey.MutateType (type); if (getter != null) getter = storey.MutateGenericMethod (getter); if (setter != null) setter = storey.MutateGenericMethod (setter); }
public override void MutateHoistedGenericType (AnonymousMethodStorey storey) { FieldInfo = storey.MutateField (FieldInfo); base.MutateHoistedGenericType (storey); }
public override void MutateHoistedGenericType (AnonymousMethodStorey storey) { base.MutateHoistedGenericType (storey); MethodInfo mi = best_candidate as MethodInfo; if (mi != null) { best_candidate = storey.MutateGenericMethod (mi); return; } best_candidate = storey.MutateConstructor ((ConstructorInfo) this); }
public override void MutateHoistedGenericType (AnonymousMethodStorey storey) { extension_argument.Expr.MutateHoistedGenericType (storey); base.MutateHoistedGenericType (storey); }
public override void MutateHoistedGenericType (AnonymousMethodStorey storey) { if (InstanceExpression != null) InstanceExpression.MutateHoistedGenericType (storey); }
public override void MutateHoistedGenericType (AnonymousMethodStorey storey) { type = storey.MutateType (type); }
public override void MutateHoistedGenericType (AnonymousMethodStorey storey) { throw new NotSupportedException (); }
// // 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' and don't need to // propagate this to value type state machine. // StateMachine sm_parent; var pb = src_block.ParametersBlock; do { sm_parent = pb.StateMachine; pb = pb.Parent == null ? null : pb.Parent.ParametersBlock; } while (sm_parent == null && pb != null); if (sm_parent == null) { top_block.RemoveThisReferenceFromChildrenBlock (src_block); } else if (sm_parent.Kind == MemberKind.Struct) { // // Special case where parent class is used to emit instance method // because currect storey is of value type (async host) and we cannot // use ldftn on non-boxed instances either to share mutated state // parent = sm_parent.Parent.PartialContainer; } else if (sm is IteratorStorey) { // // For iterators we can host everything in one class // 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, parent.PartialContainer.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 ThisInitializer (HoistedThis hoisted_this, AnonymousMethodStorey parent) { this.hoisted_this = hoisted_this; this.parent = parent; }
// // Creates anonymous method storey in current block // public AnonymousMethodStorey CreateAnonymousMethodStorey (ResolveContext ec) { // // When referencing a variable in iterator storey from children anonymous method // if (Toplevel.am_storey is IteratorStorey) { return Toplevel.am_storey; } // // An iterator has only 1 storey block // if (ec.CurrentIterator != null) return ec.CurrentIterator.Storey; if (am_storey == null) { MemberBase mc = ec.MemberContext as MemberBase; GenericMethod gm = mc == null ? null : mc.GenericMethod; // // Creates anonymous method storey for this block // am_storey = new AnonymousMethodStorey (this, ec.CurrentMemberDefinition.Parent.PartialContainer, mc, gm, "AnonStorey"); } return am_storey; }
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); }
// // Creates anonymous method storey in current block // public AnonymousMethodStorey CreateAnonymousMethodStorey (ResolveContext ec) { // // An iterator has only 1 storey block // if (ec.CurrentIterator != null) return ec.CurrentIterator.Storey; // // When referencing a variable in iterator storey from children anonymous method // if (ParametersBlock.am_storey is IteratorStorey) { return ParametersBlock.am_storey; } if (am_storey == null) { MemberBase mc = ec.MemberContext as MemberBase; // // Creates anonymous method storey for this block // am_storey = new AnonymousMethodStorey (this, ec.CurrentMemberDefinition.Parent.PartialContainer, mc, ec.CurrentTypeParameters, "AnonStorey"); } return am_storey; }
public StoreyFieldPair (AnonymousMethodStorey storey, Field field) { this.Storey = storey; this.Field = field; }
public HoistedLocalVariable (AnonymousMethodStorey scope, LocalInfo local, string name) : base (scope, name, local.VariableType) { this.name = local.Name; }
public void SetNestedStoryParent (AnonymousMethodStorey parentStorey) { Parent = parentStorey; spec.IsGeneric = false; spec.DeclaringType = parentStorey.CurrentType; MemberName.TypeParameters = null; }
public AnonymousMethodMethod (DeclSpace parent, AnonymousExpression am, AnonymousMethodStorey storey, GenericMethod generic, TypeExpr return_type, Modifiers mod, string real_name, MemberName name, ParametersCompiled parameters) : base (parent, generic, return_type, mod | Modifiers.COMPILER_GENERATED, name, parameters, null) { this.AnonymousMethod = am; this.Storey = storey; this.RealName = real_name; Parent.PartialContainer.AddMethod (this); Block = new ToplevelBlock (am.block, parameters); }
protected HoistedVariable (AnonymousMethodStorey storey, string name, TypeSpec type) : this (storey, storey.AddCapturedVariable (name, type)) { }
// // 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; if (Block.HasCapturedVariable || Block.HasCapturedThis) { storey = FindBestMethodStorey (); modifiers = storey != null ? Modifiers.INTERNAL : Modifiers.PRIVATE; } else { if (ec.CurrentAnonymousMethod != null) storey = ec.CurrentAnonymousMethod.Storey; modifiers = Modifiers.STATIC | Modifiers.PRIVATE; } TypeContainer parent = storey != null ? storey : ec.CurrentTypeDefinition.Parent.PartialContainer; MemberCore mc = ec.MemberContext as MemberCore; string name = CompilerGeneratedClass.MakeName (parent != storey ? block_name : null, "m", null, unique_id++); 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); } string real_name = String.Format ( "{0}~{1}{2}", mc.GetSignatureForError (), GetSignatureForError (), parameters.GetSignatureForError ()); return new AnonymousMethodMethod (parent, this, storey, new TypeExpression (ReturnType, Location), modifiers, real_name, member_name, parameters); }
public HoistedParameter (AnonymousMethodStorey scope, ParameterReference par) : base (scope, par.Name, par.Type) { this.parameter = par; }
// // For compiler generated local variables // public HoistedLocalVariable (AnonymousMethodStorey storey, Field field) : base (storey, field) { }
public HoistedThis (AnonymousMethodStorey storey, Field field) : base (storey, field) { }
public override void MutateHoistedGenericType (AnonymousMethodStorey storey) { // A constant cannot be of generic type }