**** Merged from MCS ****
[mono-project.git] / mcs / class / corlib / System.Reflection / MonoGenericInst.cs
blobc5c5b55952e7ebfd0cff2968aeb7214e12cf3e91
1 //
2 // System.MonoType
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 //
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:
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.
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 namespace System.Reflection
43 internal class MonoGenericInst : MonoType
45 protected Type generic_type;
46 bool initialized;
48 [MonoTODO]
49 internal MonoGenericInst ()
50 : base (null)
52 // this should not be used
53 throw new InvalidOperationException ();
56 [MethodImplAttribute(MethodImplOptions.InternalCall)]
57 protected extern void initialize (MethodInfo[] methods, ConstructorInfo[] ctors, FieldInfo[] fields, PropertyInfo[] properties, EventInfo[] events);
59 [MethodImplAttribute(MethodImplOptions.InternalCall)]
60 protected extern MethodInfo[] GetMethods_internal (Type reflected_type);
62 [MethodImplAttribute(MethodImplOptions.InternalCall)]
63 protected extern ConstructorInfo[] GetConstructors_internal (Type reflected_type);
65 [MethodImplAttribute(MethodImplOptions.InternalCall)]
66 protected extern FieldInfo[] GetFields_internal (Type reflected_type);
68 [MethodImplAttribute(MethodImplOptions.InternalCall)]
69 protected extern PropertyInfo[] GetProperties_internal (Type reflected_type);
71 [MethodImplAttribute(MethodImplOptions.InternalCall)]
72 protected extern EventInfo[] GetEvents_internal (Type reflected_type);
74 private const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic |
75 BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
77 EventInfo[] get_event_info ()
79 if (generic_type is TypeBuilder)
80 return ((TypeBuilder) generic_type).GetEvents_internal (flags);
81 else
82 return generic_type.GetEvents (flags);
85 void initialize ()
87 if (initialized)
88 return;
90 MonoGenericInst parent = GetParentType ();
91 if (parent != null)
92 parent.initialize ();
94 initialize (generic_type.GetMethods (flags),
95 generic_type.GetConstructors (flags),
96 generic_type.GetFields (flags),
97 generic_type.GetProperties (flags),
98 get_event_info ());
100 initialized = true;
103 [MethodImplAttribute(MethodImplOptions.InternalCall)]
104 protected extern MonoGenericInst GetParentType ();
106 [MethodImplAttribute(MethodImplOptions.InternalCall)]
107 protected extern MonoGenericInst[] GetInterfaces_internal ();
109 public override Type BaseType {
110 get {
111 MonoGenericInst parent = GetParentType ();
112 return parent != null ? parent : generic_type.BaseType;
116 public override Type[] GetInterfaces ()
118 return GetInterfaces_internal ();
121 protected override bool IsValueTypeImpl ()
123 return generic_type.IsValueType;
126 public override MethodInfo[] GetMethods (BindingFlags bf)
128 ArrayList l = new ArrayList ();
131 // Walk up our class hierarchy and retrieve methods from our
132 // parent classes.
135 Type current_type = this;
136 do {
137 MonoGenericInst gi = current_type as MonoGenericInst;
138 if (gi != null)
139 l.AddRange (gi.GetMethods_impl (bf, this));
140 else if (current_type is TypeBuilder)
141 l.AddRange (current_type.GetMethods (bf));
142 else {
143 // If we encounter a `MonoType', its
144 // GetMethodsByName() will return all the methods
145 // from its parent type(s), so we can stop here.
146 MonoType mt = (MonoType) current_type;
147 l.AddRange (mt.GetMethodsByName (null, bf, false, this));
148 break;
151 if ((bf & BindingFlags.DeclaredOnly) != 0)
152 break;
153 current_type = current_type.BaseType;
154 } while (current_type != null);
156 MethodInfo[] result = new MethodInfo [l.Count];
157 l.CopyTo (result);
158 return result;
161 protected MethodInfo[] GetMethods_impl (BindingFlags bf, Type reftype)
163 ArrayList l = new ArrayList ();
164 bool match;
165 MethodAttributes mattrs;
167 initialize ();
169 MethodInfo[] methods = GetMethods_internal (reftype);
171 for (int i = 0; i < methods.Length; i++) {
172 MethodInfo c = methods [i];
174 match = false;
175 mattrs = c.Attributes;
176 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
177 if ((bf & BindingFlags.Public) != 0)
178 match = true;
179 } else {
180 if ((bf & BindingFlags.NonPublic) != 0)
181 match = true;
183 if (!match)
184 continue;
185 match = false;
186 if ((mattrs & MethodAttributes.Static) != 0) {
187 if ((bf & BindingFlags.Static) != 0)
188 match = true;
189 } else {
190 if ((bf & BindingFlags.Instance) != 0)
191 match = true;
193 if (!match)
194 continue;
195 l.Add (c);
197 MethodInfo[] result = new MethodInfo [l.Count];
198 l.CopyTo (result);
199 return result;
202 public override ConstructorInfo[] GetConstructors (BindingFlags bf)
204 ArrayList l = new ArrayList ();
206 Type current_type = this;
207 do {
208 MonoGenericInst gi = current_type as MonoGenericInst;
209 if (gi != null)
210 l.AddRange (gi.GetConstructors_impl (bf, this));
211 else if (current_type is TypeBuilder)
212 l.AddRange (current_type.GetConstructors (bf));
213 else {
214 MonoType mt = (MonoType) current_type;
215 l.AddRange (mt.GetConstructors_internal (bf, this));
216 break;
219 if ((bf & BindingFlags.DeclaredOnly) != 0)
220 break;
221 current_type = current_type.BaseType;
222 } while (current_type != null);
224 ConstructorInfo[] result = new ConstructorInfo [l.Count];
225 l.CopyTo (result);
226 return result;
229 protected ConstructorInfo[] GetConstructors_impl (BindingFlags bf, Type reftype)
231 ArrayList l = new ArrayList ();
232 bool match;
233 MethodAttributes mattrs;
235 initialize ();
237 ConstructorInfo[] ctors = GetConstructors_internal (reftype);
239 for (int i = 0; i < ctors.Length; i++) {
240 ConstructorInfo c = ctors [i];
242 match = false;
243 mattrs = c.Attributes;
244 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
245 if ((bf & BindingFlags.Public) != 0)
246 match = true;
247 } else {
248 if ((bf & BindingFlags.NonPublic) != 0)
249 match = true;
251 if (!match)
252 continue;
253 match = false;
254 if ((mattrs & MethodAttributes.Static) != 0) {
255 if ((bf & BindingFlags.Static) != 0)
256 match = true;
257 } else {
258 if ((bf & BindingFlags.Instance) != 0)
259 match = true;
261 if (!match)
262 continue;
263 l.Add (c);
266 ConstructorInfo[] result = new ConstructorInfo [l.Count];
267 l.CopyTo (result);
268 return result;
271 public override FieldInfo[] GetFields (BindingFlags bf)
273 ArrayList l = new ArrayList ();
275 Type current_type = this;
276 do {
277 MonoGenericInst gi = current_type as MonoGenericInst;
278 if (gi != null)
279 l.AddRange (gi.GetFields_impl (bf, this));
280 else if (current_type is TypeBuilder)
281 l.AddRange (current_type.GetFields (bf));
282 else {
283 MonoType mt = (MonoType) current_type;
284 l.AddRange (mt.GetFields_internal (bf, this));
285 break;
288 if ((bf & BindingFlags.DeclaredOnly) != 0)
289 break;
290 current_type = current_type.BaseType;
291 } while (current_type != null);
293 FieldInfo[] result = new FieldInfo [l.Count];
294 l.CopyTo (result);
295 return result;
298 protected FieldInfo[] GetFields_impl (BindingFlags bf, Type reftype)
300 ArrayList l = new ArrayList ();
301 bool match;
302 FieldAttributes fattrs;
304 initialize ();
306 FieldInfo[] fields = GetFields_internal (reftype);
308 for (int i = 0; i < fields.Length; i++) {
309 FieldInfo c = fields [i];
311 match = false;
312 fattrs = c.Attributes;
313 if ((fattrs & FieldAttributes.FieldAccessMask) == FieldAttributes.Public) {
314 if ((bf & BindingFlags.Public) != 0)
315 match = true;
316 } else {
317 if ((bf & BindingFlags.NonPublic) != 0)
318 match = true;
320 if (!match)
321 continue;
322 match = false;
323 if ((fattrs & FieldAttributes.Static) != 0) {
324 if ((bf & BindingFlags.Static) != 0)
325 match = true;
326 } else {
327 if ((bf & BindingFlags.Instance) != 0)
328 match = true;
330 if (!match)
331 continue;
332 l.Add (c);
334 FieldInfo[] result = new FieldInfo [l.Count];
335 l.CopyTo (result);
336 return result;
339 public override PropertyInfo[] GetProperties (BindingFlags bf)
341 ArrayList l = new ArrayList ();
343 Type current_type = this;
344 do {
345 MonoGenericInst gi = current_type as MonoGenericInst;
346 if (gi != null)
347 l.AddRange (gi.GetProperties_impl (bf, this));
348 else if (current_type is TypeBuilder)
349 l.AddRange (current_type.GetProperties (bf));
350 else {
351 MonoType mt = (MonoType) current_type;
352 l.AddRange (mt.GetPropertiesByName (null, bf, false, this));
353 break;
356 if ((bf & BindingFlags.DeclaredOnly) != 0)
357 break;
358 current_type = current_type.BaseType;
359 } while (current_type != null);
361 PropertyInfo[] result = new PropertyInfo [l.Count];
362 l.CopyTo (result);
363 return result;
366 protected PropertyInfo[] GetProperties_impl (BindingFlags bf, Type reftype)
368 ArrayList l = new ArrayList ();
369 bool match;
370 MethodAttributes mattrs;
371 MethodInfo accessor;
373 initialize ();
375 PropertyInfo[] properties = GetProperties_internal (reftype);
377 for (int i = 0; i < properties.Length; i++) {
378 PropertyInfo c = properties [i];
380 match = false;
381 accessor = c.GetGetMethod (true);
382 if (accessor == null)
383 accessor = c.GetSetMethod (true);
384 if (accessor == null)
385 continue;
386 mattrs = accessor.Attributes;
387 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
388 if ((bf & BindingFlags.Public) != 0)
389 match = true;
390 } else {
391 if ((bf & BindingFlags.NonPublic) != 0)
392 match = true;
394 if (!match)
395 continue;
396 match = false;
397 if ((mattrs & MethodAttributes.Static) != 0) {
398 if ((bf & BindingFlags.Static) != 0)
399 match = true;
400 } else {
401 if ((bf & BindingFlags.Instance) != 0)
402 match = true;
404 if (!match)
405 continue;
406 l.Add (c);
408 PropertyInfo[] result = new PropertyInfo [l.Count];
409 l.CopyTo (result);
410 return result;
413 public override EventInfo[] GetEvents (BindingFlags bf)
415 ArrayList l = new ArrayList ();
417 Type current_type = this;
418 do {
419 MonoGenericInst gi = current_type as MonoGenericInst;
420 if (gi != null)
421 l.AddRange (gi.GetEvents_impl (bf, this));
422 else if (current_type is TypeBuilder)
423 l.AddRange (current_type.GetEvents (bf));
424 else {
425 MonoType mt = (MonoType) current_type;
426 l.AddRange (mt.GetEvents (bf));
427 break;
430 if ((bf & BindingFlags.DeclaredOnly) != 0)
431 break;
432 current_type = current_type.BaseType;
433 } while (current_type != null);
435 EventInfo[] result = new EventInfo [l.Count];
436 l.CopyTo (result);
437 return result;
440 protected EventInfo[] GetEvents_impl (BindingFlags bf, Type reftype)
442 ArrayList l = new ArrayList ();
443 bool match;
444 MethodAttributes mattrs;
445 MethodInfo accessor;
447 initialize ();
449 EventInfo[] events = GetEvents_internal (reftype);
451 for (int i = 0; i < events.Length; i++) {
452 EventInfo c = events [i];
454 match = false;
455 accessor = c.GetAddMethod (true);
456 if (accessor == null)
457 accessor = c.GetRemoveMethod (true);
458 if (accessor == null)
459 continue;
460 mattrs = accessor.Attributes;
461 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
462 if ((bf & BindingFlags.Public) != 0)
463 match = true;
464 } else {
465 if ((bf & BindingFlags.NonPublic) != 0)
466 match = true;
468 if (!match)
469 continue;
470 match = false;
471 if ((mattrs & MethodAttributes.Static) != 0) {
472 if ((bf & BindingFlags.Static) != 0)
473 match = true;
474 } else {
475 if ((bf & BindingFlags.Instance) != 0)
476 match = true;
478 if (!match)
479 continue;
480 l.Add (c);
482 EventInfo[] result = new EventInfo [l.Count];
483 l.CopyTo (result);
484 return result;
487 public override Type[] GetNestedTypes (BindingFlags bf)
489 return generic_type.GetNestedTypes (bf);