2 // anonymous.cs: Support for anonymous methods
5 // Miguel de Icaza (miguel@ximain.com)
7 // (C) 2003, 2004 Novell, Inc.
9 // TODO: Ideally, we should have the helper classes emited as a hierarchy to map
10 // their nesting, and have the visibility set to private, instead of NestedAssembly
17 using System.Collections;
18 using System.Reflection;
19 using System.Reflection.Emit;
21 namespace Mono.CSharp {
23 public abstract class CompilerGeneratedClass : Class
25 GenericMethod generic_method;
26 static int next_index = 0;
28 private static MemberName MakeProxyName (GenericMethod generic, Location loc)
30 string name = MakeName (null, "CompilerGenerated");
31 if (generic != null) {
32 TypeArguments args = new TypeArguments (loc);
33 foreach (TypeParameter tparam in generic.CurrentTypeParameters)
34 args.Add (new SimpleName (tparam.Name, loc));
35 return new MemberName (name, args, loc);
37 return new MemberName (name, loc);
40 public static string MakeName (string host, string prefix)
42 return "<" + host + ">c__" + prefix + next_index++;
45 protected CompilerGeneratedClass (DeclSpace parent, GenericMethod generic,
46 int mod, Location loc)
47 : base (parent.NamespaceEntry, parent,
48 MakeProxyName (generic, loc), mod | Modifiers.COMPILER_GENERATED, null)
50 this.generic_method = generic;
52 if (generic != null) {
53 ArrayList list = new ArrayList ();
54 foreach (TypeParameter tparam in generic.TypeParameters) {
55 if (tparam.Constraints != null)
56 list.Add (tparam.Constraints.Clone ());
58 SetParameterInfo (list);
61 parent.PartialContainer.AddCompilerGeneratedClass (this);
64 protected override bool DefineNestedTypes ()
66 RootContext.RegisterCompilerGeneratedType (TypeBuilder);
67 return base.DefineNestedTypes ();
70 protected override bool DoDefineMembers ()
72 members_defined = true;
74 if (!base.DoDefineMembers ())
77 if (CompilerGenerated != null) {
78 foreach (CompilerGeneratedClass c in CompilerGenerated) {
79 if (!c.DefineMembers ())
80 throw new InternalErrorException ();
87 protected override bool DoResolveMembers ()
89 if (CompilerGenerated != null) {
90 foreach (CompilerGeneratedClass c in CompilerGenerated) {
91 if (!c.ResolveMembers ())
96 return base.DoResolveMembers ();
99 public GenericMethod GenericMethod {
100 get { return generic_method; }
103 public Parameters InflateParameters (Parameters ps)
105 if (generic_method == null)
112 Parameter[] inflated_params = new Parameter [n];
113 Type[] inflated_types = new Type [n];
115 for (int i = 0; i < n; ++i) {
116 Parameter p = ps [i];
117 Type it = InflateType (p.ExternalType ()).ResolveAsTypeTerminal (this, false).Type;
118 inflated_types [i] = it;
119 inflated_params [i] = new Parameter (it, p.Name, p.ModFlags, p.OptAttributes, p.Location);
121 return Parameters.CreateFullyResolved (inflated_params, inflated_types);
124 public TypeExpr InflateType (Type it)
127 if (generic_method == null)
128 return new TypeExpression (it, Location);
130 if (it.IsGenericParameter && (it.DeclaringMethod != null)) {
131 int pos = it.GenericParameterPosition;
132 it = CurrentTypeParameters [pos].Type;
133 } else if (it.IsGenericType) {
134 Type[] args = it.GetGenericArguments ();
136 TypeArguments inflated = new TypeArguments (Location);
137 foreach (Type t in args)
138 inflated.Add (InflateType (t));
140 return new ConstructedType (it, inflated, Location);
141 } else if (it.IsArray) {
142 TypeExpr et_expr = InflateType (it.GetElementType ());
143 int rank = it.GetArrayRank ();
145 Type et = et_expr.ResolveAsTypeTerminal (this, false).Type;
146 it = et.MakeArrayType (rank);
150 return new TypeExpression (it, Location);
153 public Field CaptureVariable (string name, TypeExpr type)
156 throw new InternalErrorException ("Helper class already defined!");
158 throw new ArgumentNullException ();
160 return new CapturedVariableField (this, name, type);
163 bool members_defined;
165 internal void CheckMembersDefined ()
168 throw new InternalErrorException ("Helper class already defined!");
171 protected class CapturedVariableField : Field
173 public CapturedVariableField (CompilerGeneratedClass helper, string name,
175 : base (helper, type, Modifiers.INTERNAL, name, null, helper.Location)
177 helper.AddField (this);
182 public class ScopeInfo : CompilerGeneratedClass
184 protected readonly RootScopeInfo RootScope;
185 new public readonly DeclSpace Parent;
186 public readonly int ID = ++next_id;
187 public readonly Block ScopeBlock;
188 protected ScopeInitializer scope_initializer;
190 readonly Hashtable locals = new Hashtable ();
191 readonly Hashtable captured_scopes = new Hashtable ();
192 Hashtable captured_params;
196 public static ScopeInfo CreateScope (Block block)
198 ToplevelBlock toplevel = block.Toplevel;
199 AnonymousContainer ac = toplevel.AnonymousContainer;
201 Report.Debug (128, "CREATE SCOPE", block, block.ScopeInfo, toplevel, ac);
204 return new ScopeInfo (block, toplevel.RootScope.Parent,
205 toplevel.RootScope.GenericMethod);
207 Report.Debug (128, "CREATE SCOPE #1", ac, ac.Host, ac.Scope, ac.Block,
208 ac.Container, ac.ContainerAnonymousMethod,
212 ScopeInfo parent = null;
214 for (b = ac.Block; b != null; b = b.Parent) {
215 if (b.ScopeInfo != null) {
216 parent = b.ScopeInfo;
221 Report.Debug (128, "CREATE SCOPE #2", parent);
223 ScopeInfo new_scope = new ScopeInfo (block, parent, null);
225 Report.Debug (128, "CREATE SCOPE #3", new_scope);
230 private static int default_modflags (DeclSpace parent)
232 return parent is CompilerGeneratedClass ? Modifiers.PUBLIC : Modifiers.PRIVATE;
235 protected ScopeInfo (Block block, DeclSpace parent, GenericMethod generic)
236 : base (parent, generic, default_modflags (parent), block.StartLocation)
239 RootScope = block.Toplevel.RootScope;
242 Report.Debug (128, "NEW SCOPE", this, block,
243 block.Parent, block.Toplevel);
245 RootScope.AddScope (this);
248 protected ScopeInfo (ToplevelBlock toplevel, DeclSpace parent,
249 GenericMethod generic, Location loc)
250 : base (parent, generic, default_modflags (parent), loc)
253 RootScope = (RootScopeInfo) this;
254 ScopeBlock = toplevel;
256 Report.Debug (128, "NEW ROOT SCOPE", this, toplevel, loc);
259 protected CapturedScope[] CapturedScopes {
261 CapturedScope[] list = new CapturedScope [captured_scopes.Count];
262 captured_scopes.Values.CopyTo (list, 0);
267 protected CapturedVariable GetCapturedScope (ScopeInfo scope)
269 return (CapturedVariable) captured_scopes [scope];
272 protected void EmitScopeInstance (EmitContext ec)
274 if (scope_initializer == null) {
276 // This is needed if someone overwrites the Emit method
277 // of Statement and manually calls Block.Emit without
278 // this snippet first:
280 // ec.EmitScopeInitFromBlock (The_Block);
281 // The_Block.Emit (ec);
283 throw new InternalErrorException ();
286 scope_initializer.Emit (ec);
289 public ExpressionStatement GetScopeInitializer (EmitContext ec)
291 Report.Debug (128, "GET SCOPE INITIALIZER",
292 this, GetType (), scope_initializer, ScopeBlock);
294 if (scope_initializer == null) {
295 scope_initializer = CreateScopeInitializer ();
296 if (scope_initializer.Resolve (ec) == null)
297 throw new InternalErrorException ();
300 return scope_initializer;
303 public Type GetScopeType (EmitContext ec)
308 TypeArguments targs = new TypeArguments (Location);
310 if (ec.DeclContainer.Parent.IsGeneric)
311 foreach (TypeParameter t in ec.DeclContainer.Parent.TypeParameters)
312 targs.Add (new TypeParameterExpr (t, Location));
313 if (ec.DeclContainer.IsGeneric)
314 foreach (TypeParameter t in ec.DeclContainer.CurrentTypeParameters)
315 targs.Add (new TypeParameterExpr (t, Location));
317 Report.Debug (128, "GET SCOPE TYPE", this, TypeBuilder, targs,
318 ec.DeclContainer, ec.DeclContainer.GetType (),
319 ec.DeclContainer.Parent.Name);
321 TypeExpr te = new ConstructedType (TypeBuilder, targs, Location);
322 te = te.ResolveAsTypeTerminal (ec, false);
323 if ((te == null) || (te.Type == null))
328 protected override bool DoDefineMembers ()
330 Report.Debug (64, "SCOPE INFO DEFINE MEMBERS", this, GetType (), IsGeneric,
331 Parent.IsGeneric, GenericMethod);
333 foreach (CapturedScope child in CapturedScopes) {
334 if (!child.DefineMembers ())
338 return base.DoDefineMembers ();
341 protected override bool DoResolveMembers ()
343 Report.Debug (64, "SCOPE INFO RESOLVE MEMBERS", this, GetType (), IsGeneric,
344 Parent.IsGeneric, GenericMethod);
346 return base.DoResolveMembers ();
349 public Variable CaptureScope (ScopeInfo child)
351 CheckMembersDefined ();
352 Report.Debug (128, "CAPTURE SCOPE", this, GetType (), child, child.GetType ());
354 throw new InternalErrorException ();
355 CapturedScope captured = (CapturedScope) captured_scopes [child];
356 if (captured == null) {
357 captured = new CapturedScope (this, child);
358 captured_scopes.Add (child, captured);
363 public Variable AddLocal (LocalInfo local)
365 Report.Debug (128, "CAPTURE LOCAL", this, local);
366 Variable var = (Variable) locals [local];
368 var = new CapturedLocal (this, local);
369 locals.Add (local, var);
370 local.IsCaptured = true;
375 public Variable GetCapturedVariable (LocalInfo local)
377 return (Variable) locals [local];
380 public bool HostsParameters {
381 get { return captured_params != null; }
384 public Variable GetCapturedParameter (Parameter par)
386 if (captured_params != null)
387 return (Variable) captured_params [par];
392 public Variable AddParameter (Parameter par, int idx)
394 if (captured_params == null)
395 captured_params = new Hashtable ();
397 Variable var = (Variable) captured_params [par];
399 var = new CapturedParameter (this, par, idx);
400 captured_params.Add (par, var);
401 par.IsCaptured = true;
407 protected string MakeFieldName (string local_name)
409 return "<" + ID + ":" + local_name + ">";
412 protected virtual ScopeInitializer CreateScopeInitializer ()
414 return new ScopeInitializer (this);
417 protected abstract class CapturedVariable : Variable
419 public readonly ScopeInfo Scope;
420 public readonly string Name;
422 public FieldExpr FieldInstance;
423 protected Field field;
425 protected CapturedVariable (ScopeInfo scope, string name)
431 protected CapturedVariable (ScopeInfo scope, string name, Type type)
434 this.field = scope.CaptureVariable (
435 scope.MakeFieldName (name), scope.RootScope.InflateType (type));
439 get { return field; }
442 public override Type Type {
443 get { return Field.MemberType; }
446 public override bool HasInstance {
450 public override bool NeedsTemporary {
454 protected FieldInfo GetField (EmitContext ec)
456 if ((ec.CurrentBlock != null) &&
457 (ec.CurrentBlock.Toplevel != Scope.ScopeBlock.Toplevel))
458 return Field.FieldBuilder;
460 return FieldInstance.FieldInfo;
463 public override void EmitInstance (EmitContext ec)
465 if ((ec.CurrentAnonymousMethod != null) &&
466 (ec.CurrentAnonymousMethod.Scope == Scope)) {
467 ec.ig.Emit (OpCodes.Ldarg_0);
471 Scope.EmitScopeInstance (ec);
474 public override void Emit (EmitContext ec)
476 ec.ig.Emit (OpCodes.Ldfld, GetField (ec));
479 public override void EmitAssign (EmitContext ec)
481 ec.ig.Emit (OpCodes.Stfld, GetField (ec));
484 public override void EmitAddressOf (EmitContext ec)
486 ec.ig.Emit (OpCodes.Ldflda, GetField (ec));
490 protected class CapturedParameter : CapturedVariable {
491 public readonly Parameter Parameter;
492 public readonly int Idx;
494 public CapturedParameter (ScopeInfo scope, Parameter par, int idx)
495 : base (scope, par.Name, par.ParameterType)
497 this.Parameter = par;
501 public override string ToString ()
503 return String.Format ("{0} ({1}:{2}:{3})", GetType (), Field,
504 Parameter.Name, Idx);
508 protected class CapturedLocal : CapturedVariable {
509 public readonly LocalInfo Local;
511 public CapturedLocal (ScopeInfo scope, LocalInfo local)
512 : base (scope, local.Name, local.VariableType)
517 public override string ToString ()
519 return String.Format ("{0} ({1}:{2})", GetType (), Field,
524 protected class CapturedThis : CapturedVariable {
525 public CapturedThis (RootScopeInfo host)
526 : base (host, "<>THIS", host.ParentType)
530 protected class CapturedScope : CapturedVariable {
531 public readonly ScopeInfo ChildScope;
533 public CapturedScope (ScopeInfo root, ScopeInfo child)
534 : base (root, "scope" + child.ID)
536 this.ChildScope = child;
539 public bool DefineMembers ()
541 Type type = ChildScope.IsGeneric ?
542 ChildScope.CurrentType : ChildScope.TypeBuilder;
543 Report.Debug (128, "CAPTURED SCOPE DEFINE MEMBERS", this, Scope,
544 ChildScope, Name, type);
546 throw new InternalErrorException ();
547 field = Scope.CaptureVariable (
548 Scope.MakeFieldName (Name), Scope.InflateType (type));
552 public override string ToString ()
554 return String.Format ("CapturedScope ({1} captured in {0})",
559 static void DoPath (StringBuilder sb, ScopeInfo start)
561 sb.Append ((start.ID).ToString ());
564 public override string ToString ()
566 StringBuilder sb = new StringBuilder ();
572 return sb.ToString ();
575 protected class ScopeInitializer : ExpressionStatement
578 CapturedVariable captured_scope;
579 LocalBuilder scope_instance;
580 ConstructorInfo scope_ctor;
584 public ScopeInitializer (ScopeInfo scope)
587 this.loc = scope.Location;
588 eclass = ExprClass.Value;
591 public ScopeInfo Scope {
592 get { return scope; }
595 public override Expression DoResolve (EmitContext ec)
597 if (scope_ctor != null)
600 Report.Debug (64, "RESOLVE SCOPE INITIALIZER BASE", this, Scope,
601 ec, ec.CurrentBlock);
603 type = Scope.GetScopeType (ec);
605 throw new InternalErrorException ();
607 if (!DoResolveInternal (ec))
608 throw new InternalErrorException ();
613 protected virtual bool DoResolveInternal (EmitContext ec)
615 MethodGroupExpr mg = (MethodGroupExpr) Expression.MemberLookupFinal (
616 ec, ec.ContainerType, type, ".ctor", MemberTypes.Constructor,
617 AllBindingFlags | BindingFlags.DeclaredOnly, loc);
619 throw new InternalErrorException ();
621 scope_ctor = (ConstructorInfo) mg.Methods [0];
623 Report.Debug (128, "RESOLVE THE INIT", this, Scope, Scope.RootScope,
624 Scope.RootScope.GetType ());
626 ScopeInfo host = Scope.RootScope;
627 if ((Scope != host) && (Scope.RootScope is IteratorHost)) {
628 captured_scope = host.GetCapturedScope (Scope);
629 Type root = host.GetScopeType (ec);
630 FieldExpr fe = (FieldExpr) Expression.MemberLookup (
631 type, root, captured_scope.Field.Name, loc);
633 throw new InternalErrorException ();
635 fe.InstanceExpression = this;
636 captured_scope.FieldInstance = fe;
638 Report.Debug (128, "RESOLVE THE INIT #1", this,
641 scope_instance = ec.ig.DeclareLocal (type);
643 foreach (CapturedLocal local in Scope.locals.Values) {
644 FieldExpr fe = (FieldExpr) Expression.MemberLookup (
645 ec.ContainerType, type, local.Field.Name, loc);
646 Report.Debug (64, "RESOLVE SCOPE INITIALIZER #2", this, Scope,
647 Scope, ec, ec.ContainerType, type,
648 local.Field, local.Field.Name, loc, fe);
650 throw new InternalErrorException ();
652 fe.InstanceExpression = this;
653 local.FieldInstance = fe;
656 if (Scope.HostsParameters) {
657 foreach (CapturedParameter cp in Scope.captured_params.Values) {
658 FieldExpr fe = (FieldExpr) Expression.MemberLookup (
659 ec.ContainerType, type, cp.Field.Name, loc);
661 throw new InternalErrorException ();
663 fe.InstanceExpression = this;
664 cp.FieldInstance = fe;
668 foreach (CapturedScope scope in Scope.CapturedScopes) {
669 FieldExpr fe = (FieldExpr) Expression.MemberLookup (
670 ec.ContainerType, type, scope.Field.Name, loc);
671 Report.Debug (64, "RESOLVE SCOPE INITIALIZER #3", this, Scope,
672 scope, ec, ec.ContainerType, type,
673 scope.Field, scope.Field.Name, loc, fe);
675 throw new InternalErrorException ();
677 fe.InstanceExpression = this;
678 scope.FieldInstance = fe;
684 protected virtual void EmitParameterReference (EmitContext ec,
685 CapturedParameter cp)
687 int extra = ec.MethodIsStatic ? 0 : 1;
688 ParameterReference.EmitLdArg (ec.ig, cp.Idx + extra);
694 protected virtual void DoEmit (EmitContext ec)
696 if ((ec.CurrentBlock != null) &&
697 (ec.CurrentBlock.Toplevel != Scope.ScopeBlock.Toplevel)) {
698 ec.ig.Emit (OpCodes.Ldarg_0);
700 if (ec.CurrentAnonymousMethod != null) {
701 ScopeInfo host = ec.CurrentAnonymousMethod.Scope;
702 Variable captured = host.GetCapturedScope (scope);
703 Report.Debug (128, "EMIT SCOPE INSTANCE #2",
704 ec.CurrentAnonymousMethod, host,
706 if (captured != null)
709 } else if (scope_instance != null)
710 ec.ig.Emit (OpCodes.Ldloc, scope_instance);
712 Report.Debug (128, "DO EMIT", this, Scope, ec,
713 scope_instance, captured_scope);
714 captured_scope.EmitInstance (ec);
715 captured_scope.Emit (ec);
719 protected void DoEmitInstance (EmitContext ec)
721 Report.Debug (128, "DO EMIT INSTANCE", this, Scope, ec,
722 scope_instance, captured_scope);
724 if (scope_instance != null)
725 ec.ig.Emit (OpCodes.Ldloc, scope_instance);
727 captured_scope.EmitInstance (ec);
730 protected virtual void EmitScopeConstructor (EmitContext ec)
732 ec.ig.Emit (OpCodes.Newobj, scope_ctor);
735 public override void Emit (EmitContext ec)
738 throw new InternalErrorException (
739 "Scope {0} not initialized yet", scope);
744 public override void EmitStatement (EmitContext ec)
749 DoEmitStatement (ec);
753 protected virtual void DoEmitStatement (EmitContext ec)
755 Report.Debug (128, "EMIT SCOPE INITIALIZER STATEMENT", this, id,
756 Scope, scope_instance, ec);
758 ec.ig.Emit (OpCodes.Nop);
759 ec.ig.Emit (OpCodes.Ldc_I4, id);
760 ec.ig.Emit (OpCodes.Pop);
761 ec.ig.Emit (OpCodes.Nop);
763 if (scope_instance == null)
764 ec.ig.Emit (OpCodes.Ldarg_0);
765 EmitScopeConstructor (ec);
766 if (scope_instance != null)
767 ec.ig.Emit (OpCodes.Stloc, scope_instance);
769 captured_scope.EmitAssign (ec);
771 if (Scope.HostsParameters) {
772 foreach (CapturedParameter cp in Scope.captured_params.Values) {
773 Report.Debug (128, "EMIT SCOPE INIT #6", this,
774 ec, ec.IsStatic, Scope, cp, cp.Field.Name);
776 EmitParameterReference (ec, cp);
777 ec.ig.Emit (OpCodes.Stfld, cp.FieldInstance.FieldInfo);
781 if (Scope is IteratorHost)
784 foreach (CapturedScope scope in Scope.CapturedScopes) {
785 ScopeInfo child = scope.ChildScope;
787 Report.Debug (128, "EMIT SCOPE INIT #5", this, Scope,
788 scope.Scope, scope.ChildScope);
790 ExpressionStatement init = child.GetScopeInitializer (ec);
791 init.EmitStatement (ec);
794 scope.ChildScope.EmitScopeInstance (ec);
795 scope.EmitAssign (ec);
801 public class RootScopeInfo : ScopeInfo
803 public RootScopeInfo (ToplevelBlock toplevel, DeclSpace parent,
804 GenericMethod generic, Location loc)
805 : base (toplevel, parent, generic, loc)
807 scopes = new ArrayList ();
810 TypeExpr parent_type;
811 CapturedVariableField parent_link;
812 CapturedThis this_variable;
813 protected ArrayList scopes;
815 public virtual bool IsIterator {
816 get { return false; }
819 public RootScopeInfo ParentHost {
820 get { return Parent.PartialContainer as RootScopeInfo; }
823 public Type ParentType {
824 get { return parent_type.Type; }
827 public Field ParentLink {
828 get { return parent_link; }
831 protected CapturedThis THIS {
832 get { return this_variable; }
835 public Variable CaptureThis ()
837 if (ParentHost != null)
838 return ParentHost.CaptureThis ();
840 CheckMembersDefined ();
841 if (this_variable == null)
842 this_variable = new CapturedThis (this);
843 return this_variable;
846 public void AddScope (ScopeInfo scope)
852 public void LinkScopes ()
854 Report.Debug (128, "LINK SCOPES", this, linked, scopes);
860 if (ParentHost != null)
861 ParentHost.LinkScopes ();
863 foreach (ScopeInfo si in scopes) {
865 throw new InternalErrorException ();
866 if (si.DefineType () == null)
867 throw new InternalErrorException ();
868 if (!si.ResolveType ())
869 throw new InternalErrorException ();
872 foreach (ScopeInfo si in scopes) {
873 if (!si.ResolveMembers ())
874 throw new InternalErrorException ();
875 if (!si.DefineMembers ())
876 throw new InternalErrorException ();
880 protected override ScopeInitializer CreateScopeInitializer ()
882 return new RootScopeInitializer (this);
885 protected override bool DefineNestedTypes ()
887 if (Parent.IsGeneric) {
888 parent_type = new ConstructedType (
889 Parent.TypeBuilder, Parent.TypeParameters, Location);
890 parent_type = parent_type.ResolveAsTypeTerminal (this, false);
891 if ((parent_type == null) || (parent_type.Type == null))
894 parent_type = new TypeExpression (Parent.TypeBuilder, Location);
897 CompilerGeneratedClass parent = Parent.PartialContainer as CompilerGeneratedClass;
899 parent_link = new CapturedVariableField (this, "<>parent", parent_type);
901 return base.DefineNestedTypes ();
904 protected override bool DoDefineMembers ()
906 ArrayList args = new ArrayList ();
907 if (this is IteratorHost)
908 args.Add (new Parameter (
909 TypeManager.int32_type, "$PC", Parameter.Modifier.NONE,
913 if (Parent is CompilerGeneratedClass)
914 pfield = parent_link;
916 pfield = this_variable != null ? this_variable.Field : null;
918 args.Add (new Parameter (
919 pfield.MemberType, "parent", Parameter.Modifier.NONE,
922 Parameter[] ctor_params = new Parameter [args.Count];
923 args.CopyTo (ctor_params, 0);
924 Constructor ctor = new Constructor (
925 this, MemberName.Name, Modifiers.PUBLIC,
926 new Parameters (ctor_params),
927 new GeneratedBaseInitializer (Location),
929 AddConstructor (ctor);
931 ctor.Block = new ToplevelBlock (null, Location);
932 ctor.Block.AddStatement (new TheCtor (this));
934 return base.DoDefineMembers ();
937 protected virtual void EmitScopeConstructor (EmitContext ec)
939 int pos = (this is IteratorHost) ? 2 : 1;
942 if (Parent is CompilerGeneratedClass)
943 pfield = parent_link;
945 pfield = this_variable != null ? this_variable.Field : null;
947 if (pfield != null) {
948 ec.ig.Emit (OpCodes.Ldarg_0);
949 ec.ig.Emit (OpCodes.Ldarg, pos);
950 ec.ig.Emit (OpCodes.Stfld, pfield.FieldBuilder);
955 protected class TheCtor : Statement
959 public TheCtor (RootScopeInfo host)
964 public override bool Resolve (EmitContext ec)
969 protected override void DoEmit (EmitContext ec)
971 host.EmitScopeConstructor (ec);
975 protected class RootScopeInitializer : ScopeInitializer
979 public RootScopeInitializer (RootScopeInfo host)
985 public RootScopeInfo Host {
989 protected override bool DoResolveInternal (EmitContext ec)
991 Report.Debug (64, "RESOLVE ANONYMOUS METHOD HOST INITIALIZER",
992 this, Host, Host.ParentType, loc);
994 if (Host.THIS != null) {
995 FieldExpr fe = (FieldExpr) Expression.MemberLookup (
996 ec.ContainerType, type, Host.THIS.Field.Name, loc);
998 throw new InternalErrorException ();
1000 fe.InstanceExpression = this;
1001 Host.THIS.FieldInstance = fe;
1004 return base.DoResolveInternal (ec);
1007 protected virtual bool IsGetEnumerator {
1008 get { return false; }
1011 protected override void EmitScopeConstructor (EmitContext ec)
1013 if (host.THIS != null) {
1014 ec.ig.Emit (OpCodes.Ldarg_0);
1015 if (IsGetEnumerator)
1016 ec.ig.Emit (OpCodes.Ldfld, host.THIS.Field.FieldBuilder);
1017 else if (host.THIS.Type.IsValueType)
1018 Expression.LoadFromPtr (ec.ig, host.THIS.Type);
1019 } else if (host.ParentLink != null)
1020 ec.ig.Emit (OpCodes.Ldarg_0);
1022 base.EmitScopeConstructor (ec);
1028 public interface IAnonymousContainer
1034 GenericMethod GenericMethod {
1038 RootScopeInfo RootScope {
1047 public interface IAnonymousHost
1050 // Invoked if a yield statement is found in the body
1055 // Invoked if an anonymous method is found in the body
1057 void AddAnonymousMethod (AnonymousMethodExpression anonymous);
1060 public class AnonymousMethodExpression : Expression, IAnonymousContainer, IAnonymousHost
1062 public readonly AnonymousMethodExpression Parent;
1063 public readonly TypeContainer Host;
1064 public readonly Parameters Parameters;
1066 public ToplevelBlock Block;
1067 protected AnonymousMethod anonymous;
1069 protected Block container;
1070 protected readonly GenericMethod generic;
1072 public Block Container {
1073 get { return container; }
1076 public GenericMethod GenericMethod {
1077 get { return generic; }
1080 public AnonymousMethod AnonymousMethod {
1081 get { return anonymous; }
1084 public RootScopeInfo RootScope {
1085 get { return root_scope; }
1088 public AnonymousMethodExpression (AnonymousMethodExpression parent,
1089 GenericMethod generic, TypeContainer host,
1090 Parameters parameters, Block container,
1093 this.Parent = parent;
1094 this.generic = parent != null ? null : generic;
1096 this.Parameters = parameters;
1097 this.container = container;
1100 Report.Debug (64, "NEW ANONYMOUS METHOD EXPRESSION", this, parent, host,
1104 parent.AddAnonymousMethod (this);
1108 RootScopeInfo root_scope;
1110 static int next_index;
1112 void IAnonymousHost.SetYields ()
1114 throw new InvalidOperationException ();
1117 public void AddAnonymousMethod (AnonymousMethodExpression anonymous)
1119 if (children == null)
1120 children = new ArrayList ();
1121 children.Add (anonymous);
1124 public bool CreateAnonymousHelpers ()
1126 Report.Debug (64, "ANONYMOUS METHOD EXPRESSION CREATE ROOT SCOPE",
1127 this, Host, container, loc);
1129 if (container != null)
1130 root_scope = container.Toplevel.CreateRootScope (Host);
1132 if (children != null) {
1133 foreach (AnonymousMethodExpression child in children) {
1134 if (!child.CreateAnonymousHelpers ())
1142 public override string ExprClassName {
1144 return "anonymous method";
1148 public virtual bool HasExplicitParameters {
1154 public virtual bool ImplicitStandardConversionExists (Type delegate_type)
1156 if (Parameters == null)
1159 MethodGroupExpr invoke_mg = Delegate.GetInvokeMethod (
1160 Host.TypeBuilder, delegate_type, loc);
1161 MethodInfo invoke_mb = (MethodInfo) invoke_mg.Methods [0];
1162 ParameterData invoke_pd = TypeManager.GetParameterData (invoke_mb);
1164 if (Parameters.Count != invoke_pd.Count)
1167 for (int i = 0; i < Parameters.Count; ++i) {
1168 if (invoke_pd.ParameterType (i) != Parameters.ParameterType (i))
1174 protected Expression CompatibleChecks (EmitContext ec, Type delegate_type)
1176 if (!ec.IsAnonymousMethodAllowed) {
1177 Report.Error (1706, loc,
1178 "Anonymous methods are not allowed in the " +
1179 "attribute declaration");
1183 if (!TypeManager.IsDelegateType (delegate_type)){
1184 Report.Error (1660, loc,
1185 "Cannot convert anonymous method block to type " +
1186 "`{0}' because it is not a delegate type",
1187 TypeManager.CSharpName (delegate_type));
1193 protected bool VerifyParameterCompatibility (Type delegate_type, ParameterData invoke_pd, bool showErrors)
1195 if (Parameters.Count != invoke_pd.Count) {
1199 Report.SymbolRelatedToPreviousError (delegate_type);
1200 Report.Error (1593, loc, "Delegate `{0}' does not take `{1}' arguments",
1201 TypeManager.CSharpName (delegate_type), Parameters.Count.ToString ());
1205 if (!HasExplicitParameters)
1209 for (int i = 0; i < Parameters.Count; ++i) {
1210 Parameter.Modifier p_mod = invoke_pd.ParameterModifier (i);
1211 if (Parameters.ParameterModifier (i) != p_mod && p_mod != Parameter.Modifier.PARAMS) {
1215 if (p_mod == Parameter.Modifier.NONE)
1216 Report.Error (1677, loc, "Parameter `{0}' should not be declared with the `{1}' keyword",
1217 (i + 1).ToString (), Parameter.GetModifierSignature (Parameters.ParameterModifier (i)));
1219 Report.Error (1676, loc, "Parameter `{0}' must be declared with the `{1}' keyword",
1220 (i+1).ToString (), Parameter.GetModifierSignature (p_mod));
1225 // We assume that generic parameters are always inflated
1226 if (TypeManager.IsGenericParameter (invoke_pd.Types[i]))
1229 if (invoke_pd.ParameterType (i) != Parameters.ParameterType (i)) {
1233 Report.Error (1678, loc, "Parameter `{0}' is declared as type `{1}' but should be `{2}'",
1235 TypeManager.CSharpName (Parameters.ParameterType (i)),
1236 TypeManager.CSharpName (invoke_pd.ParameterType (i)));
1245 // TODO: Merge with lambda DoCompatibleTest
1246 // TODO: Need to sort out error reporting
1247 public Expression InferTypeArguments (EmitContext ec, Type delegateType)
1249 if (anonymous != null)
1250 return anonymous.AnonymousDelegate;
1252 if (!delegateType.ContainsGenericParameters)
1253 throw new InternalErrorException ("No inference required");
1255 // It looks like we cannot generate arguments during type inference
1256 if (Parameters == null)
1259 delegateType = delegateType.GetGenericTypeDefinition ();
1261 MethodGroupExpr invoke_mg = Delegate.GetInvokeMethod (
1262 ec.ContainerType, delegateType, loc);
1263 MethodInfo invoke_mb = (MethodInfo) invoke_mg.Methods [0];
1264 ParameterData invoke_pd = TypeManager.GetParameterData (invoke_mb);
1266 if (!VerifyParameterCompatibility (delegateType, invoke_pd, false))
1269 Type[] g_arguments = delegateType.GetGenericArguments ();
1270 Type[] inferred_arguments = new Type [g_arguments.Length];
1271 g_arguments.CopyTo (inferred_arguments, 0);
1273 for (int i = 0; i < invoke_pd.Count; ++i) {
1274 if (!invoke_pd.Types[i].IsGenericParameter)
1277 inferred_arguments [invoke_pd.Types[i].GenericParameterPosition] = Parameters.Types[i];
1280 int return_type_pos = -1;
1281 if (TypeManager.IsGenericParameter (invoke_mb.ReturnType)) {
1282 ec.InferReturnType = true;
1283 return_type_pos = invoke_mb.ReturnType.GenericParameterPosition;
1286 anonymous = new AnonymousMethod (
1287 Parent != null ? Parent.AnonymousMethod : null, RootScope, Host,
1288 GenericMethod, Parameters, Container, Block, invoke_mb.ReturnType,
1291 if (!anonymous.Resolve (ec))
1294 if (return_type_pos != -1) {
1295 inferred_arguments [return_type_pos] = anonymous.ReturnType;
1298 anonymous.AnonymousDelegate.Type = delegateType.GetGenericTypeDefinition ().MakeGenericType (inferred_arguments);
1299 anonymous.DelegateType = anonymous.AnonymousDelegate.Type;
1301 return anonymous.AnonymousDelegate;
1306 // Returns true if this anonymous method can be implicitly
1307 // converted to the delegate type `delegate_type'
1309 public virtual Expression Compatible (EmitContext ec, Type delegate_type)
1311 if (anonymous != null)
1312 return anonymous.AnonymousDelegate;
1314 if (CompatibleChecks (ec, delegate_type) == null)
1318 // At this point its the first time we know the return type that is
1319 // needed for the anonymous method. We create the method here.
1322 MethodGroupExpr invoke_mg = Delegate.GetInvokeMethod (
1323 ec.ContainerType, delegate_type, loc);
1324 MethodInfo invoke_mb = (MethodInfo) invoke_mg.Methods [0];
1325 ParameterData invoke_pd = TypeManager.GetParameterData (invoke_mb);
1327 Parameters parameters = CreateParameters (ec, delegate_type, invoke_pd);
1328 if (parameters == null)
1332 // Second: the return type of the delegate must be compatible with
1333 // the anonymous type. Instead of doing a pass to examine the block
1334 // we satisfy the rule by setting the return type on the EmitContext
1335 // to be the delegate type return type.
1338 //MethodBuilder builder = method_data.MethodBuilder;
1339 //ILGenerator ig = builder.GetILGenerator ();
1341 Report.Debug (64, "COMPATIBLE", this, Parent, GenericMethod, Host,
1342 Container, Block, invoke_mb.ReturnType, delegate_type,
1343 TypeManager.IsGenericType (delegate_type), loc);
1345 return ResolveMethod (ec, parameters, invoke_mb.ReturnType, delegate_type);
1348 protected virtual Parameters CreateParameters (EmitContext ec, Type delegateType, ParameterData delegateParameters)
1350 if (Parameters == null) {
1352 // We provide a set of inaccessible parameters
1354 Parameter[] fixedpars = new Parameter[delegateParameters.Count];
1356 for (int i = 0; i < delegateParameters.Count; i++) {
1357 Parameter.Modifier i_mod = delegateParameters.ParameterModifier (i);
1358 if ((i_mod & Parameter.Modifier.OUTMASK) != 0) {
1359 Report.Error (1688, loc, "Cannot convert anonymous " +
1360 "method block without a parameter list " +
1361 "to delegate type `{0}' because it has " +
1362 "one or more `out' parameters.",
1363 TypeManager.CSharpName (delegateType));
1366 fixedpars[i] = new Parameter (
1367 delegateParameters.ParameterType (i), "+" + (++next_index),
1368 delegateParameters.ParameterModifier (i), null, loc);
1371 Parameters parameters = new Parameters (fixedpars);
1372 if (!parameters.Resolve (ec))
1377 if (!VerifyParameterCompatibility (delegateType, delegateParameters, true)) {
1378 Report.Error (1661, loc,
1379 "Cannot convert `{0}' to delegate type `{1}' since there is a parameter mismatch",
1380 GetSignatureForError (), TypeManager.CSharpName (delegateType));
1387 public override Expression DoResolve (EmitContext ec)
1390 // Set class type, set type
1393 eclass = ExprClass.Value;
1396 // This hack means `The type is not accessible
1397 // anywhere', we depend on special conversion
1400 type = TypeManager.anonymous_method_type;
1402 if ((Parameters != null) && !Parameters.Resolve (ec))
1408 public override void Emit (EmitContext ec)
1410 // nothing, as we only exist to not do anything.
1413 public override string GetSignatureForError ()
1415 return ExprClassName;
1418 public bool IsIterator {
1419 get { return false; }
1422 protected virtual Expression ResolveMethod (EmitContext ec, Parameters parameters, Type returnType, Type delegateType)
1424 anonymous = new AnonymousMethod (
1425 Parent != null ? Parent.AnonymousMethod : null, RootScope, Host,
1426 GenericMethod, parameters, Container, Block, returnType,
1429 if (!anonymous.Resolve (ec))
1432 return anonymous.AnonymousDelegate;
1435 protected override void CloneTo (CloneContext clonectx, Expression t)
1437 AnonymousMethodExpression target = (AnonymousMethodExpression) t;
1439 target.Block = (ToplevelBlock) clonectx.LookupBlock (Block);
1440 target.container = clonectx.LookupBlock (Block);
1444 public abstract class AnonymousContainer : IAnonymousContainer
1446 public readonly Location Location;
1448 public Parameters Parameters;
1451 // The block that makes up the body for the anonymous mehtod
1453 public readonly ToplevelBlock Block;
1455 public readonly int ModFlags;
1456 public Type ReturnType;
1457 public readonly DeclSpace Host;
1460 // The implicit method we create
1462 protected Method method;
1463 protected EmitContext aec;
1465 // The emit context for the anonymous method
1466 protected bool unreachable;
1467 protected readonly Block container;
1468 protected readonly GenericMethod generic;
1471 // Points to our container anonymous method if its present
1473 public readonly AnonymousContainer ContainerAnonymousMethod;
1475 protected AnonymousContainer (AnonymousContainer parent, DeclSpace host,
1476 GenericMethod generic, Parameters parameters,
1477 Block container, ToplevelBlock block,
1478 Type return_type, int mod, Location loc)
1480 this.ContainerAnonymousMethod = parent;
1481 this.ReturnType = return_type;
1482 this.ModFlags = mod | Modifiers.COMPILER_GENERATED;
1485 this.container = container;
1486 this.generic = parent != null ? null : generic;
1487 this.Parameters = parameters;
1489 this.Location = loc;
1491 block.AnonymousContainer = this;
1494 public Method Method {
1495 get { return method; }
1498 public abstract string ContainerType {
1502 public abstract RootScopeInfo RootScope {
1506 public abstract ScopeInfo Scope {
1510 public abstract string GetSignatureForError ();
1512 public virtual bool ResolveNoDefine (EmitContext ec)
1514 Report.Debug (64, "RESOLVE ANONYMOUS METHOD", this, Location, ec,
1515 RootScope, Parameters, ec.IsStatic);
1517 if (ReturnType != null) {
1518 TypeExpr return_type_expr;
1519 if (RootScope != null)
1520 return_type_expr = RootScope.InflateType (ReturnType);
1522 return_type_expr = new TypeExpression (ReturnType, Location);
1523 return_type_expr = return_type_expr.ResolveAsTypeTerminal (ec, false);
1524 if ((return_type_expr == null) || (return_type_expr.Type == null))
1526 ReturnType = return_type_expr.Type;
1529 if (RootScope != null)
1530 Parameters = RootScope.InflateParameters (Parameters);
1532 aec = new EmitContext (
1533 ec.ResolveContext, ec.TypeContainer,
1534 RootScope != null ? RootScope : Host, Location, null, ReturnType,
1535 /* REVIEW */ (ec.InIterator ? Modifiers.METHOD_YIELDS : 0) |
1536 (ec.InUnsafe ? Modifiers.UNSAFE : 0), /* No constructor */ false);
1538 aec.CurrentAnonymousMethod = this;
1539 aec.IsFieldInitializer = ec.IsFieldInitializer;
1540 aec.IsStatic = ec.IsStatic;
1541 aec.InferReturnType = ec.InferReturnType;
1543 IDisposable aec_dispose = null;
1544 if (ec.IsInProbingMode)
1545 aec_dispose = aec.Set (EmitContext.Flags.ProbingMode);
1547 Report.Debug (64, "RESOLVE ANONYMOUS METHOD #1", this, Location, ec, aec,
1548 RootScope, Parameters, Block);
1551 bool res = aec.ResolveTopBlock (ec, Block, Parameters, null, out unreachable);
1553 if (aec_dispose != null)
1554 aec_dispose.Dispose ();
1559 public virtual bool Resolve (EmitContext ec)
1561 if (!ResolveNoDefine (ec))
1564 Report.Debug (64, "RESOLVE ANONYMOUS METHOD #3", this, ec, aec, Block);
1566 if (aec.InferReturnType)
1567 ReturnType = aec.ReturnType;
1569 method = DoCreateMethodHost (ec);
1574 if (!method.ResolveMembers ())
1576 return method.Define ();
1579 protected abstract Method DoCreateMethodHost (EmitContext ec);
1581 public Block Container {
1582 get { return container; }
1585 public GenericMethod GenericMethod {
1586 get { return generic; }
1589 public abstract bool IsIterator {
1593 protected class AnonymousMethodMethod : Method
1595 public readonly AnonymousContainer AnonymousMethod;
1596 public readonly ScopeInfo Scope;
1598 public AnonymousMethodMethod (AnonymousContainer am, ScopeInfo scope,
1599 GenericMethod generic, TypeExpr return_type,
1600 int mod, MemberName name, Parameters parameters)
1601 : base (scope != null ? scope : am.Host,
1602 generic, return_type, mod | Modifiers.COMPILER_GENERATED, false, name, parameters, null)
1604 this.AnonymousMethod = am;
1607 if (scope != null) {
1608 scope.CheckMembersDefined ();
1609 scope.AddMethod (this);
1611 ModFlags |= Modifiers.STATIC;
1612 am.Host.PartialContainer.AddMethod (this);
1617 public override EmitContext CreateEmitContext (DeclSpace tc, ILGenerator ig)
1619 EmitContext aec = AnonymousMethod.aec;
1621 aec.MethodIsStatic = Scope == null;
1627 public class LambdaMethod : AnonymousMethod
1629 public LambdaMethod (AnonymousMethod parent, RootScopeInfo root_scope,
1630 DeclSpace host, GenericMethod generic,
1631 Parameters parameters, Block container,
1632 ToplevelBlock block, Type return_type, Type delegate_type,
1634 : base (parent, root_scope, host, generic, parameters, container, block,
1635 return_type, delegate_type, loc)
1639 public override string ContainerType {
1641 return "lambda expression";
1646 public class AnonymousMethod : AnonymousContainer
1648 public Type DelegateType;
1651 // The value return by the Compatible call, this ensure that
1652 // the code works even if invoked more than once (Resolve called
1653 // more than once, due to the way Convert.ImplicitConversion works
1655 Expression anonymous_delegate;
1656 RootScopeInfo root_scope;
1659 public AnonymousMethod (AnonymousMethod parent, RootScopeInfo root_scope,
1660 DeclSpace host, GenericMethod generic,
1661 Parameters parameters, Block container,
1662 ToplevelBlock block, Type return_type, Type delegate_type,
1664 : base (parent, host, generic, parameters, container, block,
1665 return_type, 0, loc)
1667 this.DelegateType = delegate_type;
1668 this.root_scope = root_scope;
1671 public override string ContainerType {
1672 get { return "anonymous method"; }
1675 public override RootScopeInfo RootScope {
1676 get { return root_scope; }
1679 public override ScopeInfo Scope {
1680 get { return scope; }
1683 public override bool IsIterator {
1684 get { return false; }
1687 public Expression AnonymousDelegate {
1688 get { return anonymous_delegate; }
1691 public override string GetSignatureForError ()
1693 return TypeManager.CSharpName (DelegateType);
1697 // Creates the host for the anonymous method
1699 protected override Method DoCreateMethodHost (EmitContext ec)
1701 MemberCore mc = ec.ResolveContext as MemberCore;
1702 string name = CompilerGeneratedClass.MakeName (mc.Name, null);
1703 MemberName member_name;
1705 Report.Debug (128, "CREATE METHOD HOST #0", RootScope);
1710 Report.Debug (128, "CREATE METHOD HOST #1", this, Block, Block.ScopeInfo,
1711 RootScope, Location);
1713 for (b = Block.Parent; b != null; b = b.Parent) {
1714 Report.Debug (128, "CREATE METHOD HOST #2", this, Block,
1716 if (b.ScopeInfo != null) {
1717 scope = b.ScopeInfo;
1723 scope.CheckMembersDefined ();
1725 ArrayList scopes = new ArrayList ();
1727 for (b = b.Parent; b != null; b = b.Parent) {
1728 if (b.ScopeInfo != null)
1729 scopes.Add (b.ScopeInfo);
1733 Report.Debug (128, "CREATE METHOD HOST #1", this, scope, scopes);
1735 foreach (ScopeInfo si in scopes)
1736 scope.CaptureScope (si);
1738 Report.Debug (128, "CREATE METHOD HOST", this, Block, container,
1739 RootScope, scope, scopes, Location,
1740 ContainerAnonymousMethod);
1742 GenericMethod generic_method = null;
1744 if (TypeManager.IsGenericType (DelegateType)) {
1745 TypeArguments args = new TypeArguments (Location);
1747 Type dt = DelegateType.GetGenericTypeDefinition ();
1749 Type[] tparam = TypeManager.GetTypeArguments (dt);
1750 for (int i = 0; i < tparam.Length; i++)
1751 args.Add (new SimpleName (tparam [i].Name, Location));
1753 member_name = new MemberName (name, args, Location);
1755 Report.Debug (128, "CREATE METHOD HOST #5", this, DelegateType,
1756 TypeManager.GetTypeArguments (DelegateType),
1759 generic_method = new GenericMethod (
1760 Host.NamespaceEntry, scope, member_name,
1761 new TypeExpression (ReturnType, Location), Parameters);
1763 generic_method.SetParameterInfo (null);
1766 member_name = new MemberName (name, Location);
1768 return new AnonymousMethodMethod (
1769 this, scope, generic_method, new TypeExpression (ReturnType, Location),
1770 Modifiers.INTERNAL, member_name, Parameters);
1773 bool ResolveAnonymousDelegate (EmitContext ec)
1775 // If we are inferring the return type, set it to the discovered value.
1776 if (DelegateType == null){
1777 DelegateType = aec.ReturnType;
1779 // The special value pointing to our internal type means it failed.
1780 if (DelegateType == typeof (AnonymousDelegate))
1784 anonymous_delegate = new AnonymousDelegate (
1785 this, DelegateType, Location).Resolve (ec);
1786 if (anonymous_delegate == null)
1791 public override bool Resolve (EmitContext ec)
1793 if (!base.Resolve (ec))
1796 return ResolveAnonymousDelegate (ec);
1799 public override bool ResolveNoDefine (EmitContext ec)
1801 if (!base.ResolveNoDefine (ec))
1804 return ResolveAnonymousDelegate (ec);
1807 public MethodInfo GetMethodBuilder (EmitContext ec)
1809 MethodInfo builder = method.MethodBuilder;
1810 if ((Scope != null) && Scope.IsGeneric) {
1811 Type scope_type = Scope.GetScopeType (ec);
1812 if (scope_type == null)
1813 throw new InternalErrorException ();
1815 MethodGroupExpr mg = (MethodGroupExpr) Expression.MemberLookup (
1816 ec.ContainerType, scope_type, builder.Name, Location);
1819 throw new InternalErrorException ();
1820 builder = (MethodInfo) mg.Methods [0];
1824 if (!DelegateType.IsGenericType)
1827 Type[] targs = TypeManager.GetTypeArguments (DelegateType);
1828 return builder.MakeGenericMethod (targs);
1834 public static void Error_AddressOfCapturedVar (string name, Location loc)
1836 Report.Error (1686, loc,
1837 "Local variable `{0}' or its members cannot have their " +
1838 "address taken and be used inside an anonymous method block",
1844 // This will emit the code for the delegate, as well delegate creation on the host
1846 public class AnonymousDelegate : DelegateCreation {
1850 // if target_type is null, this means that we do not know the type
1851 // for this delegate, and we want to infer it from the various
1852 // returns (implicit and explicit) from the body of this anonymous
1855 // for example, the lambda: x => 1
1857 public AnonymousDelegate (AnonymousMethod am, Type target_type, Location l)
1864 public override Expression DoResolve (EmitContext ec)
1866 eclass = ExprClass.Value;
1869 // If we are inferencing
1872 type = ec.ReturnType;
1874 // No type was infered
1882 public override void Emit (EmitContext ec)
1884 //ec.ig.Emit (OpCodes.Ldstr, "EMIT ANONYMOUS DELEGATE");
1885 //ec.ig.Emit (OpCodes.Pop);
1888 // Now emit the delegate creation.
1890 if ((am.Method.ModFlags & Modifiers.STATIC) == 0) {
1891 Report.Debug (128, "EMIT ANONYMOUS DELEGATE", this, am, am.Scope, loc);
1892 delegate_instance_expression = am.Scope.GetScopeInitializer (ec);
1894 if (delegate_instance_expression == null)
1895 throw new InternalErrorException ();
1898 Expression ml = Expression.MemberLookup (
1899 ec.ContainerType, type, ".ctor", MemberTypes.Constructor,
1900 BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
1903 constructor_method = ((MethodGroupExpr) ml).Methods [0];
1905 if (type.IsGenericType && type is TypeBuilder)
1906 constructor_method = TypeBuilder.GetConstructor (type, (ConstructorInfo)constructor_method);
1909 delegate_method = am.GetMethodBuilder (ec);
1912 //ec.ig.Emit (OpCodes.Ldstr, "EMIT ANONYMOUS DELEGATE DONE");
1913 //ec.ig.Emit (OpCodes.Pop);
1915 Report.Debug (128, "EMIT ANONYMOUS DELEGATE DONE", this, am, am.Scope, loc);
1919 public class AnonymousClass : CompilerGeneratedClass
1921 public AnonymousClass (TypeContainer parent, Location loc)
1922 : base (parent, null, 0, loc)