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