2 // System.Reflection.MonoGenericClass
4 // Sean MacIsaac (macisaac@ximian.com)
5 // Paolo Molaro (lupus@ximian.com)
6 // Patrik Torstensson (patrik.torstensson@labs2.com)
8 // (C) 2001 Ximian, Inc.
12 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
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:
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
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.
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;
42 namespace System.Reflection
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
50 internal class MonoGenericClass : MonoType
52 #region Keep in sync with object-internals.h
53 #pragma warning disable 649
54 internal TypeBuilder generic_type;
55 Type[] type_arguments;
57 #pragma warning restore 649
60 Hashtable fields, ctors, methods;
63 internal MonoGenericClass ()
66 // this should not be used
67 throw new InvalidOperationException ();
70 internal MonoGenericClass (TypeBuilder tb, Type[] args) : base (null)
72 this.generic_type = tb;
73 this.type_arguments = args;
76 [MethodImplAttribute(MethodImplOptions.InternalCall)]
77 extern void initialize (MethodInfo[] methods, ConstructorInfo[] ctors, FieldInfo[] fields, PropertyInfo[] properties, EventInfo[] events);
79 private const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic |
80 BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
87 MonoGenericClass parent = GetParentType () as MonoGenericClass;
90 EventInfo[] events = generic_type.GetEvents_internal (flags);
91 event_count = events.Length;
93 initialize (generic_type.GetMethods (flags),
94 generic_type.GetConstructorsInternal (flags),
95 generic_type.GetFields (flags),
96 generic_type.GetProperties (flags),
102 Type GetParentType ()
104 return InflateType (generic_type.BaseType);
107 internal Type InflateType (Type type)
109 return InflateType (type, null);
112 internal Type InflateType (Type type, Type[] method_args)
116 if (!type.IsGenericParameter && !type.ContainsGenericParameters)
118 if (type.IsGenericParameter) {
119 if (type.DeclaringMethod == null)
120 return type_arguments [type.GenericParameterPosition];
121 if (method_args != null)
122 return method_args [type.GenericParameterPosition];
126 return InflateType (type.GetElementType (), method_args).MakePointerType ();
128 return InflateType (type.GetElementType (), method_args).MakeByRefType ();
130 if (type.GetArrayRank () > 1)
131 return InflateType (type.GetElementType (), method_args).MakeArrayType (type.GetArrayRank ());
132 #if BOOTSTRAP_NET_2_0
133 if (type.ToString ().EndsWith ("[*]"))
135 if (type.ToString ().EndsWith ("[*]", StringComparison.Ordinal)) /*FIXME, the reflection API doesn't offer a way around this*/
137 return InflateType (type.GetElementType (), method_args).MakeArrayType (1);
138 return InflateType (type.GetElementType (), method_args).MakeArrayType ();
141 Type[] args = type.GetGenericArguments ();
142 for (int i = 0; i < args.Length; ++i)
143 args [i] = InflateType (args [i], method_args);
145 Type gtd = type.IsGenericTypeDefinition ? type : type.GetGenericTypeDefinition ();
146 return gtd.MakeGenericType (args);
149 public override Type BaseType {
151 Type parent = GetParentType ();
152 return parent != null ? parent : generic_type.BaseType;
156 Type[] GetInterfacesInternal ()
158 if (generic_type.interfaces == null)
160 Type[] res = new Type [generic_type.interfaces.Length];
161 for (int i = 0; i < res.Length; ++i)
162 res [i] = InflateType (generic_type.interfaces [i]);
166 public override Type[] GetInterfaces ()
168 if (!generic_type.IsCompilerContext)
169 throw new NotSupportedException ();
170 return GetInterfacesInternal ();
173 protected override bool IsValueTypeImpl ()
175 return generic_type.IsValueType;
178 internal override MethodInfo GetMethod (MethodInfo fromNoninstanciated)
182 if (!(fromNoninstanciated is MethodBuilder))
183 throw new InvalidOperationException ("Inflating non MethodBuilder objects is not supported: " + fromNoninstanciated.GetType ());
185 MethodBuilder mb = (MethodBuilder)fromNoninstanciated;
187 methods = new Hashtable ();
188 if (!methods.ContainsKey (mb))
189 methods [mb] = new MethodOnTypeBuilderInst (this, mb);
190 return (MethodInfo)methods [mb];
193 internal override ConstructorInfo GetConstructor (ConstructorInfo fromNoninstanciated)
197 if (!(fromNoninstanciated is ConstructorBuilder))
198 throw new InvalidOperationException ("Inflating non ConstructorBuilder objects is not supported: " + fromNoninstanciated.GetType ());
200 ConstructorBuilder cb = (ConstructorBuilder)fromNoninstanciated;
202 ctors = new Hashtable ();
203 if (!ctors.ContainsKey (cb))
204 ctors [cb] = new ConstructorOnTypeBuilderInst (this, cb);
205 return (ConstructorInfo)ctors [cb];
208 internal override FieldInfo GetField (FieldInfo fromNoninstanciated)
212 if (!(fromNoninstanciated is FieldBuilder))
213 throw new InvalidOperationException ("Inflating non FieldBuilder objects is not supported: " + fromNoninstanciated.GetType ());
215 FieldBuilder fb = (FieldBuilder)fromNoninstanciated;
217 fields = new Hashtable ();
218 if (!fields.ContainsKey (fb))
219 fields [fb] = new FieldOnTypeBuilderInst (this, fb);
220 return (FieldInfo)fields [fb];
223 public override MethodInfo[] GetMethods (BindingFlags bf)
225 if (!generic_type.IsCompilerContext)
226 throw new NotSupportedException ();
228 ArrayList l = new ArrayList ();
231 // Walk up our class hierarchy and retrieve methods from our
235 Type current_type = this;
237 MonoGenericClass gi = current_type as MonoGenericClass;
239 l.AddRange (gi.GetMethodsInternal (bf, this));
240 else if (current_type is TypeBuilder)
241 l.AddRange (current_type.GetMethods (bf));
243 // If we encounter a `MonoType', its
244 // GetMethodsByName() will return all the methods
245 // from its parent type(s), so we can stop here.
246 MonoType mt = (MonoType) current_type;
247 l.AddRange (mt.GetMethodsByName (null, bf, false, this));
251 if ((bf & BindingFlags.DeclaredOnly) != 0)
253 current_type = current_type.BaseType;
254 } while (current_type != null);
256 MethodInfo[] result = new MethodInfo [l.Count];
261 MethodInfo[] GetMethodsInternal (BindingFlags bf, MonoGenericClass reftype)
263 if (generic_type.num_methods == 0)
264 return new MethodInfo [0];
266 ArrayList l = new ArrayList ();
268 MethodAttributes mattrs;
273 for (int i = 0; i < generic_type.num_methods; ++i) {
274 MethodInfo c = generic_type.methods [i];
277 mattrs = c.Attributes;
278 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
279 if ((bf & BindingFlags.Public) != 0)
282 if ((bf & BindingFlags.NonPublic) != 0)
288 if ((mattrs & MethodAttributes.Static) != 0) {
289 if ((bf & BindingFlags.Static) != 0)
292 if ((bf & BindingFlags.Instance) != 0)
297 c = TypeBuilder.GetMethod (this, c);
301 MethodInfo[] result = new MethodInfo [l.Count];
306 public override ConstructorInfo[] GetConstructors (BindingFlags bf)
308 if (!generic_type.IsCompilerContext)
309 throw new NotSupportedException ();
311 ArrayList l = new ArrayList ();
313 Type current_type = this;
315 MonoGenericClass gi = current_type as MonoGenericClass;
317 l.AddRange (gi.GetConstructorsInternal (bf, this));
318 else if (current_type is TypeBuilder)
319 l.AddRange (current_type.GetConstructors (bf));
321 MonoType mt = (MonoType) current_type;
322 l.AddRange (mt.GetConstructors_internal (bf, this));
326 if ((bf & BindingFlags.DeclaredOnly) != 0)
328 current_type = current_type.BaseType;
329 } while (current_type != null);
331 ConstructorInfo[] result = new ConstructorInfo [l.Count];
336 ConstructorInfo[] GetConstructorsInternal (BindingFlags bf, MonoGenericClass reftype)
338 if (generic_type.ctors == null)
339 return new ConstructorInfo [0];
341 ArrayList l = new ArrayList ();
343 MethodAttributes mattrs;
347 for (int i = 0; i < generic_type.ctors.Length; i++) {
348 ConstructorInfo c = generic_type.ctors [i];
351 mattrs = c.Attributes;
352 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
353 if ((bf & BindingFlags.Public) != 0)
356 if ((bf & BindingFlags.NonPublic) != 0)
362 if ((mattrs & MethodAttributes.Static) != 0) {
363 if ((bf & BindingFlags.Static) != 0)
366 if ((bf & BindingFlags.Instance) != 0)
371 l.Add (TypeBuilder.GetConstructor (this, c));
374 ConstructorInfo[] result = new ConstructorInfo [l.Count];
379 public override FieldInfo[] GetFields (BindingFlags bf)
381 if (!generic_type.IsCompilerContext)
382 throw new NotSupportedException ();
384 ArrayList l = new ArrayList ();
386 Type current_type = this;
388 MonoGenericClass gi = current_type as MonoGenericClass;
390 l.AddRange (gi.GetFieldsInternal (bf, this));
391 else if (current_type is TypeBuilder)
392 l.AddRange (current_type.GetFields (bf));
394 MonoType mt = (MonoType) current_type;
395 l.AddRange (mt.GetFields_internal (bf, this));
399 if ((bf & BindingFlags.DeclaredOnly) != 0)
401 current_type = current_type.BaseType;
402 } while (current_type != null);
404 FieldInfo[] result = new FieldInfo [l.Count];
409 FieldInfo[] GetFieldsInternal (BindingFlags bf, MonoGenericClass reftype)
411 if (generic_type.num_fields == 0)
412 return new FieldInfo [0];
414 ArrayList l = new ArrayList ();
416 FieldAttributes fattrs;
420 for (int i = 0; i < generic_type.num_fields; i++) {
421 FieldInfo c = generic_type.fields [i];
424 fattrs = c.Attributes;
425 if ((fattrs & FieldAttributes.FieldAccessMask) == FieldAttributes.Public) {
426 if ((bf & BindingFlags.Public) != 0)
429 if ((bf & BindingFlags.NonPublic) != 0)
435 if ((fattrs & FieldAttributes.Static) != 0) {
436 if ((bf & BindingFlags.Static) != 0)
439 if ((bf & BindingFlags.Instance) != 0)
444 l.Add (TypeBuilder.GetField (this, c));
447 FieldInfo[] result = new FieldInfo [l.Count];
452 public override PropertyInfo[] GetProperties (BindingFlags bf)
454 if (!generic_type.IsCompilerContext)
455 throw new NotSupportedException ();
457 ArrayList l = new ArrayList ();
459 Type current_type = this;
461 MonoGenericClass gi = current_type as MonoGenericClass;
463 l.AddRange (gi.GetPropertiesInternal (bf, this));
464 else if (current_type is TypeBuilder)
465 l.AddRange (current_type.GetProperties (bf));
467 MonoType mt = (MonoType) current_type;
468 l.AddRange (mt.GetPropertiesByName (null, bf, false, this));
472 if ((bf & BindingFlags.DeclaredOnly) != 0)
474 current_type = current_type.BaseType;
475 } while (current_type != null);
477 PropertyInfo[] result = new PropertyInfo [l.Count];
482 PropertyInfo[] GetPropertiesInternal (BindingFlags bf, MonoGenericClass reftype)
484 if (generic_type.properties == null)
485 return new PropertyInfo [0];
487 ArrayList l = new ArrayList ();
489 MethodAttributes mattrs;
494 foreach (PropertyInfo pinfo in generic_type.properties) {
496 accessor = pinfo.GetGetMethod (true);
497 if (accessor == null)
498 accessor = pinfo.GetSetMethod (true);
499 if (accessor == null)
501 mattrs = accessor.Attributes;
502 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
503 if ((bf & BindingFlags.Public) != 0)
506 if ((bf & BindingFlags.NonPublic) != 0)
512 if ((mattrs & MethodAttributes.Static) != 0) {
513 if ((bf & BindingFlags.Static) != 0)
516 if ((bf & BindingFlags.Instance) != 0)
521 l.Add (new PropertyOnTypeBuilderInst (reftype, pinfo));
523 PropertyInfo[] result = new PropertyInfo [l.Count];
528 public override EventInfo[] GetEvents (BindingFlags bf)
530 if (!generic_type.IsCompilerContext)
531 throw new NotSupportedException ();
533 ArrayList l = new ArrayList ();
535 Type current_type = this;
537 MonoGenericClass gi = current_type as MonoGenericClass;
539 l.AddRange (gi.GetEventsInternal (bf, this));
540 else if (current_type is TypeBuilder)
541 l.AddRange (current_type.GetEvents (bf));
543 MonoType mt = (MonoType) current_type;
544 l.AddRange (mt.GetEvents (bf));
548 if ((bf & BindingFlags.DeclaredOnly) != 0)
550 current_type = current_type.BaseType;
551 } while (current_type != null);
553 EventInfo[] result = new EventInfo [l.Count];
558 EventInfo[] GetEventsInternal (BindingFlags bf, MonoGenericClass reftype) {
559 if (generic_type.events == null)
560 return new EventInfo [0];
564 ArrayList l = new ArrayList ();
566 MethodAttributes mattrs;
569 for (int i = 0; i < event_count; ++i) {
570 EventBuilder ev = generic_type.events [i];
573 accessor = ev.add_method;
574 if (accessor == null)
575 accessor = ev.remove_method;
576 if (accessor == null)
578 mattrs = accessor.Attributes;
579 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
580 if ((bf & BindingFlags.Public) != 0)
583 if ((bf & BindingFlags.NonPublic) != 0)
589 if ((mattrs & MethodAttributes.Static) != 0) {
590 if ((bf & BindingFlags.Static) != 0)
593 if ((bf & BindingFlags.Instance) != 0)
598 l.Add (new EventOnTypeBuilderInst (this, ev));
600 EventInfo[] result = new EventInfo [l.Count];
605 public override Type[] GetNestedTypes (BindingFlags bf)
607 return generic_type.GetNestedTypes (bf);
610 public override bool IsAssignableFrom (Type c)
615 Type[] interfaces = GetInterfacesInternal ();
618 if (interfaces == null)
620 foreach (Type t in interfaces)
621 if (c.IsAssignableFrom (t))
626 Type parent = GetParentType ();
628 return c == typeof (object);
630 return c.IsAssignableFrom (parent);
633 public override Type UnderlyingSystemType {
637 public override string Name {
638 get { return generic_type.Name; }
641 public override string Namespace {
642 get { return generic_type.Namespace; }
645 public override string FullName {
646 get { return format_name (true, false); }
649 public override string AssemblyQualifiedName {
650 get { return format_name (true, true); }
653 public override Guid GUID {
654 get { throw new NotSupportedException (); }
657 string format_name (bool full_name, bool assembly_qualified)
659 StringBuilder sb = new StringBuilder (generic_type.FullName);
660 bool compiler_ctx = generic_type.IsCompilerContext;
663 for (int i = 0; i < type_arguments.Length; ++i) {
667 string name = full_name ? type_arguments [i].AssemblyQualifiedName : type_arguments [i].ToString ();
669 if (compiler_ctx && type_arguments [i].IsGenericParameter)
670 name = type_arguments [i].Name;
681 if (assembly_qualified) {
683 sb.Append (generic_type.Assembly.FullName);
685 return sb.ToString ();
688 public override string ToString ()
690 return format_name (false, false);
693 public override Type MakeArrayType ()
695 return new ArrayType (this, 0);
698 public override Type MakeArrayType (int rank)
701 throw new IndexOutOfRangeException ();
702 return new ArrayType (this, rank);
705 public override Type MakeByRefType ()
707 return new ByRefType (this);
710 public override Type MakePointerType ()
712 return new PointerType (this);
715 /*public override Type GetElementType ()
717 throw new NotSupportedException ();
720 protected override bool IsCOMObjectImpl ()
725 protected override bool IsPrimitiveImpl ()
731 protected override bool IsArrayImpl ()
736 protected override bool IsByRefImpl ()
741 protected override bool IsPointerImpl ()
746 protected override TypeAttributes GetAttributeFlagsImpl ()
748 return generic_type.Attributes;
752 public override Type GetInterface (string name, bool ignoreCase)
754 throw new NotSupportedException ();
757 public override EventInfo GetEvent (string name, BindingFlags bindingAttr)
759 if (!generic_type.IsCompilerContext)
760 throw new NotSupportedException ();
761 foreach (var evt in GetEvents (bindingAttr)) {
762 if (evt.Name == name)
768 public override FieldInfo GetField( string name, BindingFlags bindingAttr)
770 throw new NotSupportedException ();
773 public override MemberInfo[] GetMembers (BindingFlags bindingAttr)
775 throw new NotSupportedException ();
778 public override Type GetNestedType (string name, BindingFlags bindingAttr)
780 throw new NotSupportedException ();
783 public override object InvokeMember (string name, BindingFlags invokeAttr,
784 Binder binder, object target, object[] args,
785 ParameterModifier[] modifiers,
786 CultureInfo culture, string[] namedParameters)
788 throw new NotSupportedException ();
791 protected override MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder,
792 CallingConventions callConvention, Type[] types,
793 ParameterModifier[] modifiers)
795 throw new NotSupportedException ();
798 protected override PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr, Binder binder,
799 Type returnType, Type[] types, ParameterModifier[] modifiers)
801 throw new NotSupportedException ();
804 protected override ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr,
806 CallingConventions callConvention,
808 ParameterModifier[] modifiers)
810 throw new NotSupportedException ();
814 public override bool IsDefined (Type attributeType, bool inherit)
816 throw new NotSupportedException ();
819 public override object [] GetCustomAttributes (bool inherit)
821 throw new NotSupportedException ();
824 public override object [] GetCustomAttributes (Type attributeType, bool inherit)
826 throw new NotSupportedException ();