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