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 ("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 prefix)
42 return "<>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 new Parameters (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 Block ScopeBlock;
191 public static ScopeInfo CreateScope (Block block)
193 ToplevelBlock toplevel = block.Toplevel;
194 AnonymousContainer ac = toplevel.AnonymousContainer;
196 Report.Debug (128, "CREATE SCOPE", block, block.ScopeInfo, toplevel, ac);
199 return new ScopeInfo (block, toplevel.RootScope.Parent,
200 toplevel.RootScope.GenericMethod);
202 Report.Debug (128, "CREATE SCOPE #1", ac, ac.Host, ac.Scope, ac.Block,
203 ac.Container, ac.ContainerAnonymousMethod,
207 ScopeInfo parent = null;
209 for (b = ac.Block; b != null; b = b.Parent) {
210 if (b.ScopeInfo != null) {
211 parent = b.ScopeInfo;
216 Report.Debug (128, "CREATE SCOPE #2", parent);
218 ScopeInfo new_scope = new ScopeInfo (block, parent, null);
220 Report.Debug (128, "CREATE SCOPE #3", new_scope);
225 private static int default_modflags (DeclSpace parent)
227 return parent is CompilerGeneratedClass ? Modifiers.PUBLIC : Modifiers.PRIVATE;
230 protected ScopeInfo (Block block, DeclSpace parent, GenericMethod generic)
231 : base (parent, generic, default_modflags (parent), block.StartLocation)
234 RootScope = block.Toplevel.RootScope;
237 Report.Debug (128, "NEW SCOPE", this, block,
238 block.Parent, block.Toplevel);
240 RootScope.AddScope (this);
243 protected ScopeInfo (ToplevelBlock toplevel, DeclSpace parent,
244 GenericMethod generic, Location loc)
245 : base (parent, generic, default_modflags (parent), loc)
248 RootScope = (RootScopeInfo) this;
249 ScopeBlock = toplevel;
251 Report.Debug (128, "NEW ROOT SCOPE", this, toplevel, loc);
254 protected ScopeInitializer scope_initializer;
256 Hashtable locals = new Hashtable ();
257 Hashtable captured_scopes = new Hashtable ();
258 Hashtable captured_params;
260 protected CapturedScope[] CapturedScopes {
262 CapturedScope[] list = new CapturedScope [captured_scopes.Count];
263 captured_scopes.Values.CopyTo (list, 0);
268 protected CapturedVariable GetCapturedScope (ScopeInfo scope)
270 return (CapturedVariable) captured_scopes [scope];
273 protected void EmitScopeInstance (EmitContext ec)
275 if (scope_initializer == null) {
277 // This is needed if someone overwrites the Emit method
278 // of Statement and manually calls Block.Emit without
279 // this snippet first:
281 // ec.EmitScopeInitFromBlock (The_Block);
282 // The_Block.Emit (ec);
284 throw new InternalErrorException ();
287 scope_initializer.Emit (ec);
290 public ExpressionStatement GetScopeInitializer (EmitContext ec)
292 Report.Debug (128, "GET SCOPE INITIALIZER",
293 this, GetType (), scope_initializer, ScopeBlock);
295 if (scope_initializer == null) {
296 scope_initializer = CreateScopeInitializer ();
297 if (scope_initializer.Resolve (ec) == null)
298 throw new InternalErrorException ();
301 return scope_initializer;
304 public Type GetScopeType (EmitContext ec)
309 TypeArguments targs = new TypeArguments (Location);
311 if (ec.DeclContainer.Parent.IsGeneric)
312 foreach (TypeParameter t in ec.DeclContainer.Parent.TypeParameters)
313 targs.Add (new TypeParameterExpr (t, Location));
314 if (ec.DeclContainer.IsGeneric)
315 foreach (TypeParameter t in ec.DeclContainer.CurrentTypeParameters)
316 targs.Add (new TypeParameterExpr (t, Location));
318 Report.Debug (128, "GET SCOPE TYPE", this, TypeBuilder, targs,
319 ec.DeclContainer, ec.DeclContainer.GetType (),
320 ec.DeclContainer.Parent.Name);
322 TypeExpr te = new ConstructedType (TypeBuilder, targs, Location);
323 te = te.ResolveAsTypeTerminal (ec, false);
324 if ((te == null) || (te.Type == null))
329 protected override bool DoDefineMembers ()
331 Report.Debug (64, "SCOPE INFO DEFINE MEMBERS", this, GetType (), IsGeneric,
332 Parent.IsGeneric, GenericMethod);
334 foreach (CapturedScope child in CapturedScopes) {
335 if (!child.DefineMembers ())
339 return base.DoDefineMembers ();
342 protected override bool DoResolveMembers ()
344 Report.Debug (64, "SCOPE INFO RESOLVE MEMBERS", this, GetType (), IsGeneric,
345 Parent.IsGeneric, GenericMethod);
347 return base.DoResolveMembers ();
350 public Variable CaptureScope (ScopeInfo child)
352 CheckMembersDefined ();
353 Report.Debug (128, "CAPTURE SCOPE", this, GetType (), child, child.GetType ());
355 throw new InternalErrorException ();
356 CapturedScope captured = (CapturedScope) captured_scopes [child];
357 if (captured == null) {
358 captured = new CapturedScope (this, child);
359 captured_scopes.Add (child, captured);
364 public Variable AddLocal (LocalInfo local)
366 Report.Debug (128, "CAPTURE LOCAL", this, local);
367 Variable var = (Variable) locals [local];
369 var = new CapturedLocal (this, local);
370 locals.Add (local, var);
371 local.IsCaptured = true;
376 public Variable GetCapturedVariable (LocalInfo local)
378 return (Variable) locals [local];
381 public bool HostsParameters {
382 get { return captured_params != null; }
385 public Variable GetCapturedParameter (Parameter par)
387 if (captured_params != null)
388 return (Variable) captured_params [par];
393 public bool IsParameterCaptured (string name)
395 if (captured_params != null)
396 return captured_params [name] != null;
400 public Variable AddParameter (Parameter par, int idx)
402 if (captured_params == null)
403 captured_params = new Hashtable ();
405 Variable var = (Variable) captured_params [par];
407 var = new CapturedParameter (this, par, idx);
408 captured_params.Add (par, var);
409 par.IsCaptured = true;
415 protected string MakeFieldName (string local_name)
417 return "<" + ID + ":" + local_name + ">";
420 protected virtual ScopeInitializer CreateScopeInitializer ()
422 return new ScopeInitializer (this);
425 protected abstract class CapturedVariable : Variable
427 public readonly ScopeInfo Scope;
428 public readonly string Name;
430 public FieldExpr FieldInstance;
431 protected Field field;
433 protected CapturedVariable (ScopeInfo scope, string name)
439 protected CapturedVariable (ScopeInfo scope, string name, Type type)
442 this.field = scope.CaptureVariable (
443 scope.MakeFieldName (name), scope.RootScope.InflateType (type));
447 get { return field; }
450 public override Type Type {
451 get { return Field.MemberType; }
454 public override bool HasInstance {
458 public override bool NeedsTemporary {
462 protected FieldInfo GetField (EmitContext ec)
464 if ((ec.CurrentBlock != null) &&
465 (ec.CurrentBlock.Toplevel != Scope.ScopeBlock.Toplevel))
466 return Field.FieldBuilder;
468 return FieldInstance.FieldInfo;
471 public override void EmitInstance (EmitContext ec)
473 if ((ec.CurrentAnonymousMethod != null) &&
474 (ec.CurrentAnonymousMethod.Scope == Scope)) {
475 ec.ig.Emit (OpCodes.Ldarg_0);
479 Scope.EmitScopeInstance (ec);
482 public override void Emit (EmitContext ec)
484 ec.ig.Emit (OpCodes.Ldfld, GetField (ec));
487 public override void EmitAssign (EmitContext ec)
489 ec.ig.Emit (OpCodes.Stfld, GetField (ec));
492 public override void EmitAddressOf (EmitContext ec)
494 ec.ig.Emit (OpCodes.Ldflda, GetField (ec));
498 protected class CapturedParameter : CapturedVariable {
499 public readonly Parameter Parameter;
500 public readonly int Idx;
502 public CapturedParameter (ScopeInfo scope, Parameter par, int idx)
503 : base (scope, par.Name, par.ParameterType)
505 this.Parameter = par;
509 public override string ToString ()
511 return String.Format ("{0} ({1}:{2}:{3})", GetType (), Field,
512 Parameter.Name, Idx);
516 protected class CapturedLocal : CapturedVariable {
517 public readonly LocalInfo Local;
519 public CapturedLocal (ScopeInfo scope, LocalInfo local)
520 : base (scope, local.Name, local.VariableType)
525 public override string ToString ()
527 return String.Format ("{0} ({1}:{2})", GetType (), Field,
532 protected class CapturedThis : CapturedVariable {
533 public CapturedThis (RootScopeInfo host)
534 : base (host, "<>THIS", host.ParentType)
538 protected class CapturedScope : CapturedVariable {
539 public readonly ScopeInfo ChildScope;
541 public CapturedScope (ScopeInfo root, ScopeInfo child)
542 : base (root, "scope" + child.ID)
544 this.ChildScope = child;
547 public bool DefineMembers ()
549 Type type = ChildScope.IsGeneric ?
550 ChildScope.CurrentType : ChildScope.TypeBuilder;
551 Report.Debug (128, "CAPTURED SCOPE DEFINE MEMBERS", this, Scope,
552 ChildScope, Name, type);
554 throw new InternalErrorException ();
555 field = Scope.CaptureVariable (
556 Scope.MakeFieldName (Name), Scope.InflateType (type));
560 public override string ToString ()
562 return String.Format ("CapturedScope ({1} captured in {0})",
567 static void DoPath (StringBuilder sb, ScopeInfo start)
569 sb.Append ((start.ID).ToString ());
572 public override string ToString ()
574 StringBuilder sb = new StringBuilder ();
580 return sb.ToString ();
583 protected class ScopeInitializer : ExpressionStatement
586 CapturedVariable captured_scope;
587 LocalBuilder scope_instance;
588 ConstructorInfo scope_ctor;
592 public ScopeInitializer (ScopeInfo scope)
595 this.loc = scope.Location;
596 eclass = ExprClass.Value;
599 public ScopeInfo Scope {
600 get { return scope; }
603 public override Expression DoResolve (EmitContext ec)
605 if (scope_ctor != null)
608 Report.Debug (64, "RESOLVE SCOPE INITIALIZER BASE", this, Scope,
609 ec, ec.CurrentBlock);
611 type = Scope.GetScopeType (ec);
613 throw new InternalErrorException ();
615 if (!DoResolveInternal (ec))
616 throw new InternalErrorException ();
621 protected virtual bool DoResolveInternal (EmitContext ec)
623 MethodGroupExpr mg = (MethodGroupExpr) Expression.MemberLookupFinal (
624 ec, ec.ContainerType, type, ".ctor", MemberTypes.Constructor,
625 AllBindingFlags | BindingFlags.DeclaredOnly, loc);
627 throw new InternalErrorException ();
629 scope_ctor = (ConstructorInfo) mg.Methods [0];
631 Report.Debug (128, "RESOLVE THE INIT", this, Scope, Scope.RootScope,
632 Scope.RootScope.GetType ());
634 ScopeInfo host = Scope.RootScope;
635 if ((Scope != host) && (Scope.RootScope is IteratorHost)) {
636 captured_scope = host.GetCapturedScope (Scope);
637 Type root = host.GetScopeType (ec);
638 FieldExpr fe = (FieldExpr) Expression.MemberLookup (
639 type, root, captured_scope.Field.Name, loc);
641 throw new InternalErrorException ();
643 fe.InstanceExpression = this;
644 captured_scope.FieldInstance = fe;
646 Report.Debug (128, "RESOLVE THE INIT #1", this,
649 scope_instance = ec.ig.DeclareLocal (type);
651 foreach (CapturedLocal local in Scope.locals.Values) {
652 FieldExpr fe = (FieldExpr) Expression.MemberLookup (
653 ec.ContainerType, type, local.Field.Name, loc);
654 Report.Debug (64, "RESOLVE SCOPE INITIALIZER #2", this, Scope,
655 Scope, ec, ec.ContainerType, type,
656 local.Field, local.Field.Name, loc, fe);
658 throw new InternalErrorException ();
660 fe.InstanceExpression = this;
661 local.FieldInstance = fe;
664 if (Scope.HostsParameters) {
665 foreach (CapturedParameter cp in Scope.captured_params.Values) {
666 FieldExpr fe = (FieldExpr) Expression.MemberLookup (
667 ec.ContainerType, type, cp.Field.Name, loc);
669 throw new InternalErrorException ();
671 fe.InstanceExpression = this;
672 cp.FieldInstance = fe;
676 foreach (CapturedScope scope in Scope.CapturedScopes) {
677 FieldExpr fe = (FieldExpr) Expression.MemberLookup (
678 ec.ContainerType, type, scope.Field.Name, loc);
679 Report.Debug (64, "RESOLVE SCOPE INITIALIZER #3", this, Scope,
680 scope, ec, ec.ContainerType, type,
681 scope.Field, scope.Field.Name, loc, fe);
683 throw new InternalErrorException ();
685 fe.InstanceExpression = this;
686 scope.FieldInstance = fe;
692 protected virtual void EmitParameterReference (EmitContext ec,
693 CapturedParameter cp)
695 int extra = ec.MethodIsStatic ? 0 : 1;
696 ParameterReference.EmitLdArg (ec.ig, cp.Idx + extra);
702 protected virtual void DoEmit (EmitContext ec)
704 if ((ec.CurrentBlock != null) &&
705 (ec.CurrentBlock.Toplevel != Scope.ScopeBlock.Toplevel)) {
706 ec.ig.Emit (OpCodes.Ldarg_0);
708 if (ec.CurrentAnonymousMethod != null) {
709 ScopeInfo host = ec.CurrentAnonymousMethod.Scope;
710 Variable captured = host.GetCapturedScope (scope);
711 Report.Debug (128, "EMIT SCOPE INSTANCE #2",
712 ec.CurrentAnonymousMethod, host,
714 if (captured != null)
717 } else if (scope_instance != null)
718 ec.ig.Emit (OpCodes.Ldloc, scope_instance);
720 Report.Debug (128, "DO EMIT", this, Scope, ec,
721 scope_instance, captured_scope);
722 captured_scope.EmitInstance (ec);
723 captured_scope.Emit (ec);
727 protected void DoEmitInstance (EmitContext ec)
729 Report.Debug (128, "DO EMIT INSTANCE", this, Scope, ec,
730 scope_instance, captured_scope);
732 if (scope_instance != null)
733 ec.ig.Emit (OpCodes.Ldloc, scope_instance);
735 captured_scope.EmitInstance (ec);
738 protected virtual void EmitScopeConstructor (EmitContext ec)
740 ec.ig.Emit (OpCodes.Newobj, scope_ctor);
743 public override void Emit (EmitContext ec)
746 throw new InternalErrorException (
747 "Scope {0} not initialized yet", scope);
752 public override void EmitStatement (EmitContext ec)
757 DoEmitStatement (ec);
761 protected virtual void DoEmitStatement (EmitContext ec)
763 Report.Debug (128, "EMIT SCOPE INITIALIZER STATEMENT", this, id,
764 Scope, scope_instance, ec);
766 ec.ig.Emit (OpCodes.Nop);
767 ec.ig.Emit (OpCodes.Ldc_I4, id);
768 ec.ig.Emit (OpCodes.Pop);
769 ec.ig.Emit (OpCodes.Nop);
771 if (scope_instance == null)
772 ec.ig.Emit (OpCodes.Ldarg_0);
773 EmitScopeConstructor (ec);
774 if (scope_instance != null)
775 ec.ig.Emit (OpCodes.Stloc, scope_instance);
777 captured_scope.EmitAssign (ec);
779 if (Scope.HostsParameters) {
780 foreach (CapturedParameter cp in Scope.captured_params.Values) {
781 Report.Debug (128, "EMIT SCOPE INIT #6", this,
782 ec, ec.IsStatic, Scope, cp, cp.Field.Name);
784 EmitParameterReference (ec, cp);
785 ec.ig.Emit (OpCodes.Stfld, cp.FieldInstance.FieldInfo);
789 if (Scope is IteratorHost)
792 foreach (CapturedScope scope in Scope.CapturedScopes) {
793 ScopeInfo child = scope.ChildScope;
795 Report.Debug (128, "EMIT SCOPE INIT #5", this, Scope,
796 scope.Scope, scope.ChildScope);
798 ExpressionStatement init = child.GetScopeInitializer (ec);
799 init.EmitStatement (ec);
802 scope.ChildScope.EmitScopeInstance (ec);
803 scope.EmitAssign (ec);
809 public class RootScopeInfo : ScopeInfo
811 public RootScopeInfo (ToplevelBlock toplevel, DeclSpace parent,
812 GenericMethod generic, Location loc)
813 : base (toplevel, parent, generic, loc)
815 scopes = new ArrayList ();
818 TypeExpr parent_type;
819 CapturedVariableField parent_link;
820 CapturedThis this_variable;
821 protected ArrayList scopes;
823 public virtual bool IsIterator {
824 get { return false; }
827 public RootScopeInfo ParentHost {
828 get { return Parent.PartialContainer as RootScopeInfo; }
831 public Type ParentType {
832 get { return parent_type.Type; }
835 public Field ParentLink {
836 get { return parent_link; }
839 protected CapturedThis THIS {
840 get { return this_variable; }
843 public Variable CaptureThis ()
845 if (ParentHost != null)
846 return ParentHost.CaptureThis ();
848 CheckMembersDefined ();
849 if (this_variable == null)
850 this_variable = new CapturedThis (this);
851 return this_variable;
854 public void AddScope (ScopeInfo scope)
860 public void LinkScopes ()
862 Report.Debug (128, "LINK SCOPES", this, linked, scopes);
868 if (ParentHost != null)
869 ParentHost.LinkScopes ();
871 foreach (ScopeInfo si in scopes) {
873 throw new InternalErrorException ();
874 if (si.DefineType () == null)
875 throw new InternalErrorException ();
876 if (!si.ResolveType ())
877 throw new InternalErrorException ();
880 foreach (ScopeInfo si in scopes) {
881 if (!si.ResolveMembers ())
882 throw new InternalErrorException ();
883 if (!si.DefineMembers ())
884 throw new InternalErrorException ();
888 protected override ScopeInitializer CreateScopeInitializer ()
890 return new RootScopeInitializer (this);
893 protected override bool DefineNestedTypes ()
895 if (Parent.IsGeneric) {
896 parent_type = new ConstructedType (
897 Parent.TypeBuilder, Parent.TypeParameters, Location);
898 parent_type = parent_type.ResolveAsTypeTerminal (this, false);
899 if ((parent_type == null) || (parent_type.Type == null))
902 parent_type = new TypeExpression (Parent.TypeBuilder, Location);
905 CompilerGeneratedClass parent = Parent.PartialContainer as CompilerGeneratedClass;
907 parent_link = new CapturedVariableField (this, "<>parent", parent_type);
909 return base.DefineNestedTypes ();
912 protected override bool DoDefineMembers ()
914 ArrayList args = new ArrayList ();
915 if (this is IteratorHost)
916 args.Add (new Parameter (
917 TypeManager.int32_type, "$PC", Parameter.Modifier.NONE,
921 if (Parent is CompilerGeneratedClass)
922 pfield = parent_link;
924 pfield = this_variable != null ? this_variable.Field : null;
926 args.Add (new Parameter (
927 pfield.MemberType, "parent", Parameter.Modifier.NONE,
930 Parameter[] ctor_params = new Parameter [args.Count];
931 args.CopyTo (ctor_params, 0);
932 Constructor ctor = new Constructor (
933 this, MemberName.Name, Modifiers.PUBLIC,
934 new Parameters (ctor_params),
935 new GeneratedBaseInitializer (Location),
937 AddConstructor (ctor);
939 ctor.Block = new ToplevelBlock (null, Location);
940 ctor.Block.AddStatement (new TheCtor (this));
942 return base.DoDefineMembers ();
945 protected virtual void EmitScopeConstructor (EmitContext ec)
947 int pos = (this is IteratorHost) ? 2 : 1;
950 if (Parent is CompilerGeneratedClass)
951 pfield = parent_link;
953 pfield = this_variable != null ? this_variable.Field : null;
955 if (pfield != null) {
956 ec.ig.Emit (OpCodes.Ldarg_0);
957 ec.ig.Emit (OpCodes.Ldarg, pos);
958 ec.ig.Emit (OpCodes.Stfld, pfield.FieldBuilder);
963 protected class TheCtor : Statement
967 public TheCtor (RootScopeInfo host)
972 public override bool Resolve (EmitContext ec)
977 protected override void DoEmit (EmitContext ec)
979 host.EmitScopeConstructor (ec);
983 protected class RootScopeInitializer : ScopeInitializer
987 public RootScopeInitializer (RootScopeInfo host)
993 public RootScopeInfo Host {
997 protected override bool DoResolveInternal (EmitContext ec)
999 Report.Debug (64, "RESOLVE ANONYMOUS METHOD HOST INITIALIZER",
1000 this, Host, Host.ParentType, loc);
1002 if (Host.THIS != null) {
1003 FieldExpr fe = (FieldExpr) Expression.MemberLookup (
1004 ec.ContainerType, type, Host.THIS.Field.Name, loc);
1006 throw new InternalErrorException ();
1008 fe.InstanceExpression = this;
1009 Host.THIS.FieldInstance = fe;
1012 return base.DoResolveInternal (ec);
1015 protected virtual bool IsGetEnumerator {
1016 get { return false; }
1019 protected override void EmitScopeConstructor (EmitContext ec)
1021 if (host.THIS != null) {
1022 ec.ig.Emit (OpCodes.Ldarg_0);
1023 if (IsGetEnumerator)
1024 ec.ig.Emit (OpCodes.Ldfld, host.THIS.Field.FieldBuilder);
1025 else if (host.THIS.Type.IsValueType)
1026 Expression.LoadFromPtr (ec.ig, host.THIS.Type);
1027 } else if (host.ParentLink != null)
1028 ec.ig.Emit (OpCodes.Ldarg_0);
1030 base.EmitScopeConstructor (ec);
1036 public interface IAnonymousContainer
1042 GenericMethod GenericMethod {
1046 RootScopeInfo RootScope {
1055 public interface IAnonymousHost
1058 // Invoked if a yield statement is found in the body
1063 // Invoked if an anonymous method is found in the body
1065 void AddAnonymousMethod (AnonymousMethodExpression anonymous);
1068 public class AnonymousMethodExpression : Expression, IAnonymousContainer, IAnonymousHost
1070 public readonly AnonymousMethodExpression Parent;
1071 public readonly TypeContainer Host;
1072 public Parameters Parameters;
1074 public ToplevelBlock Block;
1075 protected AnonymousMethod anonymous;
1077 protected Block container;
1078 protected readonly GenericMethod generic;
1080 public Block Container {
1081 get { return container; }
1084 public GenericMethod GenericMethod {
1085 get { return generic; }
1088 public AnonymousMethod AnonymousMethod {
1089 get { return anonymous; }
1092 public RootScopeInfo RootScope {
1093 get { return root_scope; }
1096 public AnonymousMethodExpression (AnonymousMethodExpression parent,
1097 GenericMethod generic, TypeContainer host,
1098 Parameters parameters, Block container,
1101 this.Parent = parent;
1102 this.generic = parent != null ? null : generic;
1104 this.Parameters = parameters;
1105 this.container = container;
1108 Report.Debug (64, "NEW ANONYMOUS METHOD EXPRESSION", this, parent, host,
1112 parent.AddAnonymousMethod (this);
1116 RootScopeInfo root_scope;
1118 static int next_index;
1120 void IAnonymousHost.SetYields ()
1122 throw new InvalidOperationException ();
1125 public void AddAnonymousMethod (AnonymousMethodExpression anonymous)
1127 if (children == null)
1128 children = new ArrayList ();
1129 children.Add (anonymous);
1132 public bool CreateAnonymousHelpers ()
1134 Report.Debug (64, "ANONYMOUS METHOD EXPRESSION CREATE ROOT SCOPE",
1135 this, Host, container, loc);
1137 if (container != null)
1138 root_scope = container.Toplevel.CreateRootScope (Host);
1140 if (children != null) {
1141 foreach (AnonymousMethodExpression child in children) {
1142 if (!child.CreateAnonymousHelpers ())
1150 public override string ExprClassName {
1152 return "anonymous method";
1156 void Error_ParameterMismatch (Type t)
1158 Report.Error (1661, loc, "Anonymous method could not be converted to delegate `" +
1159 "{0}' since there is a parameter mismatch",
1160 TypeManager.CSharpName (t));
1163 public virtual bool ImplicitStandardConversionExists (Type delegate_type)
1165 if (Parameters == null)
1168 MethodGroupExpr invoke_mg = Delegate.GetInvokeMethod (
1169 Host.TypeBuilder, delegate_type, loc);
1170 MethodInfo invoke_mb = (MethodInfo) invoke_mg.Methods [0];
1171 ParameterData invoke_pd = TypeManager.GetParameterData (invoke_mb);
1173 if (Parameters.Count != invoke_pd.Count)
1176 for (int i = 0; i < Parameters.Count; ++i) {
1177 if (invoke_pd.ParameterType (i) != Parameters.ParameterType (i))
1183 protected Expression CompatibleChecks (EmitContext ec, Type delegate_type)
1185 if (!ec.IsAnonymousMethodAllowed) {
1186 Report.Error (1706, loc,
1187 "Anonymous methods are not allowed in the " +
1188 "attribute declaration");
1192 if (!TypeManager.IsDelegateType (delegate_type)){
1193 Report.Error (1660, loc,
1194 "Cannot convert anonymous method block to type " +
1195 "`{0}' because it is not a delegate type",
1196 TypeManager.CSharpName (delegate_type));
1202 protected bool VerifyExplicitParameterCompatibility (Type delegate_type, ParameterData invoke_pd, bool showErrors)
1204 if (Parameters.Count != invoke_pd.Count) {
1208 Report.SymbolRelatedToPreviousError (delegate_type);
1209 Report.Error (1593, loc, "Delegate `{0}' does not take `{1}' arguments",
1210 TypeManager.CSharpName (delegate_type), Parameters.Count.ToString ());
1211 Error_ParameterMismatch (delegate_type);
1215 for (int i = 0; i < Parameters.Count; ++i) {
1216 Parameter.Modifier p_mod = invoke_pd.ParameterModifier (i);
1217 if (Parameters.ParameterModifier (i) != p_mod && p_mod != Parameter.Modifier.PARAMS) {
1221 if (p_mod == Parameter.Modifier.NONE)
1222 Report.Error (1677, loc, "Parameter `{0}' should not be declared with the `{1}' keyword",
1223 (i + 1).ToString (), Parameter.GetModifierSignature (Parameters.ParameterModifier (i)));
1225 Report.Error (1676, loc, "Parameter `{0}' must be declared with the `{1}' keyword",
1226 (i+1).ToString (), Parameter.GetModifierSignature (p_mod));
1227 Error_ParameterMismatch (delegate_type);
1231 // We assume that generic parameters are always inflated
1232 if (TypeManager.IsGenericParameter (invoke_pd.Types[i]))
1235 if (invoke_pd.ParameterType (i) != Parameters.ParameterType (i)) {
1239 Report.Error (1678, loc, "Parameter `{0}' is declared as type `{1}' but should be `{2}'",
1241 TypeManager.CSharpName (Parameters.ParameterType (i)),
1242 TypeManager.CSharpName (invoke_pd.ParameterType (i)));
1243 Error_ParameterMismatch (delegate_type);
1251 // TODO: Merge with lambda DoCompatibleTest
1252 // TODO: Need to sort out error reporting
1253 public Expression InferTypeArguments (EmitContext ec, Type delegateType)
1255 if (anonymous != null)
1256 return anonymous.AnonymousDelegate;
1258 if (!delegateType.ContainsGenericParameters)
1259 throw new InternalErrorException ("No inference required");
1261 // It looks like we cannot generate arguments during type inference
1262 if (Parameters == null)
1265 delegateType = delegateType.GetGenericTypeDefinition ();
1267 MethodGroupExpr invoke_mg = Delegate.GetInvokeMethod (
1268 ec.ContainerType, delegateType, loc);
1269 MethodInfo invoke_mb = (MethodInfo) invoke_mg.Methods [0];
1270 ParameterData invoke_pd = TypeManager.GetParameterData (invoke_mb);
1272 if (!VerifyExplicitParameterCompatibility (delegateType, invoke_pd, false))
1275 Type[] g_arguments = delegateType.GetGenericArguments ();
1276 Type[] inferred_arguments = new Type [g_arguments.Length];
1277 g_arguments.CopyTo (inferred_arguments, 0);
1279 for (int i = 0; i < invoke_pd.Count; ++i) {
1280 if (!invoke_pd.Types[i].IsGenericParameter)
1283 inferred_arguments [invoke_pd.Types[i].GenericParameterPosition] = Parameters.Types[i];
1286 int return_type_pos = -1;
1287 if (TypeManager.IsGenericParameter (invoke_mb.ReturnType)) {
1288 ec.InferReturnType = true;
1289 return_type_pos = invoke_mb.ReturnType.GenericParameterPosition;
1292 anonymous = new AnonymousMethod (
1293 Parent != null ? Parent.AnonymousMethod : null, RootScope, Host,
1294 GenericMethod, Parameters, Container, Block, invoke_mb.ReturnType,
1297 if (!anonymous.Resolve (ec))
1300 if (return_type_pos != -1) {
1301 inferred_arguments [return_type_pos] = anonymous.ReturnType;
1304 anonymous.AnonymousDelegate.Type = delegateType.GetGenericTypeDefinition ().MakeGenericType (inferred_arguments);
1305 anonymous.DelegateType = anonymous.AnonymousDelegate.Type;
1307 return anonymous.AnonymousDelegate;
1312 // Returns true if this anonymous method can be implicitly
1313 // converted to the delegate type `delegate_type'
1315 public virtual Expression Compatible (EmitContext ec, Type delegate_type)
1317 if (anonymous != null)
1318 return anonymous.AnonymousDelegate;
1320 if (CompatibleChecks (ec, delegate_type) == null)
1324 // At this point its the first time we know the return type that is
1325 // needed for the anonymous method. We create the method here.
1328 MethodGroupExpr invoke_mg = Delegate.GetInvokeMethod (
1329 ec.ContainerType, delegate_type, loc);
1330 MethodInfo invoke_mb = (MethodInfo) invoke_mg.Methods [0];
1331 ParameterData invoke_pd = TypeManager.GetParameterData (invoke_mb);
1333 Parameters parameters;
1334 if (Parameters == null) {
1336 // We provide a set of inaccessible parameters
1338 Parameter [] fixedpars = new Parameter [invoke_pd.Count];
1340 for (int i = 0; i < invoke_pd.Count; i++) {
1341 Parameter.Modifier i_mod = invoke_pd.ParameterModifier (i);
1342 if ((i_mod & Parameter.Modifier.OUTMASK) != 0) {
1343 Report.Error (1688, loc, "Cannot convert anonymous " +
1344 "method block without a parameter list " +
1345 "to delegate type `{0}' because it has " +
1346 "one or more `out' parameters.",
1347 TypeManager.CSharpName (delegate_type));
1350 fixedpars [i] = new Parameter (
1351 invoke_pd.ParameterType (i), "+" + (++next_index),
1352 invoke_pd.ParameterModifier (i), null, loc);
1355 parameters = new Parameters (fixedpars);
1356 if (!parameters.Resolve (ec))
1359 if (!VerifyExplicitParameterCompatibility (delegate_type, invoke_pd, true))
1362 parameters = Parameters;
1366 // Second: the return type of the delegate must be compatible with
1367 // the anonymous type. Instead of doing a pass to examine the block
1368 // we satisfy the rule by setting the return type on the EmitContext
1369 // to be the delegate type return type.
1372 //MethodBuilder builder = method_data.MethodBuilder;
1373 //ILGenerator ig = builder.GetILGenerator ();
1375 Report.Debug (64, "COMPATIBLE", this, Parent, GenericMethod, Host,
1376 Container, Block, invoke_mb.ReturnType, delegate_type,
1377 TypeManager.IsGenericType (delegate_type), loc);
1379 anonymous = new AnonymousMethod (
1380 Parent != null ? Parent.AnonymousMethod : null, RootScope, Host,
1381 GenericMethod, parameters, Container, Block, invoke_mb.ReturnType,
1382 delegate_type, loc);
1384 if (!anonymous.Resolve (ec))
1387 return anonymous.AnonymousDelegate;
1390 public override Expression DoResolve (EmitContext ec)
1393 // Set class type, set type
1396 eclass = ExprClass.Value;
1399 // This hack means `The type is not accessible
1400 // anywhere', we depend on special conversion
1403 type = TypeManager.anonymous_method_type;
1405 if ((Parameters != null) && !Parameters.Resolve (ec))
1411 public override void Emit (EmitContext ec)
1413 // nothing, as we only exist to not do anything.
1416 public bool IsIterator {
1417 get { return false; }
1420 protected override void CloneTo (CloneContext clonectx, Expression t)
1422 AnonymousMethodExpression target = (AnonymousMethodExpression) t;
1424 target.Block = (ToplevelBlock) clonectx.LookupBlock (Block);
1425 target.container = clonectx.LookupBlock (Block);
1426 target.Parameters = Parameters.Clone ();
1430 public abstract class AnonymousContainer : IAnonymousContainer
1432 public readonly Location Location;
1434 public Parameters Parameters;
1437 // The block that makes up the body for the anonymous mehtod
1439 public readonly ToplevelBlock Block;
1441 public readonly int ModFlags;
1442 public Type ReturnType;
1443 public readonly DeclSpace Host;
1446 // The implicit method we create
1448 protected Method method;
1449 protected EmitContext aec;
1451 // The emit context for the anonymous method
1452 protected bool unreachable;
1453 protected readonly Block container;
1454 protected readonly GenericMethod generic;
1457 // Points to our container anonymous method if its present
1459 public readonly AnonymousContainer ContainerAnonymousMethod;
1461 protected AnonymousContainer (AnonymousContainer parent, DeclSpace host,
1462 GenericMethod generic, Parameters parameters,
1463 Block container, ToplevelBlock block,
1464 Type return_type, int mod, Location loc)
1466 this.ContainerAnonymousMethod = parent;
1467 this.ReturnType = return_type;
1468 this.ModFlags = mod | Modifiers.COMPILER_GENERATED;
1471 this.container = container;
1472 this.generic = parent != null ? null : generic;
1473 this.Parameters = parameters;
1475 this.Location = loc;
1477 block.AnonymousContainer = this;
1480 public Method Method {
1481 get { return method; }
1484 public abstract RootScopeInfo RootScope {
1488 public abstract ScopeInfo Scope {
1492 public abstract string GetSignatureForError ();
1494 public virtual bool ResolveNoDefine (EmitContext ec)
1496 Report.Debug (64, "RESOLVE ANONYMOUS METHOD", this, Location, ec,
1497 RootScope, Parameters, ec.IsStatic);
1499 if (ReturnType != null) {
1500 TypeExpr return_type_expr;
1501 if (RootScope != null)
1502 return_type_expr = RootScope.InflateType (ReturnType);
1504 return_type_expr = new TypeExpression (ReturnType, Location);
1505 return_type_expr = return_type_expr.ResolveAsTypeTerminal (ec, false);
1506 if ((return_type_expr == null) || (return_type_expr.Type == null))
1508 ReturnType = return_type_expr.Type;
1511 if (RootScope != null)
1512 Parameters = RootScope.InflateParameters (Parameters);
1514 aec = new EmitContext (
1515 ec.ResolveContext, ec.TypeContainer,
1516 RootScope != null ? RootScope : Host, Location, null, ReturnType,
1517 /* REVIEW */ (ec.InIterator ? Modifiers.METHOD_YIELDS : 0) |
1518 (ec.InUnsafe ? Modifiers.UNSAFE : 0), /* No constructor */ false);
1520 aec.CurrentAnonymousMethod = this;
1521 aec.IsFieldInitializer = ec.IsFieldInitializer;
1522 aec.IsStatic = ec.IsStatic;
1523 aec.InferReturnType = ec.InferReturnType;
1525 Report.Debug (64, "RESOLVE ANONYMOUS METHOD #1", this, Location, ec, aec,
1526 RootScope, Parameters, Block);
1529 if (!aec.ResolveTopBlock (ec, Block, Parameters, null, out unreachable))
1535 public virtual bool Resolve (EmitContext ec)
1537 if (!ResolveNoDefine (ec))
1540 Report.Debug (64, "RESOLVE ANONYMOUS METHOD #3", this, ec, aec, Block);
1542 if (aec.InferReturnType)
1543 ReturnType = aec.ReturnType;
1545 method = DoCreateMethodHost (ec);
1550 if (!method.ResolveMembers ())
1552 return method.Define ();
1555 protected abstract Method DoCreateMethodHost (EmitContext ec);
1557 public Block Container {
1558 get { return container; }
1561 public GenericMethod GenericMethod {
1562 get { return generic; }
1565 public abstract bool IsIterator {
1569 protected class AnonymousMethodMethod : Method
1571 public readonly AnonymousContainer AnonymousMethod;
1572 public readonly ScopeInfo Scope;
1574 public AnonymousMethodMethod (AnonymousContainer am, ScopeInfo scope,
1575 GenericMethod generic, TypeExpr return_type,
1576 int mod, MemberName name, Parameters parameters)
1577 : base (scope != null ? scope : am.Host,
1578 generic, return_type, mod | Modifiers.COMPILER_GENERATED, false, name, parameters, null)
1580 this.AnonymousMethod = am;
1583 if (scope != null) {
1584 scope.CheckMembersDefined ();
1585 scope.AddMethod (this);
1587 ModFlags |= Modifiers.STATIC;
1588 am.Host.PartialContainer.AddMethod (this);
1593 public override EmitContext CreateEmitContext (DeclSpace tc, ILGenerator ig)
1595 EmitContext aec = AnonymousMethod.aec;
1597 aec.MethodIsStatic = Scope == null;
1603 public class AnonymousMethod : AnonymousContainer
1605 public Type DelegateType;
1608 // The value return by the Compatible call, this ensure that
1609 // the code works even if invoked more than once (Resolve called
1610 // more than once, due to the way Convert.ImplicitConversion works
1612 Expression anonymous_delegate;
1613 RootScopeInfo root_scope;
1616 public AnonymousMethod (AnonymousMethod parent, RootScopeInfo root_scope,
1617 DeclSpace host, GenericMethod generic,
1618 Parameters parameters, Block container,
1619 ToplevelBlock block, Type return_type, Type delegate_type,
1621 : base (parent, host, generic, parameters, container, block,
1622 return_type, 0, loc)
1624 this.DelegateType = delegate_type;
1625 this.root_scope = root_scope;
1628 public override RootScopeInfo RootScope {
1629 get { return root_scope; }
1632 public override ScopeInfo Scope {
1633 get { return scope; }
1636 public override bool IsIterator {
1637 get { return false; }
1640 public Expression AnonymousDelegate {
1641 get { return anonymous_delegate; }
1644 public override string GetSignatureForError ()
1646 return TypeManager.CSharpName (DelegateType);
1650 // Creates the host for the anonymous method
1652 protected override Method DoCreateMethodHost (EmitContext ec)
1654 string name = CompilerGeneratedClass.MakeName ("AnonymousMethod");
1655 MemberName member_name;
1657 Report.Debug (128, "CREATE METHOD HOST #0", RootScope);
1662 Report.Debug (128, "CREATE METHOD HOST #1", this, Block, Block.ScopeInfo,
1663 RootScope, Location);
1665 for (b = Block.Parent; b != null; b = b.Parent) {
1666 Report.Debug (128, "CREATE METHOD HOST #2", this, Block,
1668 if (b.ScopeInfo != null) {
1669 scope = b.ScopeInfo;
1675 scope.CheckMembersDefined ();
1677 ArrayList scopes = new ArrayList ();
1679 for (b = b.Parent; b != null; b = b.Parent) {
1680 if (b.ScopeInfo != null)
1681 scopes.Add (b.ScopeInfo);
1685 Report.Debug (128, "CREATE METHOD HOST #1", this, scope, scopes);
1687 foreach (ScopeInfo si in scopes)
1688 scope.CaptureScope (si);
1690 Report.Debug (128, "CREATE METHOD HOST", this, Block, container,
1691 RootScope, scope, scopes, Location,
1692 ContainerAnonymousMethod);
1694 GenericMethod generic_method = null;
1696 if (TypeManager.IsGenericType (DelegateType)) {
1697 TypeArguments args = new TypeArguments (Location);
1699 Type dt = DelegateType.GetGenericTypeDefinition ();
1701 Type[] tparam = TypeManager.GetTypeArguments (dt);
1702 for (int i = 0; i < tparam.Length; i++)
1703 args.Add (new SimpleName (tparam [i].Name, Location));
1705 member_name = new MemberName (name, args, Location);
1707 Report.Debug (128, "CREATE METHOD HOST #5", this, DelegateType,
1708 TypeManager.GetTypeArguments (DelegateType),
1711 generic_method = new GenericMethod (
1712 Host.NamespaceEntry, scope, member_name,
1713 new TypeExpression (ReturnType, Location), Parameters);
1715 generic_method.SetParameterInfo (null);
1718 member_name = new MemberName (name, Location);
1720 return new AnonymousMethodMethod (
1721 this, scope, generic_method, new TypeExpression (ReturnType, Location),
1722 Modifiers.INTERNAL, member_name, Parameters);
1725 bool ResolveAnonymousDelegate (EmitContext ec)
1727 // If we are inferring the return type, set it to the discovered value.
1728 if (DelegateType == null){
1729 DelegateType = aec.ReturnType;
1731 // The special value pointing to our internal type means it failed.
1732 if (DelegateType == typeof (AnonymousDelegate))
1736 anonymous_delegate = new AnonymousDelegate (
1737 this, DelegateType, Location).Resolve (ec);
1738 if (anonymous_delegate == null)
1743 public override bool Resolve (EmitContext ec)
1745 if (!base.Resolve (ec))
1748 return ResolveAnonymousDelegate (ec);
1751 public override bool ResolveNoDefine (EmitContext ec)
1753 if (!base.ResolveNoDefine (ec))
1756 return ResolveAnonymousDelegate (ec);
1759 public MethodInfo GetMethodBuilder (EmitContext ec)
1761 MethodInfo builder = method.MethodBuilder;
1762 if ((Scope != null) && Scope.IsGeneric) {
1763 Type scope_type = Scope.GetScopeType (ec);
1764 if (scope_type == null)
1765 throw new InternalErrorException ();
1767 MethodGroupExpr mg = (MethodGroupExpr) Expression.MemberLookup (
1768 ec.ContainerType, scope_type, builder.Name, Location);
1771 throw new InternalErrorException ();
1772 builder = (MethodInfo) mg.Methods [0];
1776 if (!DelegateType.IsGenericType)
1779 Type[] targs = TypeManager.GetTypeArguments (DelegateType);
1780 return builder.MakeGenericMethod (targs);
1786 public static void Error_AddressOfCapturedVar (string name, Location loc)
1788 Report.Error (1686, loc,
1789 "Local variable `{0}' or its members cannot have their " +
1790 "address taken and be used inside an anonymous method block",
1796 // This will emit the code for the delegate, as well delegate creation on the host
1798 public class AnonymousDelegate : DelegateCreation {
1802 // if target_type is null, this means that we do not know the type
1803 // for this delegate, and we want to infer it from the various
1804 // returns (implicit and explicit) from the body of this anonymous
1807 // for example, the lambda: x => 1
1809 public AnonymousDelegate (AnonymousMethod am, Type target_type, Location l)
1816 public override Expression DoResolve (EmitContext ec)
1818 eclass = ExprClass.Value;
1821 // If we are inferencing
1824 type = ec.ReturnType;
1826 // No type was infered
1834 public override void Emit (EmitContext ec)
1836 //ec.ig.Emit (OpCodes.Ldstr, "EMIT ANONYMOUS DELEGATE");
1837 //ec.ig.Emit (OpCodes.Pop);
1840 // Now emit the delegate creation.
1842 if ((am.Method.ModFlags & Modifiers.STATIC) == 0) {
1843 Report.Debug (128, "EMIT ANONYMOUS DELEGATE", this, am, am.Scope, loc);
1844 delegate_instance_expression = am.Scope.GetScopeInitializer (ec);
1846 if (delegate_instance_expression == null)
1847 throw new InternalErrorException ();
1850 Expression ml = Expression.MemberLookup (
1851 ec.ContainerType, type, ".ctor", MemberTypes.Constructor,
1852 BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
1855 constructor_method = ((MethodGroupExpr) ml).Methods [0];
1857 if (type.IsGenericType)
1858 constructor_method = TypeBuilder.GetConstructor (type, (ConstructorInfo)constructor_method);
1861 delegate_method = am.GetMethodBuilder (ec);
1864 //ec.ig.Emit (OpCodes.Ldstr, "EMIT ANONYMOUS DELEGATE DONE");
1865 //ec.ig.Emit (OpCodes.Pop);
1867 Report.Debug (128, "EMIT ANONYMOUS DELEGATE DONE", this, am, am.Scope, loc);
1871 public class AnonymousClass : CompilerGeneratedClass
1873 public AnonymousClass (TypeContainer parent, Location loc)
1874 : base (parent, null, 0, loc)