Wed Feb 24 15:47:16 CET 2010 Paolo Molaro <lupus@ximian.com>
[mono.git] / mcs / class / corlib / System.Reflection / MonoGenericClass.cs
1 //
2 // System.Reflection.MonoGenericClass
3 //
4 // Sean MacIsaac (macisaac@ximian.com)
5 // Paolo Molaro (lupus@ximian.com)
6 // Patrik Torstensson (patrik.torstensson@labs2.com)
7 //
8 // (C) 2001 Ximian, Inc.
9 //
10
11 //
12 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33
34 using System.Reflection;
35 using System.Reflection.Emit;
36 using System.Collections;
37 using System.Runtime.CompilerServices;
38 using System.Globalization;
39 using System.Runtime.Serialization;
40 using System.Text;
41
42 namespace System.Reflection
43 {
44         /*
45          * MonoGenericClass represents an instantiation of a generic TypeBuilder. MS
46          * calls this class TypeBuilderInstantiation (a much better name). MS returns 
47          * NotImplementedException for many of the methods but we can't do that as gmcs
48          * depends on them.
49          */
50         internal class MonoGenericClass : Type
51         {
52                 #region Keep in sync with object-internals.h
53 #pragma warning disable 649
54                 internal Type generic_type;
55                 Type[] type_arguments;
56                 bool initialized;
57 #pragma warning restore 649
58                 #endregion
59
60                 Hashtable fields, ctors, methods;
61                 int event_count;
62                 int is_compiler_context;
63
64                 internal MonoGenericClass ()
65                 {
66                         // this should not be used
67                         throw new InvalidOperationException ();
68                 }
69
70                 internal MonoGenericClass (Type tb, Type[] args)
71                 {
72                         this.generic_type = tb;
73                         this.type_arguments = args;
74                         register_with_runtime (this); /*Temporary hack while*/
75                 }
76
77
78                 internal override bool IsCompilerContext {
79                         get {
80                                 if (is_compiler_context == 0) {
81                                         bool is_cc = generic_type.IsCompilerContext;
82                                         foreach (Type t in type_arguments)
83                                                 is_cc |= t.IsCompilerContext;
84                                         is_compiler_context = is_cc ? 1 : -1;
85                                 }
86                                 return is_compiler_context == 1;
87                         }
88                 }
89
90                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
91                 extern void initialize (MethodInfo[] methods, ConstructorInfo[] ctors, FieldInfo[] fields, PropertyInfo[] properties, EventInfo[] events);
92
93                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
94                 internal static extern void register_with_runtime (Type type);
95
96                 EventInfo[] GetEventsFromGTD (BindingFlags flags) {
97                         TypeBuilder tb = generic_type as TypeBuilder;
98                         if (tb == null)
99                                 return generic_type.GetEvents (flags);
100
101                         return tb.GetEvents_internal (flags);
102                 }
103
104                 ConstructorInfo[] GetConstructorsFromGTD (BindingFlags flags)
105                 {
106                         TypeBuilder tb = generic_type as TypeBuilder;
107                         if (tb == null)
108                                 return generic_type.GetConstructors (flags);
109
110                         return tb.GetConstructorsInternal (flags);
111                 }
112
113                 /*
114                 MethodInfo[] GetMethodsFromGTD (BindingFlags bf)
115                 {
116                         TypeBuilder tb = generic_type as TypeBuilder;
117                         if (tb == null)
118                                 return generic_type.GetMethods (bf);
119
120                         MethodInfo[] res = new MethodInfo [tb.num_methods];
121                         if (tb.num_methods > 0)
122                                 Array.Copy (tb.methods, res, tb.num_methods);
123
124                         return res;
125                 }
126                 */
127
128                 FieldInfo[] GetFieldsFromGTD (BindingFlags bf)
129                 {
130                         TypeBuilder tb = generic_type as TypeBuilder;
131                         if (tb == null)
132                                 return generic_type.GetFields (bf);
133
134                         FieldInfo[] res = new FieldInfo [tb.num_fields];
135                         if (tb.num_fields > 0)
136                                 Array.Copy (tb.fields, res, tb.num_fields);
137
138                         return res;
139                 }
140
141                 /*@hint might not be honored so it required aditional filtering
142                 TODO move filtering into here for the TypeBuilder case and remove the hint ugliness 
143                 */
144                 MethodInfo[] GetMethodsFromGTDWithHint (BindingFlags hint)
145                 {
146                         TypeBuilder tb = generic_type as TypeBuilder;
147                         if (tb == null)
148                                 return generic_type.GetMethods (hint);
149
150                         if (tb.num_methods == 0)
151                                 return new MethodInfo [0];
152                         MethodInfo[] res = new MethodInfo [tb.num_methods];
153                         Array.Copy (tb.methods, 0, res, 0, tb.num_methods);
154                         return res;
155                 }
156
157                 /*@hint might not be honored so it required aditional filtering
158                 TODO move filtering into here for the TypeBuilder case and remove the hint ugliness 
159                 */
160                 ConstructorInfo[] GetConstructorsFromGTDWithHint (BindingFlags hint)
161                 {
162                         TypeBuilder tb = generic_type as TypeBuilder;
163                         if (tb == null)
164                                 return generic_type.GetConstructors (hint);
165
166                         if (tb.ctors == null)
167                                 return new ConstructorInfo [0];
168                         ConstructorInfo[] res = new ConstructorInfo [tb.ctors.Length];
169                         tb.ctors.CopyTo (res, 0);
170                         return res;
171                 }
172
173                 static Type PeelType (Type t) {
174                         if (t.HasElementType)
175                                 return PeelType (t.GetElementType ());
176                         if (t.IsGenericType && !t.IsGenericParameter)
177                                 return t.GetGenericTypeDefinition ();
178                         return t;
179                 }
180
181                 static PropertyInfo[] GetPropertiesInternal (Type type, BindingFlags bf)
182                 {
183                         TypeBuilder tb = type as TypeBuilder;
184                         if (tb != null)
185                                 return tb.properties;
186                         return type.GetProperties (bf); 
187                 }
188
189                 Type[] GetInterfacesFromGTD ()
190                 {
191                         TypeBuilder tb = generic_type as TypeBuilder;
192                         if (tb != null)
193                                 return tb.interfaces;
194                         return generic_type.GetInterfaces ();   
195                 }
196
197                 internal bool IsCreated {
198                         get {
199                                 TypeBuilder tb = generic_type as TypeBuilder;
200                                 return tb != null ? tb.is_created : true;
201                         }
202                 }
203
204                 private const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic |
205                 BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
206
207                 void initialize ()
208                 {
209                         if (initialized)
210                                 return;
211
212                         MonoGenericClass parent = GetParentType () as MonoGenericClass;
213                         if (parent != null)
214                                 parent.initialize ();
215                         EventInfo[] events = GetEventsFromGTD (flags);
216                         event_count = events.Length;
217                                 
218                         initialize (generic_type.GetMethods (flags),
219                                                 GetConstructorsFromGTD (flags),
220                                                 generic_type.GetFields (flags),
221                                                 generic_type.GetProperties (flags),
222                                                 events);
223
224                         initialized = true;
225                 }
226
227                 Type GetParentType ()
228                 {
229                         return InflateType (generic_type.BaseType);             
230                 }
231
232                 internal Type InflateType (Type type)
233                 {
234                         return InflateType (type, type_arguments, null);
235                 }
236
237                 internal Type InflateType (Type type, Type[] method_args)
238                 {
239                         return InflateType (type, type_arguments, method_args);
240                 }
241
242                 internal static Type InflateType (Type type, Type[] type_args, Type[] method_args)
243                 {
244                         if (type == null)
245                                 return null;
246                         if (!type.IsGenericParameter && !type.ContainsGenericParameters)
247                                 return type;
248                         if (type.IsGenericParameter) {
249                                 if (type.DeclaringMethod == null)
250                                         return type_args == null ? type : type_args [type.GenericParameterPosition];
251                                 return method_args == null ? type : method_args [type.GenericParameterPosition];
252                         }
253                         if (type.IsPointer)
254                                 return InflateType (type.GetElementType (), type_args, method_args).MakePointerType ();
255                         if (type.IsByRef)
256                                 return InflateType (type.GetElementType (), type_args, method_args).MakeByRefType ();
257                         if (type.IsArray) {
258                                 if (type.GetArrayRank () > 1)
259                                         return InflateType (type.GetElementType (), type_args, method_args).MakeArrayType (type.GetArrayRank ());
260 #if BOOTSTRAP_NET_2_0
261                                 if (type.ToString ().EndsWith ("[*]"))
262 #else
263                                 if (type.ToString ().EndsWith ("[*]", StringComparison.Ordinal)) /*FIXME, the reflection API doesn't offer a way around this*/
264 #endif
265                                         return InflateType (type.GetElementType (), type_args, method_args).MakeArrayType (1);
266                                 return InflateType (type.GetElementType (), type_args, method_args).MakeArrayType ();
267                         }
268
269                         Type[] args = type.GetGenericArguments ();
270                         for (int i = 0; i < args.Length; ++i)
271                                 args [i] = InflateType (args [i], type_args, method_args);
272
273                         Type gtd = type.IsGenericTypeDefinition ? type : type.GetGenericTypeDefinition ();
274                         return gtd.MakeGenericType (args);
275                 }
276                 
277                 public override Type BaseType {
278                         get {
279                                 Type parent = GetParentType ();
280                                 return parent != null ? parent : generic_type.BaseType;
281                         }
282                 }
283
284                 Type[] GetInterfacesInternal ()
285                 {
286                         Type[] ifaces = GetInterfacesFromGTD ();
287                         if (ifaces == null)
288                                 return new Type [0];
289                         Type[] res = new Type [ifaces.Length];
290                         for (int i = 0; i < res.Length; ++i)
291                                 res [i] = InflateType (ifaces [i]);
292                         return res;
293                 }
294
295                 public override Type[] GetInterfaces ()
296                 {
297                         if (!IsCompilerContext) {
298                                 Console.WriteLine ("--FAIL {0}", this);
299                                 Console.WriteLine ("\tgt {0}/{1}/{2}", generic_type, generic_type.IsCompilerContext, generic_type.GetType ());
300                                 
301                                 foreach (Type t in type_arguments)
302                                         Console.WriteLine ("\targ {0}/{1}/{2}", t, t.IsCompilerContext, t.GetType ());
303                                 
304                                 throw new NotSupportedException ();
305                         }
306                         return GetInterfacesInternal ();
307                 }
308
309                 protected override bool IsValueTypeImpl ()
310                 {
311                         return generic_type.IsValueType;
312                 }
313
314                 internal override MethodInfo GetMethod (MethodInfo fromNoninstanciated)
315                 {
316                         initialize ();
317
318                         if (methods == null)
319                                 methods = new Hashtable ();
320                         if (!methods.ContainsKey (fromNoninstanciated))
321                                 methods [fromNoninstanciated] = new MethodOnTypeBuilderInst (this, fromNoninstanciated);
322                         return (MethodInfo)methods [fromNoninstanciated];
323                 }
324
325                 internal override ConstructorInfo GetConstructor (ConstructorInfo fromNoninstanciated)
326                 {
327                         initialize ();
328
329                         if (ctors == null)
330                                 ctors = new Hashtable ();
331                         if (!ctors.ContainsKey (fromNoninstanciated))
332                                 ctors [fromNoninstanciated] = new ConstructorOnTypeBuilderInst (this, fromNoninstanciated);
333                         return (ConstructorInfo)ctors [fromNoninstanciated];
334                 }
335
336                 internal override FieldInfo GetField (FieldInfo fromNoninstanciated)
337                 {
338                         initialize ();
339                         if (fields == null)
340                                 fields = new Hashtable ();
341                         if (!fields.ContainsKey (fromNoninstanciated))
342                                 fields [fromNoninstanciated] = new FieldOnTypeBuilderInst (this, fromNoninstanciated);
343                         return (FieldInfo)fields [fromNoninstanciated];
344                 }
345                 
346                 public override MethodInfo[] GetMethods (BindingFlags bf)
347                 {
348                         if (!IsCompilerContext)
349                                 throw new NotSupportedException ();
350
351                         ArrayList l = new ArrayList ();
352
353                         //
354                         // Walk up our class hierarchy and retrieve methods from our
355                         // parent classes.
356                         //
357                         if (!(generic_type is TypeBuilder)) {
358                                 foreach (var method in generic_type.GetMethods (bf)) {
359                                         var m = method;
360                                         if (m.DeclaringType.IsGenericTypeDefinition)
361                                                 m = TypeBuilder.GetMethod (this, m);
362                                         l.Add (m);
363                                 }
364                         } else {
365                                 Type current_type = this;
366                                 do {
367                                         MonoGenericClass gi = current_type as MonoGenericClass;
368                                         if (gi != null)
369                                                 l.AddRange (gi.GetMethodsInternal (bf, this));
370                                         else if (current_type is TypeBuilder)
371                                                 l.AddRange (current_type.GetMethods (bf));
372                                         else {
373                                                 // If we encounter a `MonoType', its
374                                                 // GetMethodsByName() will return all the methods
375                                                 // from its parent type(s), so we can stop here.
376                                                 MonoType mt = (MonoType) current_type;
377                                                 l.AddRange (mt.GetMethodsByName (null, bf, false, this));
378                                                 break;
379                                         }
380
381                                         if ((bf & BindingFlags.DeclaredOnly) != 0)
382                                                 break;
383                                         current_type = current_type.BaseType;
384                                 } while (current_type != null);
385                         }
386
387                         MethodInfo[] result = new MethodInfo [l.Count];
388                         l.CopyTo (result);
389                         return result;
390                 }
391
392                 MethodInfo[] GetMethodsInternal (BindingFlags bf, MonoGenericClass reftype)
393                 {
394                         if (reftype != this)
395                                 bf |= BindingFlags.DeclaredOnly; /*To avoid duplicates*/
396
397                         MethodInfo[] methods = GetMethodsFromGTDWithHint (bf);
398                         if (methods.Length == 0)
399                                 return new MethodInfo [0];
400
401                         ArrayList l = new ArrayList ();
402                         bool match;
403                         MethodAttributes mattrs;
404
405                         initialize ();
406
407                         for (int i = 0; i < methods.Length; ++i) {
408                                 MethodInfo c = methods [i];
409
410                                 match = false;
411                                 mattrs = c.Attributes;
412                                 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
413                                         if ((bf & BindingFlags.Public) != 0)
414                                                 match = true;
415                                 } else {
416                                         if ((bf & BindingFlags.NonPublic) != 0)
417                                                 match = true;
418                                 }
419                                 if (!match)
420                                         continue;
421                                 match = false;
422                                 if ((mattrs & MethodAttributes.Static) != 0) {
423                                         if ((bf & BindingFlags.Static) != 0)
424                                                 match = true;
425                                 } else {
426                                         if ((bf & BindingFlags.Instance) != 0)
427                                                 match = true;
428                                 }
429                                 if (!match)
430                                         continue;
431                                 if (c.DeclaringType.IsGenericTypeDefinition)
432                                         c = TypeBuilder.GetMethod (this, c);
433                                 l.Add (c);
434                         }
435
436                         MethodInfo[] result = new MethodInfo [l.Count];
437                         l.CopyTo (result);
438                         return result;
439                 }
440
441                 public override ConstructorInfo[] GetConstructors (BindingFlags bf)
442                 {
443                         if (!IsCompilerContext)
444                                 throw new NotSupportedException ();
445
446                         ArrayList l = new ArrayList ();
447
448                         Type current_type = this;
449                         do {
450                                 MonoGenericClass gi = current_type as MonoGenericClass;
451                                 if (gi != null)
452                                         l.AddRange (gi.GetConstructorsInternal (bf, this));
453                                 else if (current_type is TypeBuilder)
454                                         l.AddRange (current_type.GetConstructors (bf));
455                                 else {
456                                         MonoType mt = (MonoType) current_type;
457                                         l.AddRange (mt.GetConstructors_internal (bf, this));
458                                         break;
459                                 }
460
461                                 if ((bf & BindingFlags.DeclaredOnly) != 0)
462                                         break;
463                                 current_type = current_type.BaseType;
464                         } while (current_type != null);
465
466                         ConstructorInfo[] result = new ConstructorInfo [l.Count];
467                         l.CopyTo (result);
468                         return result;
469                 }
470
471                 ConstructorInfo[] GetConstructorsInternal (BindingFlags bf, MonoGenericClass reftype)
472                 {
473                         ConstructorInfo[] ctors = GetConstructorsFromGTDWithHint (bf);
474                         if (ctors == null || ctors.Length == 0)
475                                 return new ConstructorInfo [0];
476
477                         ArrayList l = new ArrayList ();
478                         bool match;
479                         MethodAttributes mattrs;
480
481                         initialize ();
482
483                         for (int i = 0; i < ctors.Length; i++) {
484                                 ConstructorInfo c = ctors [i];
485
486                                 match = false;
487                                 mattrs = c.Attributes;
488                                 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
489                                         if ((bf & BindingFlags.Public) != 0)
490                                                 match = true;
491                                 } else {
492                                         if ((bf & BindingFlags.NonPublic) != 0)
493                                                 match = true;
494                                 }
495                                 if (!match)
496                                         continue;
497                                 match = false;
498                                 if ((mattrs & MethodAttributes.Static) != 0) {
499                                         if ((bf & BindingFlags.Static) != 0)
500                                                 match = true;
501                                 } else {
502                                         if ((bf & BindingFlags.Instance) != 0)
503                                                 match = true;
504                                 }
505                                 if (!match)
506                                         continue;
507                                 l.Add (TypeBuilder.GetConstructor (this, c));
508                         }
509
510                         ConstructorInfo[] result = new ConstructorInfo [l.Count];
511                         l.CopyTo (result);
512                         return result;
513                 }
514
515                 public override FieldInfo[] GetFields (BindingFlags bf)
516                 {
517                         if (!IsCompilerContext)
518                                 throw new NotSupportedException ();
519
520                         ArrayList l = new ArrayList ();
521
522                         Type current_type = this;
523                         do {
524                                 MonoGenericClass gi = current_type as MonoGenericClass;
525                                 if (gi != null)
526                                         l.AddRange (gi.GetFieldsInternal (bf, this));
527                                 else if (current_type is TypeBuilder)
528                                         l.AddRange (current_type.GetFields (bf));
529                                 else {
530                                         MonoType mt = (MonoType) current_type;
531                                         l.AddRange (mt.GetFields_internal (bf, this));
532                                         break;
533                                 }
534
535                                 if ((bf & BindingFlags.DeclaredOnly) != 0)
536                                         break;
537                                 current_type = current_type.BaseType;
538                         } while (current_type != null);
539
540                         FieldInfo[] result = new FieldInfo [l.Count];
541                         l.CopyTo (result);
542                         return result;
543                 }
544
545                 FieldInfo[] GetFieldsInternal (BindingFlags bf, MonoGenericClass reftype)
546                 {
547                         FieldInfo[] fields = GetFieldsFromGTD (bf);
548                         if (fields.Length == 0)
549                                 return new FieldInfo [0];
550
551                         ArrayList l = new ArrayList ();
552                         bool match;
553                         FieldAttributes fattrs;
554
555                         initialize ();
556
557                         for (int i = 0; i < fields.Length; i++) {
558                                 FieldInfo c = fields [i];
559
560                                 match = false;
561                                 fattrs = c.Attributes;
562                                 if ((fattrs & FieldAttributes.FieldAccessMask) == FieldAttributes.Public) {
563                                         if ((bf & BindingFlags.Public) != 0)
564                                                 match = true;
565                                 } else {
566                                         if ((bf & BindingFlags.NonPublic) != 0)
567                                                 match = true;
568                                 }
569                                 if (!match)
570                                         continue;
571                                 match = false;
572                                 if ((fattrs & FieldAttributes.Static) != 0) {
573                                         if ((bf & BindingFlags.Static) != 0)
574                                                 match = true;
575                                 } else {
576                                         if ((bf & BindingFlags.Instance) != 0)
577                                                 match = true;
578                                 }
579                                 if (!match)
580                                         continue;
581                                 l.Add (TypeBuilder.GetField (this, c));
582                         }
583
584                         FieldInfo[] result = new FieldInfo [l.Count];
585                         l.CopyTo (result);
586                         return result;
587                 }
588
589                 public override PropertyInfo[] GetProperties (BindingFlags bf)
590                 {
591                         if (!IsCompilerContext)
592                                 throw new NotSupportedException ();
593
594                         ArrayList l = new ArrayList ();
595
596                         Type current_type = this;
597                         do {
598                                 MonoGenericClass gi = current_type as MonoGenericClass;
599                                 if (gi != null)
600                                         l.AddRange (gi.GetPropertiesInternal (bf, this));
601                                 else if (current_type is TypeBuilder)
602                                         l.AddRange (current_type.GetProperties (bf));
603                                 else {
604                                         MonoType mt = (MonoType) current_type;
605                                         l.AddRange (mt.GetPropertiesByName (null, bf, false, this));
606                                         break;
607                                 }
608
609                                 if ((bf & BindingFlags.DeclaredOnly) != 0)
610                                         break;
611                                 current_type = current_type.BaseType;
612                         } while (current_type != null);
613
614                         PropertyInfo[] result = new PropertyInfo [l.Count];
615                         l.CopyTo (result);
616                         return result;
617                 }
618
619                 PropertyInfo[] GetPropertiesInternal (BindingFlags bf, MonoGenericClass reftype)
620                 {
621                         PropertyInfo[] props = GetPropertiesInternal (generic_type, bf);
622                         if (props == null || props.Length == 0)
623                                 return new PropertyInfo [0];
624
625                         ArrayList l = new ArrayList ();
626                         bool match;
627                         MethodAttributes mattrs;
628                         MethodInfo accessor;
629
630                         initialize ();
631
632                         foreach (PropertyInfo pinfo in props) {
633                                 match = false;
634                                 accessor = pinfo.GetGetMethod (true);
635                                 if (accessor == null)
636                                         accessor = pinfo.GetSetMethod (true);
637                                 if (accessor == null)
638                                         continue;
639                                 mattrs = accessor.Attributes;
640                                 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
641                                         if ((bf & BindingFlags.Public) != 0)
642                                                 match = true;
643                                 } else {
644                                         if ((bf & BindingFlags.NonPublic) != 0)
645                                                 match = true;
646                                 }
647                                 if (!match)
648                                         continue;
649                                 match = false;
650                                 if ((mattrs & MethodAttributes.Static) != 0) {
651                                         if ((bf & BindingFlags.Static) != 0)
652                                                 match = true;
653                                 } else {
654                                         if ((bf & BindingFlags.Instance) != 0)
655                                                 match = true;
656                                 }
657                                 if (!match)
658                                         continue;
659                                 l.Add (new PropertyOnTypeBuilderInst (reftype, pinfo));
660                         }
661                         PropertyInfo[] result = new PropertyInfo [l.Count];
662                         l.CopyTo (result);
663                         return result;
664                 }
665
666                 public override EventInfo[] GetEvents (BindingFlags bf)
667                 {
668                         if (!IsCompilerContext)
669                                 throw new NotSupportedException ();
670
671                         ArrayList l = new ArrayList ();
672
673                         Type current_type = this;
674                         do {
675                                 MonoGenericClass gi = current_type as MonoGenericClass;
676                                 if (gi != null)
677                                         l.AddRange (gi.GetEventsInternal (bf, this));
678                                 else if (current_type is TypeBuilder)
679                                         l.AddRange (current_type.GetEvents (bf));
680                                 else {
681                                         MonoType mt = (MonoType) current_type;
682                                         l.AddRange (mt.GetEvents (bf));
683                                         break;
684                                 }
685
686                                 if ((bf & BindingFlags.DeclaredOnly) != 0)
687                                         break;
688                                 current_type = current_type.BaseType;
689                         } while (current_type != null);
690
691                         EventInfo[] result = new EventInfo [l.Count];
692                         l.CopyTo (result);
693                         return result;
694                 }
695         
696                 EventInfo[] GetEventsInternal (BindingFlags bf, MonoGenericClass reftype) {
697                         TypeBuilder tb = generic_type as TypeBuilder;
698                         if (tb == null) {
699                                 EventInfo[] res = generic_type.GetEvents (bf);
700                                 for (int i = 0; i < res.Length; ++i)
701                                         res [i] = new EventOnTypeBuilderInst (this, res [i]);
702                                 return res;
703                         }
704                         EventBuilder[] events = tb.events;
705
706                         if (events == null || events.Length == 0)
707                                 return new EventInfo [0];
708
709                         initialize ();
710
711                         ArrayList l = new ArrayList ();
712                         bool match;
713                         MethodAttributes mattrs;
714                         MethodInfo accessor;
715
716                         for (int i = 0; i < event_count; ++i) {
717                                 EventBuilder ev = events [i];
718
719                                 match = false;
720                                 accessor = ev.add_method;
721                                 if (accessor == null)
722                                         accessor = ev.remove_method;
723                                 if (accessor == null)
724                                         continue;
725                                 mattrs = accessor.Attributes;
726                                 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
727                                         if ((bf & BindingFlags.Public) != 0)
728                                                 match = true;
729                                 } else {
730                                         if ((bf & BindingFlags.NonPublic) != 0)
731                                                 match = true;
732                                 }
733                                 if (!match)
734                                         continue;
735                                 match = false;
736                                 if ((mattrs & MethodAttributes.Static) != 0) {
737                                         if ((bf & BindingFlags.Static) != 0)
738                                                 match = true;
739                                 } else {
740                                         if ((bf & BindingFlags.Instance) != 0)
741                                                 match = true;
742                                 }
743                                 if (!match)
744                                         continue;
745                                 l.Add (new EventOnTypeBuilderInst (this, ev));
746                         }
747                         EventInfo[] result = new EventInfo [l.Count];
748                         l.CopyTo (result);
749                         return result;
750                 }
751
752                 public override Type[] GetNestedTypes (BindingFlags bf)
753                 {
754                         return generic_type.GetNestedTypes (bf);
755                 }
756
757                 public override bool IsAssignableFrom (Type c)
758                 {
759                         if (c == this)
760                                 return true;
761
762                         Type[] interfaces = GetInterfacesInternal ();
763
764                         if (c.IsInterface) {
765                                 if (interfaces == null)
766                                         return false;
767                                 foreach (Type t in interfaces)
768                                         if (c.IsAssignableFrom (t))
769                                                 return true;
770                                 return false;
771                         }
772
773                         Type parent = GetParentType ();
774                         if (parent == null)
775                                 return c == typeof (object);
776                         else
777                                 return c.IsAssignableFrom (parent);
778                 }
779
780                 public override Type UnderlyingSystemType {
781                         get { return this; }
782                 }
783
784                 public override Assembly Assembly {
785                         get { return generic_type.Assembly; }
786                 }
787
788                 public override Module Module {
789                         get { return generic_type.Module; }
790                 }
791
792                 public override string Name {
793                         get { return generic_type.Name; }
794                 }
795
796                 public override string Namespace {
797                         get { return generic_type.Namespace; }
798                 }
799
800                 public override string FullName {
801                         get { return format_name (true, false); }
802                 }
803
804                 public override string AssemblyQualifiedName {
805                         get { return format_name (true, true); }
806                 }
807
808                 public override Guid GUID {
809                         get { throw new NotSupportedException (); }
810                 }
811
812                 string format_name (bool full_name, bool assembly_qualified)
813                 {
814                         StringBuilder sb = new StringBuilder (generic_type.FullName);
815                         bool compiler_ctx = IsCompilerContext;
816
817                         sb.Append ("[");
818                         for (int i = 0; i < type_arguments.Length; ++i) {
819                                 if (i > 0)
820                                         sb.Append (",");
821                                 
822                                 string name;
823                                 if (full_name) {
824                                         string assemblyName = type_arguments [i].Assembly.FullName;
825                                         name = type_arguments [i].FullName;
826                                         if (name != null && assemblyName != null)
827                                                 name = name + ", " + assemblyName;
828                                 } else {
829                                         name = type_arguments [i].ToString ();
830                                 }
831                                 if (name == null) {
832                                         if (compiler_ctx && type_arguments [i].IsGenericParameter)
833                                                 name = type_arguments [i].Name;
834                                         else
835                                                 return null;
836                                 }
837                                 if (full_name)
838                                         sb.Append ("[");
839                                 sb.Append (name);
840                                 if (full_name)
841                                         sb.Append ("]");
842                         }
843                         sb.Append ("]");
844                         if (assembly_qualified) {
845                                 sb.Append (", ");
846                                 sb.Append (generic_type.Assembly.FullName);
847                         }
848                         return sb.ToString ();
849                 }
850
851                 public override string ToString ()
852                 {
853                         return format_name (false, false);
854                 }
855
856                 public override Type GetGenericTypeDefinition ()
857                 {
858                         return generic_type;
859                 }
860
861                 public override Type[] GetGenericArguments ()
862                 {
863                         Type[] ret = new Type [type_arguments.Length];
864                         type_arguments.CopyTo (ret, 0);
865                         return ret;
866                 }
867
868                 public override bool ContainsGenericParameters {
869                         get {
870                                 /*FIXME remove this once compound types are not instantiated using MGC*/
871                                 if (HasElementType)
872                                         return GetElementType ().ContainsGenericParameters;
873
874                                 foreach (Type t in type_arguments) {
875                                         if (t.ContainsGenericParameters)
876                                                 return true;
877                                 }
878                                 return false;
879                         }
880                 }
881
882                 public override bool IsGenericTypeDefinition {
883                         get { return false; }
884                 }
885
886                 public override bool IsGenericType {
887                         get { return !HasElementType; }
888                 }
889
890                 public override Type DeclaringType {
891                         get { return InflateType (generic_type.DeclaringType); }
892                 }
893
894                 public override RuntimeTypeHandle TypeHandle {
895                         get {
896                                 if (!IsCompilerContext)
897                                         throw new NotSupportedException ();
898                                 return _impl;
899                         }
900                 }
901
902                 public override Type MakeArrayType ()
903                 {
904                         return new ArrayType (this, 0);
905                 }
906
907                 public override Type MakeArrayType (int rank)
908                 {
909                         if (rank < 1)
910                                 throw new IndexOutOfRangeException ();
911                         return new ArrayType (this, rank);
912                 }
913
914                 public override Type MakeByRefType ()
915                 {
916                         return new ByRefType (this);
917                 }
918
919                 public override Type MakePointerType ()
920                 {
921                         return new PointerType (this);
922                 }
923
924                 public override Type GetElementType ()
925                 {
926                         throw new NotSupportedException ();
927                 }
928
929                 protected override bool HasElementTypeImpl ()
930                 {
931                         return false;
932                 }
933
934                 protected override bool IsCOMObjectImpl ()
935                 {
936                         return false;
937                 }
938
939                 protected override bool IsPrimitiveImpl ()
940                 {
941                         return false;
942                 }
943
944                 protected override bool IsArrayImpl ()
945                 {
946                         return false;
947                 }
948
949                 protected override bool IsByRefImpl ()
950                 {
951                         return false;
952                 }
953
954                 protected override bool IsPointerImpl ()
955                 {
956                         return false;
957                 }
958
959                 protected override TypeAttributes GetAttributeFlagsImpl ()
960                 {
961                         return generic_type.Attributes; 
962                 }
963
964                 //stuff that throws
965                 public override Type GetInterface (string name, bool ignoreCase)
966                 {
967                         throw new NotSupportedException ();
968                 }
969
970                 public override EventInfo GetEvent (string name, BindingFlags bindingAttr)
971                 {
972                         if (!IsCompilerContext)
973                                 throw new NotSupportedException ();
974                         foreach (var evt in GetEvents (bindingAttr)) {
975                                 if (evt.Name == name)
976                                         return evt;
977                         }
978                         return null;
979                 }
980
981                 public override FieldInfo GetField( string name, BindingFlags bindingAttr)
982                 {
983                         throw new NotSupportedException ();
984                 }
985
986                 public override MemberInfo[] GetMembers (BindingFlags bindingAttr)
987                 {
988                         throw new NotSupportedException ();
989                 }
990
991                 public override Type GetNestedType (string name, BindingFlags bindingAttr)
992                 {
993                         throw new NotSupportedException ();
994                 }
995
996                 public override object InvokeMember (string name, BindingFlags invokeAttr,
997                                                      Binder binder, object target, object[] args,
998                                                      ParameterModifier[] modifiers,
999                                                      CultureInfo culture, string[] namedParameters)
1000                 {
1001                         throw new NotSupportedException ();
1002                 }
1003
1004                 protected override MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder,
1005                                                              CallingConventions callConvention, Type[] types,
1006                                                              ParameterModifier[] modifiers)
1007                 {
1008                         throw new NotSupportedException ();
1009                 }
1010
1011                 protected override PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr, Binder binder,
1012                                                                  Type returnType, Type[] types, ParameterModifier[] modifiers)
1013                 {
1014                         throw new NotSupportedException ();
1015                 }
1016
1017                 protected override ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr,
1018                                                                        Binder binder,
1019                                                                        CallingConventions callConvention,
1020                                                                        Type[] types,
1021                                                                        ParameterModifier[] modifiers)
1022                 {
1023                         if (!IsCompilerContext)
1024                                 throw new NotSupportedException ();
1025                         return MonoType.GetConstructorImpl (GetConstructors (bindingAttr), bindingAttr, binder, callConvention, types, modifiers);
1026                 }
1027
1028                 //MemberInfo
1029                 public override bool IsDefined (Type attributeType, bool inherit)
1030                 {
1031                         if (!IsCompilerContext)
1032                                 throw new NotSupportedException ();
1033                         return generic_type.IsDefined (attributeType, inherit);
1034                 }
1035
1036                 public override object [] GetCustomAttributes (bool inherit)
1037                 {
1038                         if (!IsCompilerContext)
1039                                 throw new NotSupportedException ();
1040                         return generic_type.GetCustomAttributes (inherit);
1041                 }
1042
1043                 public override object [] GetCustomAttributes (Type attributeType, bool inherit)
1044                 {
1045                         if (!IsCompilerContext)
1046                                 throw new NotSupportedException ();
1047                         return generic_type.GetCustomAttributes (attributeType, inherit);
1048                 }
1049         }
1050 }
1051