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;
41 #if NET_2_0 || BOOTSTRAP_NET_2_0
43 namespace System.Reflection
46 * MonoGenericClass represents an instantiation of a generic TypeBuilder. MS
47 * calls this class TypeBuilderInstantiation (a much better name). MS returns
48 * NotImplementedException for many of the methods but we can't do that as gmcs
51 internal class MonoGenericClass : MonoType
53 #region Keep in sync with object-internals.h
54 protected TypeBuilder generic_type;
60 internal MonoGenericClass ()
63 // this should not be used
64 throw new InvalidOperationException ();
67 [MethodImplAttribute(MethodImplOptions.InternalCall)]
68 protected extern void initialize (MethodInfo[] methods, ConstructorInfo[] ctors, FieldInfo[] fields, PropertyInfo[] properties, EventInfo[] events);
70 [MethodImplAttribute(MethodImplOptions.InternalCall)]
71 extern MethodInfo GetCorrespondingInflatedMethod (MethodInfo generic);
73 [MethodImplAttribute(MethodImplOptions.InternalCall)]
74 extern ConstructorInfo GetCorrespondingInflatedConstructor (ConstructorInfo generic);
76 [MethodImplAttribute(MethodImplOptions.InternalCall)]
77 extern FieldInfo GetCorrespondingInflatedField (string generic);
79 [MethodImplAttribute(MethodImplOptions.InternalCall)]
80 protected extern MethodInfo[] GetMethods_internal (Type reflected_type);
82 [MethodImplAttribute(MethodImplOptions.InternalCall)]
83 protected extern ConstructorInfo[] GetConstructors_internal (Type reflected_type);
85 [MethodImplAttribute(MethodImplOptions.InternalCall)]
86 protected extern FieldInfo[] GetFields_internal (Type reflected_type);
88 [MethodImplAttribute(MethodImplOptions.InternalCall)]
89 protected extern PropertyInfo[] GetProperties_internal (Type reflected_type);
91 [MethodImplAttribute(MethodImplOptions.InternalCall)]
92 protected extern EventInfo[] GetEvents_internal (Type reflected_type);
94 private const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic |
95 BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
102 MonoGenericClass parent = GetParentType () as MonoGenericClass;
104 parent.initialize ();
106 initialize (generic_type.GetMethods (flags),
107 generic_type.GetConstructors (flags),
108 generic_type.GetFields (flags),
109 generic_type.GetProperties (flags),
110 generic_type.GetEvents_internal (flags));
115 [MethodImplAttribute(MethodImplOptions.InternalCall)]
116 protected extern Type GetParentType ();
118 [MethodImplAttribute(MethodImplOptions.InternalCall)]
119 protected extern MonoGenericClass[] GetInterfaces_internal ();
121 public override Type BaseType {
123 Type parent = GetParentType ();
124 return parent != null ? parent : generic_type.BaseType;
128 public override Type[] GetInterfaces ()
130 return GetInterfaces_internal ();
133 protected override bool IsValueTypeImpl ()
135 return generic_type.IsValueType;
138 internal override MethodInfo GetMethod (MethodInfo fromNoninstanciated)
142 return GetCorrespondingInflatedMethod (fromNoninstanciated);
145 internal override ConstructorInfo GetConstructor (ConstructorInfo fromNoninstanciated)
149 return GetCorrespondingInflatedConstructor (fromNoninstanciated);
152 internal override FieldInfo GetField (FieldInfo fromNoninstanciated)
157 if (fromNoninstanciated is FieldBuilder) {
158 FieldBuilder fb = (FieldBuilder)fromNoninstanciated;
160 fields = new Hashtable ();
161 if (!fields.ContainsKey (fb))
162 fields [fb] = new FieldOnTypeBuilderInst (this, fb);
163 return (FieldInfo)fields [fb];
166 /* Keep the old code for a while in case the code above needs to be reverted */
167 return GetCorrespondingInflatedField (fromNoninstanciated.Name);
170 public override MethodInfo[] GetMethods (BindingFlags bf)
172 ArrayList l = new ArrayList ();
175 // Walk up our class hierarchy and retrieve methods from our
179 Type current_type = this;
181 MonoGenericClass gi = current_type as MonoGenericClass;
183 l.AddRange (gi.GetMethods_impl (bf, this));
184 else if (current_type is TypeBuilder)
185 l.AddRange (current_type.GetMethods (bf));
187 // If we encounter a `MonoType', its
188 // GetMethodsByName() will return all the methods
189 // from its parent type(s), so we can stop here.
190 MonoType mt = (MonoType) current_type;
191 l.AddRange (mt.GetMethodsByName (null, bf, false, this));
195 if ((bf & BindingFlags.DeclaredOnly) != 0)
197 current_type = current_type.BaseType;
198 } while (current_type != null);
200 MethodInfo[] result = new MethodInfo [l.Count];
205 protected MethodInfo[] GetMethods_impl (BindingFlags bf, Type reftype)
207 ArrayList l = new ArrayList ();
209 MethodAttributes mattrs;
213 MethodInfo[] methods = GetMethods_internal (reftype);
215 for (int i = 0; i < methods.Length; i++) {
216 MethodInfo c = methods [i];
219 mattrs = c.Attributes;
220 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
221 if ((bf & BindingFlags.Public) != 0)
224 if ((bf & BindingFlags.NonPublic) != 0)
230 if ((mattrs & MethodAttributes.Static) != 0) {
231 if ((bf & BindingFlags.Static) != 0)
234 if ((bf & BindingFlags.Instance) != 0)
241 MethodInfo[] result = new MethodInfo [l.Count];
246 public override ConstructorInfo[] GetConstructors (BindingFlags bf)
248 ArrayList l = new ArrayList ();
250 Type current_type = this;
252 MonoGenericClass gi = current_type as MonoGenericClass;
254 l.AddRange (gi.GetConstructors_impl (bf, this));
255 else if (current_type is TypeBuilder)
256 l.AddRange (current_type.GetConstructors (bf));
258 MonoType mt = (MonoType) current_type;
259 l.AddRange (mt.GetConstructors_internal (bf, this));
263 if ((bf & BindingFlags.DeclaredOnly) != 0)
265 current_type = current_type.BaseType;
266 } while (current_type != null);
268 ConstructorInfo[] result = new ConstructorInfo [l.Count];
273 protected ConstructorInfo[] GetConstructors_impl (BindingFlags bf, Type reftype)
275 ArrayList l = new ArrayList ();
277 MethodAttributes mattrs;
281 ConstructorInfo[] ctors = GetConstructors_internal (reftype);
283 for (int i = 0; i < ctors.Length; i++) {
284 ConstructorInfo c = ctors [i];
287 mattrs = c.Attributes;
288 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
289 if ((bf & BindingFlags.Public) != 0)
292 if ((bf & BindingFlags.NonPublic) != 0)
298 if ((mattrs & MethodAttributes.Static) != 0) {
299 if ((bf & BindingFlags.Static) != 0)
302 if ((bf & BindingFlags.Instance) != 0)
310 ConstructorInfo[] result = new ConstructorInfo [l.Count];
315 public override FieldInfo[] GetFields (BindingFlags bf)
317 ArrayList l = new ArrayList ();
319 Type current_type = this;
321 MonoGenericClass gi = current_type as MonoGenericClass;
323 l.AddRange (gi.GetFields_impl (bf, this));
324 else if (current_type is TypeBuilder)
325 l.AddRange (current_type.GetFields (bf));
327 MonoType mt = (MonoType) current_type;
328 l.AddRange (mt.GetFields_internal (bf, this));
332 if ((bf & BindingFlags.DeclaredOnly) != 0)
334 current_type = current_type.BaseType;
335 } while (current_type != null);
337 FieldInfo[] result = new FieldInfo [l.Count];
342 protected FieldInfo[] GetFields_impl (BindingFlags bf, Type reftype)
344 ArrayList l = new ArrayList ();
346 FieldAttributes fattrs;
350 FieldInfo[] fields = GetFields_internal (reftype);
352 for (int i = 0; i < fields.Length; i++) {
353 FieldInfo c = fields [i];
356 fattrs = c.Attributes;
357 if ((fattrs & FieldAttributes.FieldAccessMask) == FieldAttributes.Public) {
358 if ((bf & BindingFlags.Public) != 0)
361 if ((bf & BindingFlags.NonPublic) != 0)
367 if ((fattrs & FieldAttributes.Static) != 0) {
368 if ((bf & BindingFlags.Static) != 0)
371 if ((bf & BindingFlags.Instance) != 0)
378 FieldInfo[] result = new FieldInfo [l.Count];
383 public override PropertyInfo[] GetProperties (BindingFlags bf)
385 ArrayList l = new ArrayList ();
387 Type current_type = this;
389 MonoGenericClass gi = current_type as MonoGenericClass;
391 l.AddRange (gi.GetProperties_impl (bf, this));
392 else if (current_type is TypeBuilder)
393 l.AddRange (current_type.GetProperties (bf));
395 MonoType mt = (MonoType) current_type;
396 l.AddRange (mt.GetPropertiesByName (null, bf, false, this));
400 if ((bf & BindingFlags.DeclaredOnly) != 0)
402 current_type = current_type.BaseType;
403 } while (current_type != null);
405 PropertyInfo[] result = new PropertyInfo [l.Count];
410 protected PropertyInfo[] GetProperties_impl (BindingFlags bf, Type reftype)
412 ArrayList l = new ArrayList ();
414 MethodAttributes mattrs;
419 PropertyInfo[] properties = GetProperties_internal (reftype);
421 for (int i = 0; i < properties.Length; i++) {
422 PropertyInfo c = properties [i];
425 accessor = c.GetGetMethod (true);
426 if (accessor == null)
427 accessor = c.GetSetMethod (true);
428 if (accessor == null)
430 mattrs = accessor.Attributes;
431 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
432 if ((bf & BindingFlags.Public) != 0)
435 if ((bf & BindingFlags.NonPublic) != 0)
441 if ((mattrs & MethodAttributes.Static) != 0) {
442 if ((bf & BindingFlags.Static) != 0)
445 if ((bf & BindingFlags.Instance) != 0)
452 PropertyInfo[] result = new PropertyInfo [l.Count];
457 protected override PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr,
458 Binder binder, Type returnType,
460 ParameterModifier[] modifiers)
462 bool ignoreCase = ((bindingAttr & BindingFlags.IgnoreCase) != 0);
463 PropertyInfo [] props = GetProperties (bindingAttr);
466 for (int i = 0; i < props.Length; ++i) {
467 if (String.Compare (props [i].Name, name, ignoreCase) == 0) {
469 al = new ArrayList ();
476 props = (PropertyInfo[])al.ToArray (typeof (PropertyInfo));
478 int count = props.Length;
480 if (count == 1 && (types == null || types.Length == 0))
484 binder = Binder.DefaultBinder;
486 return binder.SelectProperty (bindingAttr, props, returnType, types, modifiers);
489 public override EventInfo[] GetEvents (BindingFlags bf)
491 ArrayList l = new ArrayList ();
493 Type current_type = this;
495 MonoGenericClass gi = current_type as MonoGenericClass;
497 l.AddRange (gi.GetEvents_impl (bf, this));
498 else if (current_type is TypeBuilder)
499 l.AddRange (current_type.GetEvents (bf));
501 MonoType mt = (MonoType) current_type;
502 l.AddRange (mt.GetEvents (bf));
506 if ((bf & BindingFlags.DeclaredOnly) != 0)
508 current_type = current_type.BaseType;
509 } while (current_type != null);
511 EventInfo[] result = new EventInfo [l.Count];
516 protected EventInfo[] GetEvents_impl (BindingFlags bf, Type reftype)
518 ArrayList l = new ArrayList ();
520 MethodAttributes mattrs;
525 EventInfo[] events = GetEvents_internal (reftype);
527 for (int i = 0; i < events.Length; i++) {
528 EventInfo c = events [i];
531 accessor = c.GetAddMethod (true);
532 if (accessor == null)
533 accessor = c.GetRemoveMethod (true);
534 if (accessor == null)
536 mattrs = accessor.Attributes;
537 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
538 if ((bf & BindingFlags.Public) != 0)
541 if ((bf & BindingFlags.NonPublic) != 0)
547 if ((mattrs & MethodAttributes.Static) != 0) {
548 if ((bf & BindingFlags.Static) != 0)
551 if ((bf & BindingFlags.Instance) != 0)
558 EventInfo[] result = new EventInfo [l.Count];
563 public override Type[] GetNestedTypes (BindingFlags bf)
565 return generic_type.GetNestedTypes (bf);
568 public override bool IsAssignableFrom (Type c)
573 MonoGenericClass[] interfaces = GetInterfaces_internal ();
576 if (interfaces == null)
578 foreach (Type t in interfaces)
579 if (c.IsAssignableFrom (t))
584 Type parent = GetParentType ();
586 return c == typeof (object);
588 return c.IsAssignableFrom (parent);