IKVM11  11
Java SE 11 Virtual Machine for .NET
Loading...
Searching...
No Matches
Type.cs
Go to the documentation of this file.
1/*
2 Copyright (C) 2009-2015 Jeroen Frijters
3
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
7
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
11
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
19
20 Jeroen Frijters
21 jeroen@frijters.net
22
23*/
24using System;
25using System.Collections.Generic;
26using System.Runtime.InteropServices;
27
28namespace IKVM.Reflection
29{
30
31 internal abstract class Type : MemberInfo, IGenericContext, IGenericBinder
32 {
33
34 public static readonly Type[] EmptyTypes = Array.Empty<Type>();
35 protected readonly Type underlyingType;
36 protected TypeFlags typeFlags;
37 byte sigElementType; // only used if (__IsBuiltIn || HasElementType || __IsFunctionPointer || IsGenericParameter)
38
39 [Flags]
40 protected enum TypeFlags : ushort
41 {
42 // for use by TypeBuilder or TypeDefImpl
43 IsGenericTypeDefinition = 1,
44
45 // for use by TypeBuilder
46 HasNestedTypes = 2,
47 Baked = 4,
48
49 // for use by IsValueType to cache result of IsValueTypeImpl
50 ValueType = 8,
51 NotValueType = 16,
52
53 // for use by TypeDefImpl, TypeBuilder or MissingType
54 PotentialEnumOrValueType = 32,
55 EnumOrValueType = 64,
56
57 // for use by TypeDefImpl
58 NotGenericTypeDefinition = 128,
59
60 // used to cache __ContainsMissingType
61 ContainsMissingType_Unknown = 0,
62 ContainsMissingType_Pending = 256,
63 ContainsMissingType_Yes = 512,
64 ContainsMissingType_No = 256 | 512,
65 ContainsMissingType_Mask = 256 | 512,
66
67 // built-in type support
68 PotentialBuiltIn = 1024,
69 BuiltIn = 2048,
70 }
71
75 internal Type()
76 {
77 this.underlyingType = this;
78 }
79
84 internal Type(Type underlyingType)
85 {
86 System.Diagnostics.Debug.Assert(underlyingType.underlyingType == underlyingType);
87 this.underlyingType = underlyingType;
88 this.typeFlags = underlyingType.typeFlags;
89 }
90
95 internal Type(byte sigElementType) :
96 this()
97 {
98 this.sigElementType = sigElementType;
99 }
100
101 public static Binder DefaultBinder
102 {
103 get { return new DefaultBinder(); }
104 }
105
106 public sealed override MemberTypes MemberType
107 {
108 get { return IsNested ? MemberTypes.NestedType : MemberTypes.TypeInfo; }
109 }
110
111 public virtual string AssemblyQualifiedName
112 {
113 // NOTE the assembly name is not escaped here, only when used in a generic type instantiation
114 get { return this.FullName + ", " + this.Assembly.FullName; }
115 }
116
117 public abstract Type BaseType
118 {
119 get;
120 }
121
122 public abstract TypeAttributes Attributes
123 {
124 get;
125 }
126
127 public virtual Type GetElementType()
128 {
129 return null;
130 }
131
132 internal virtual void CheckBaked()
133 {
134 }
135
136 public virtual Type[] __GetDeclaredTypes()
137 {
138 return Type.EmptyTypes;
139 }
140
141 public virtual Type[] __GetDeclaredInterfaces()
142 {
143 return Type.EmptyTypes;
144 }
145
146 public virtual MethodBase[] __GetDeclaredMethods()
147 {
148 return Array.Empty<MethodBase>();
149 }
150
151 public virtual __MethodImplMap __GetMethodImplMap()
152 {
153 throw new NotSupportedException();
154 }
155
156 public virtual FieldInfo[] __GetDeclaredFields()
157 {
158 return Array.Empty<FieldInfo>();
159 }
160
161 public virtual EventInfo[] __GetDeclaredEvents()
162 {
163 return Array.Empty<EventInfo>();
164 }
165
166 public virtual PropertyInfo[] __GetDeclaredProperties()
167 {
168 return Array.Empty<PropertyInfo>();
169 }
170
171 public virtual CustomModifiers __GetCustomModifiers()
172 {
173 return new CustomModifiers();
174 }
175
176 [Obsolete("Please use __GetCustomModifiers() instead.")]
177 public Type[] __GetRequiredCustomModifiers()
178 {
179 return __GetCustomModifiers().GetRequired();
180 }
181
182 [Obsolete("Please use __GetCustomModifiers() instead.")]
183 public Type[] __GetOptionalCustomModifiers()
184 {
185 return __GetCustomModifiers().GetOptional();
186 }
187
188 public virtual __StandAloneMethodSig __MethodSignature
189 {
190 get { throw new InvalidOperationException(); }
191 }
192
193 public bool HasElementType
194 {
195 get { return IsArray || IsByRef || IsPointer; }
196 }
197
198 public bool IsArray
199 {
200 get { return sigElementType == Signature.ELEMENT_TYPE_ARRAY || sigElementType == Signature.ELEMENT_TYPE_SZARRAY; }
201 }
202
203 public bool IsSZArray
204 {
205 get { return sigElementType == Signature.ELEMENT_TYPE_SZARRAY; }
206 }
207
208 public bool IsByRef
209 {
210 get { return sigElementType == Signature.ELEMENT_TYPE_BYREF; }
211 }
212
213 public bool IsPointer
214 {
215 get { return sigElementType == Signature.ELEMENT_TYPE_PTR; }
216 }
217
218 public bool IsFunctionPointer
219 {
220 get { return sigElementType == Signature.ELEMENT_TYPE_FNPTR; }
221 }
222
223 public bool IsUnmanagedFunctionPointer
224 {
225 get { throw new NotSupportedException(); }
226 }
227
228 public bool IsValueType
229 {
230 get
231 {
232 // MissingType sets both flags for WinRT projection types
233 return (typeFlags & (TypeFlags.ValueType | TypeFlags.NotValueType)) switch
234 {
235 0 or TypeFlags.ValueType | TypeFlags.NotValueType => IsValueTypeImpl,
236 _ => (typeFlags & TypeFlags.ValueType) != 0,
237 };
238 }
239 }
240
241 protected abstract bool IsValueTypeImpl
242 {
243 get;
244 }
245
246 public bool IsGenericParameter
247 {
248 get { return sigElementType == Signature.ELEMENT_TYPE_VAR || sigElementType == Signature.ELEMENT_TYPE_MVAR; }
249 }
250
251 public bool IsGenericMethodParameter
252 {
253 get { return IsGenericParameter && DeclaringMethod is not null; }
254 }
255
256 public bool IsGenericTypeParameter
257 {
258 get { return IsGenericParameter && DeclaringMethod is null; }
259 }
260
261 public virtual int GenericParameterPosition
262 {
263 get { throw new NotSupportedException(); }
264 }
265
266 public virtual MethodBase DeclaringMethod
267 {
268 get { return null; }
269 }
270
271 public Type UnderlyingSystemType
272 {
273 get { return underlyingType; }
274 }
275
276 public override Type DeclaringType
277 {
278 get { return null; }
279 }
280
281 internal virtual TypeName TypeName
282 {
283 get { throw new InvalidOperationException(); }
284 }
285
286 public string __Name
287 {
288 get { return TypeName.Name; }
289 }
290
291 public string __Namespace
292 {
293 get { return TypeName.Namespace; }
294 }
295
296 public abstract override string Name
297 {
298 get;
299 }
300
301 public virtual string Namespace
302 {
303 get
304 {
305 if (IsNested)
306 return DeclaringType.Namespace;
307
308 return __Namespace;
309 }
310 }
311
312 internal virtual int GetModuleBuilderToken()
313 {
314 throw new InvalidOperationException();
315 }
316
317 public static bool operator ==(Type t1, Type t2)
318 {
319 // Casting to object results in smaller code than calling ReferenceEquals and makes
320 // this method more likely to be inlined.
321 // On CLR v2 x86, microbenchmarks show this to be faster than calling ReferenceEquals.
322 return (object)t1 == (object)t2
323 || ((object)t1 != null && (object)t2 != null && (object)t1.underlyingType == (object)t2.underlyingType);
324 }
325
326 public static bool operator !=(Type t1, Type t2)
327 {
328 return !(t1 == t2);
329 }
330
331 public bool Equals(Type type)
332 {
333 return this == type;
334 }
335
336 public override bool Equals(object obj)
337 {
338 return Equals(obj as Type);
339 }
340
341 public override int GetHashCode()
342 {
343 Type type = UnderlyingSystemType;
344 return ReferenceEquals(type, this) ? base.GetHashCode() : type.GetHashCode();
345 }
346
347 public Type[] GenericTypeArguments
348 {
349 get { return IsConstructedGenericType ? GetGenericArguments() : Type.EmptyTypes; }
350 }
351
352 public virtual Type[] GetGenericArguments()
353 {
354 return Type.EmptyTypes;
355 }
356
357 public virtual CustomModifiers[] __GetGenericArgumentsCustomModifiers()
358 {
359 return Array.Empty<CustomModifiers>();
360 }
361
362 [Obsolete("Please use __GetGenericArgumentsCustomModifiers() instead")]
363 public Type[][] __GetGenericArgumentsRequiredCustomModifiers()
364 {
365 var customModifiers = __GetGenericArgumentsCustomModifiers();
366 var array = new Type[customModifiers.Length][];
367 for (int i = 0; i < array.Length; i++)
368 array[i] = customModifiers[i].GetRequired();
369
370 return array;
371 }
372
373 [Obsolete("Please use __GetGenericArgumentsCustomModifiers() instead")]
374 public Type[][] __GetGenericArgumentsOptionalCustomModifiers()
375 {
376 var customModifiers = __GetGenericArgumentsCustomModifiers();
377 var array = new Type[customModifiers.Length][];
378 for (int i = 0; i < array.Length; i++)
379 array[i] = customModifiers[i].GetOptional();
380
381 return array;
382 }
383
384 public virtual Type GetGenericTypeDefinition()
385 {
386 throw new InvalidOperationException();
387 }
388
389 public StructLayoutAttribute StructLayoutAttribute
390 {
391 get
392 {
393 var layout = (Attributes & TypeAttributes.LayoutMask) switch
394 {
395 TypeAttributes.AutoLayout => new StructLayoutAttribute(LayoutKind.Auto),
396 TypeAttributes.SequentialLayout => new StructLayoutAttribute(LayoutKind.Sequential),
397 TypeAttributes.ExplicitLayout => new StructLayoutAttribute(LayoutKind.Explicit),
398 _ => throw new BadImageFormatException(),
399 };
400
401 layout.CharSet = (Attributes & TypeAttributes.StringFormatMask) switch
402 {
403 TypeAttributes.AnsiClass => CharSet.Ansi,
404 TypeAttributes.UnicodeClass => CharSet.Unicode,
405 TypeAttributes.AutoClass => CharSet.Auto,
406 _ => CharSet.None,
407 };
408
409 // compatibility with System.Reflection
410 if (!__GetLayout(out layout.Pack, out layout.Size))
411 layout.Pack = 8;
412
413 return layout;
414 }
415 }
416
417 public virtual bool __GetLayout(out int packingSize, out int typeSize)
418 {
419 packingSize = 0;
420 typeSize = 0;
421 return false;
422 }
423
424 public virtual bool IsGenericType
425 {
426 get { return false; }
427 }
428
429 public virtual bool IsGenericTypeDefinition
430 {
431 get { return false; }
432 }
433
434 // .NET 4.5 API
435 public virtual bool IsConstructedGenericType
436 {
437 get { return false; }
438 }
439
440 public virtual bool ContainsGenericParameters
441 {
442 get
443 {
444 if (IsGenericParameter)
445 return true;
446
447 foreach (var arg in GetGenericArguments())
448 if (arg.ContainsGenericParameters)
449 return true;
450
451 return false;
452 }
453 }
454
455 public virtual Type[] GetGenericParameterConstraints()
456 {
457 throw new InvalidOperationException();
458 }
459
460 public virtual CustomModifiers[] __GetGenericParameterConstraintCustomModifiers()
461 {
462 throw new InvalidOperationException();
463 }
464
465 public virtual GenericParameterAttributes GenericParameterAttributes
466 {
467 get { throw new InvalidOperationException(); }
468 }
469
470 public virtual int GetArrayRank()
471 {
472 throw new NotSupportedException();
473 }
474
475 public virtual int[] __GetArraySizes()
476 {
477 throw new NotSupportedException();
478 }
479
480 public virtual int[] __GetArrayLowerBounds()
481 {
482 throw new NotSupportedException();
483 }
484
485 // .NET 4.0 API
486 public virtual Type GetEnumUnderlyingType()
487 {
488 if (!IsEnum)
489 throw new ArgumentException();
490
491 CheckBaked();
492 return GetEnumUnderlyingTypeImpl();
493 }
494
495 internal Type GetEnumUnderlyingTypeImpl()
496 {
497 foreach (var field in __GetDeclaredFields())
498 if (!field.IsStatic)
499 return field.FieldType; // the CLR assumes that an enum has only one instance field, so we can do the same
500
501 throw new InvalidOperationException();
502 }
503
504 public string[] GetEnumNames()
505 {
506 if (!IsEnum)
507 throw new ArgumentException();
508
509 var names = new List<string>();
510 foreach (var field in __GetDeclaredFields())
511 if (field.IsLiteral)
512 names.Add(field.Name);
513
514 return names.ToArray();
515 }
516
517 public string GetEnumName(object value)
518 {
519 if (!IsEnum)
520 throw new ArgumentException();
521 if (value == null)
522 throw new ArgumentNullException();
523
524 try
525 {
526 value = Convert.ChangeType(value, __GetSystemType(GetTypeCode(GetEnumUnderlyingType())));
527 }
528 catch (FormatException)
529 {
530 throw new ArgumentException();
531 }
532 catch (OverflowException)
533 {
534 return null;
535 }
536 catch (InvalidCastException)
537 {
538 return null;
539 }
540
541 foreach (var field in __GetDeclaredFields())
542 if (field.IsLiteral && field.GetRawConstantValue().Equals(value))
543 return field.Name;
544
545 return null;
546 }
547
548 public bool IsEnumDefined(object value)
549 {
550 if (value is string)
551 return Array.IndexOf(GetEnumNames(), value) != -1;
552 if (!IsEnum)
553 throw new ArgumentException();
554 if (value == null)
555 throw new ArgumentNullException();
556 if (value.GetType() != __GetSystemType(GetTypeCode(GetEnumUnderlyingType())))
557 throw new ArgumentException();
558
559 foreach (var field in __GetDeclaredFields())
560 if (field.IsLiteral && field.GetRawConstantValue().Equals(value))
561 return true;
562
563 return false;
564 }
565
566 public Array GetEnumValues()
567 {
568 if (!IsEnum)
569 throw new ArgumentException();
570
571 var l = __GetDeclaredFields();
572 var a = new object[l.Length];
573
574 for (int i = 0; i < l.Length; i++)
575 if (l[i].IsLiteral)
576 a[i] = l[i];
577
578 return a;
579 }
580
581 public override string ToString()
582 {
583 return FullName;
584 }
585
586 public abstract string FullName
587 {
588 get;
589 }
590
591 protected string GetFullName()
592 {
593 var ns = TypeNameParser.Escape(__Namespace);
594 var decl = DeclaringType;
595 if (decl == null)
596 {
597 if (ns == null)
598 return Name;
599 else
600 return ns + "." + Name;
601 }
602 else
603 {
604 if (ns == null)
605 return decl.FullName + "+" + Name;
606 else
607 return decl.FullName + "+" + ns + "." + Name;
608 }
609 }
610
611 internal virtual bool IsModulePseudoType
612 {
613 get { return false; }
614 }
615
616 internal virtual Type GetGenericTypeArgument(int index)
617 {
618 throw new InvalidOperationException();
619 }
620
621 public MemberInfo[] GetDefaultMembers()
622 {
623 var defaultMemberAttribute = Module.Universe.Import(typeof(System.Reflection.DefaultMemberAttribute));
624 foreach (var cad in CustomAttributeData.GetCustomAttributes(this))
625 if (cad.Constructor.DeclaringType.Equals(defaultMemberAttribute))
626 return GetMember((string)cad.ConstructorArguments[0].Value);
627
628 return Array.Empty<MemberInfo>();
629 }
630
631 public MemberInfo[] GetMember(string name)
632 {
633 return GetMember(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
634 }
635
636 public MemberInfo[] GetMember(string name, BindingFlags bindingAttr)
637 {
638 return GetMember(name, MemberTypes.All, bindingAttr);
639 }
640
641 public MemberInfo[] GetMembers()
642 {
643 return GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
644 }
645
646 public MemberInfo[] GetMembers(BindingFlags bindingAttr)
647 {
648 var members = new List<MemberInfo>();
649 members.AddRange(GetConstructors(bindingAttr));
650 members.AddRange(GetMethods(bindingAttr));
651 members.AddRange(GetFields(bindingAttr));
652 members.AddRange(GetProperties(bindingAttr));
653 members.AddRange(GetEvents(bindingAttr));
654 members.AddRange(GetNestedTypes(bindingAttr));
655 return members.ToArray();
656 }
657
658 public MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr)
659 {
660 MemberFilter filter;
661 if ((bindingAttr & BindingFlags.IgnoreCase) != 0)
662 {
663 name = name.ToLowerInvariant();
664 filter = delegate (MemberInfo member, object filterCriteria) { return member.Name.ToLowerInvariant().Equals(filterCriteria); };
665 }
666 else
667 {
668 filter = delegate (MemberInfo member, object filterCriteria) { return member.Name.Equals(filterCriteria); };
669 }
670
671 return FindMembers(type, bindingAttr, filter, name);
672 }
673
674 static void AddMembers(List<MemberInfo> list, MemberFilter filter, object filterCriteria, MemberInfo[] members)
675 {
676 foreach (var member in members)
677 if (filter == null || filter(member, filterCriteria))
678 list.Add(member);
679 }
680
681 public MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria)
682 {
683 var members = new List<MemberInfo>();
684 if ((memberType & MemberTypes.Constructor) != 0)
685 AddMembers(members, filter, filterCriteria, GetConstructors(bindingAttr));
686 if ((memberType & MemberTypes.Method) != 0)
687 AddMembers(members, filter, filterCriteria, GetMethods(bindingAttr));
688 if ((memberType & MemberTypes.Field) != 0)
689 AddMembers(members, filter, filterCriteria, GetFields(bindingAttr));
690 if ((memberType & MemberTypes.Property) != 0)
691 AddMembers(members, filter, filterCriteria, GetProperties(bindingAttr));
692 if ((memberType & MemberTypes.Event) != 0)
693 AddMembers(members, filter, filterCriteria, GetEvents(bindingAttr));
694 if ((memberType & MemberTypes.NestedType) != 0)
695 AddMembers(members, filter, filterCriteria, GetNestedTypes(bindingAttr));
696
697 return members.ToArray();
698 }
699
700 MemberInfo[] GetMembers<T>()
701 {
702 if (typeof(T) == typeof(ConstructorInfo) || typeof(T) == typeof(MethodInfo))
703 return __GetDeclaredMethods();
704 else if (typeof(T) == typeof(FieldInfo))
705 return __GetDeclaredFields();
706 else if (typeof(T) == typeof(PropertyInfo))
707 return __GetDeclaredProperties();
708 else if (typeof(T) == typeof(EventInfo))
709 return __GetDeclaredEvents();
710 else if (typeof(T) == typeof(Type))
711 return __GetDeclaredTypes();
712 else
713 throw new InvalidOperationException();
714 }
715
716 T[] GetMembers<T>(BindingFlags flags)
717 where T : MemberInfo
718 {
719 CheckBaked();
720
721 var list = new List<T>();
722 foreach (var member in GetMembers<T>())
723 if (member is T m && m.BindingFlagsMatch(flags))
724 list.Add(m);
725
726 if ((flags & BindingFlags.DeclaredOnly) == 0)
727 {
728 for (var type = BaseType; type != null; type = type.BaseType)
729 {
730 type.CheckBaked();
731
732 foreach (var member in type.GetMembers<T>())
733 if (member is T m && m.BindingFlagsMatchInherited(flags))
734 list.Add((T)m.SetReflectedType(this));
735 }
736 }
737
738 return list.ToArray();
739 }
740
741 T GetMemberByName<T>(string name, BindingFlags flags, Predicate<T> filter)
742 where T : MemberInfo
743 {
744 CheckBaked();
745
746 if ((flags & BindingFlags.IgnoreCase) != 0)
747 name = name.ToLowerInvariant();
748
749 T found = null;
750
751 foreach (var member in GetMembers<T>())
752 {
753 if (member is T m && m.BindingFlagsMatch(flags))
754 {
755 var memberName = m.Name;
756 if ((flags & BindingFlags.IgnoreCase) != 0)
757 memberName = memberName.ToLowerInvariant();
758
759 if (memberName == name && (filter == null || filter(m)))
760 {
761 if (found != null)
762 throw new AmbiguousMatchException();
763
764 found = m;
765 }
766 }
767 }
768
769 if ((flags & BindingFlags.DeclaredOnly) == 0)
770 {
771 for (var type = BaseType; (found == null || typeof(T) == typeof(MethodInfo)) && type != null; type = type.BaseType)
772 {
773 type.CheckBaked();
774
775 foreach (var member in type.GetMembers<T>())
776 {
777 if (member is T m && m.BindingFlagsMatchInherited(flags))
778 {
779 var memberName = m.Name;
780
781 if ((flags & BindingFlags.IgnoreCase) != 0)
782 memberName = memberName.ToLowerInvariant();
783
784 if (memberName == name && (filter == null || filter(m)))
785 {
786 if (found != null)
787 {
788 // TODO does this depend on HideBySig vs HideByName?
789 if (found is MethodInfo mi && mi.MethodSignature.MatchParameterTypes(((MethodBase)member).MethodSignature))
790 continue;
791
792 throw new AmbiguousMatchException();
793 }
794
795 found = (T)member.SetReflectedType(this);
796 }
797 }
798 }
799 }
800 }
801
802 return found;
803 }
804
805 T GetMemberByName<T>(string name, BindingFlags flags)
806 where T : MemberInfo
807 {
808 return GetMemberByName<T>(name, flags, null);
809 }
810
811 public EventInfo GetEvent(string name)
812 {
813 return GetEvent(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
814 }
815
816 public EventInfo GetEvent(string name, BindingFlags bindingAttr)
817 {
818 return GetMemberByName<EventInfo>(name, bindingAttr);
819 }
820
821 public EventInfo[] GetEvents()
822 {
823 return GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
824 }
825
826 public EventInfo[] GetEvents(BindingFlags bindingAttr)
827 {
828 return GetMembers<EventInfo>(bindingAttr);
829 }
830
831 public FieldInfo GetField(string name)
832 {
833 return GetField(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
834 }
835
836 public FieldInfo GetField(string name, BindingFlags bindingAttr)
837 {
838 return GetMemberByName<FieldInfo>(name, bindingAttr);
839 }
840
841 public FieldInfo[] GetFields()
842 {
843 return GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
844 }
845
846 public FieldInfo[] GetFields(BindingFlags bindingAttr)
847 {
848 return GetMembers<FieldInfo>(bindingAttr);
849 }
850
851 public Type[] GetInterfaces()
852 {
853 var list = new List<Type>();
854 for (var type = this; type != null; type = type.BaseType)
855 AddInterfaces(list, type);
856
857 return list.ToArray();
858 }
859
860 private static void AddInterfaces(List<Type> list, Type type)
861 {
862 foreach (Type iface in type.__GetDeclaredInterfaces())
863 {
864 if (!list.Contains(iface))
865 {
866 list.Add(iface);
867 AddInterfaces(list, iface);
868 }
869 }
870 }
871
872 public MethodInfo[] GetMethods(BindingFlags bindingAttr)
873 {
874 CheckBaked();
875
876 var list = new List<MethodInfo>();
877
878 foreach (var mb in __GetDeclaredMethods())
879 {
880 var mi = mb as MethodInfo;
881 if (mi != null && mi.BindingFlagsMatch(bindingAttr))
882 list.Add(mi);
883 }
884
885 if ((bindingAttr & BindingFlags.DeclaredOnly) == 0)
886 {
887 var baseMethods = new List<MethodInfo>();
888 foreach (var mi in list)
889 if (mi.IsVirtual)
890 baseMethods.Add(mi.GetBaseDefinition());
891
892 for (var type = BaseType; type != null; type = type.BaseType)
893 {
894 type.CheckBaked();
895
896 foreach (var mb in type.__GetDeclaredMethods())
897 {
898 var mi = mb as MethodInfo;
899 if (mi != null && mi.BindingFlagsMatchInherited(bindingAttr))
900 {
901 if (mi.IsVirtual)
902 {
903 if (baseMethods == null)
904 baseMethods = new List<MethodInfo>();
905 else if (baseMethods.Contains(mi.GetBaseDefinition()))
906 continue;
907
908 baseMethods.Add(mi.GetBaseDefinition());
909 }
910
911 list.Add((MethodInfo)mi.SetReflectedType(this));
912 }
913 }
914 }
915 }
916
917 return list.ToArray();
918 }
919
920 public MethodInfo[] GetMethods()
921 {
922 return GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
923 }
924
925 public MethodInfo GetMethod(string name)
926 {
927 return GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
928 }
929
930 public MethodInfo GetMethod(string name, BindingFlags bindingAttr)
931 {
932 return GetMemberByName<MethodInfo>(name, bindingAttr);
933 }
934
935 public MethodInfo GetMethod(string name, Type[] types)
936 {
937 return GetMethod(name, types, null);
938 }
939
940 public MethodInfo GetMethod(string name, Type[] types, ParameterModifier[] modifiers)
941 {
942 return GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, null, types, modifiers);
943 }
944
945 public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
946 {
947 // first we try an exact match and only if that fails we fall back to using the binder
948 return GetMemberByName(name, bindingAttr, (MethodInfo m) => m.MethodSignature.MatchParameterTypes(types)) ?? GetMethodWithBinder<MethodInfo>(name, bindingAttr, binder ?? DefaultBinder, types, modifiers);
949 }
950
951 private T GetMethodWithBinder<T>(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
952 where T : MethodBase
953 {
954 var list = new List<MethodBase>();
955
956 GetMemberByName(name, bindingAttr, delegate (T method)
957 {
958 list.Add(method);
959 return false;
960 });
961
962 return (T)binder.SelectMethod(bindingAttr, list.ToArray(), types, modifiers);
963 }
964
965 public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
966 {
967 // FXBUG callConvention seems to be ignored
968 return GetMethod(name, bindingAttr, binder, types, modifiers);
969 }
970
971 public ConstructorInfo[] GetConstructors()
972 {
973 return GetConstructors(BindingFlags.Public | BindingFlags.Instance);
974 }
975
976 public ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
977 {
978 return GetMembers<ConstructorInfo>(bindingAttr | BindingFlags.DeclaredOnly);
979 }
980
981 public ConstructorInfo GetConstructor(Type[] types)
982 {
983 return GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, CallingConventions.Standard, types, null);
984 }
985
986 public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
987 {
988 ConstructorInfo ci1 = null;
989 if ((bindingAttr & BindingFlags.Instance) != 0)
990 ci1 = GetConstructorImpl(ConstructorInfo.ConstructorName, bindingAttr, binder, types, modifiers);
991
992 if ((bindingAttr & BindingFlags.Static) != 0)
993 {
994 var ci2 = GetConstructorImpl(ConstructorInfo.TypeConstructorName, bindingAttr, binder, types, modifiers);
995 if (ci2 != null)
996 {
997 if (ci1 != null)
998 throw new AmbiguousMatchException();
999
1000 return ci2;
1001 }
1002 }
1003
1004 return ci1;
1005 }
1006
1007 private ConstructorInfo GetConstructorImpl(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
1008 {
1009 // first we try an exact match and only if that fails we fall back to using the binder
1010 return GetMemberByName<ConstructorInfo>(name, bindingAttr | BindingFlags.DeclaredOnly,
1011 delegate (ConstructorInfo ctor) { return ctor.MethodSignature.MatchParameterTypes(types); })
1012 ?? GetMethodWithBinder<ConstructorInfo>(name, bindingAttr, binder ?? DefaultBinder, types, modifiers);
1013 }
1014
1015 public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, CallingConventions callingConvention, Type[] types, ParameterModifier[] modifiers)
1016 {
1017 // FXBUG callConvention seems to be ignored
1018 return GetConstructor(bindingAttr, binder, types, modifiers);
1019 }
1020
1021 internal Type ResolveNestedType(Module requester, TypeName typeName)
1022 {
1023 return FindNestedType(typeName) ?? Module.Universe.GetMissingTypeOrThrow(requester, Module, this, typeName);
1024 }
1025
1026 // unlike the public API, this takes the namespace and name into account
1027 internal virtual Type FindNestedType(TypeName name)
1028 {
1029 foreach (var type in __GetDeclaredTypes())
1030 if (type.TypeName == name)
1031 return type;
1032
1033 return null;
1034 }
1035
1036 internal virtual Type FindNestedTypeIgnoreCase(TypeName lowerCaseName)
1037 {
1038 foreach (var type in __GetDeclaredTypes())
1039 if (type.TypeName.ToLowerInvariant() == lowerCaseName)
1040 return type;
1041
1042 return null;
1043 }
1044
1045 public Type GetNestedType(string name)
1046 {
1047 return GetNestedType(name, BindingFlags.Public);
1048 }
1049
1050 public Type GetNestedType(string name, BindingFlags bindingAttr)
1051 {
1052 // FXBUG the namespace is ignored, so we can use GetMemberByName
1053 return GetMemberByName<Type>(name, bindingAttr | BindingFlags.DeclaredOnly);
1054 }
1055
1056 public Type[] GetNestedTypes()
1057 {
1058 return GetNestedTypes(BindingFlags.Public);
1059 }
1060
1061 public Type[] GetNestedTypes(BindingFlags bindingAttr)
1062 {
1063 // FXBUG the namespace is ignored, so we can use GetMember
1064 return GetMembers<Type>(bindingAttr | BindingFlags.DeclaredOnly);
1065 }
1066
1067 public PropertyInfo[] GetProperties()
1068 {
1069 return GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
1070 }
1071
1072 public PropertyInfo[] GetProperties(BindingFlags bindingAttr)
1073 {
1074 return GetMembers<PropertyInfo>(bindingAttr);
1075 }
1076
1077 public PropertyInfo GetProperty(string name)
1078 {
1079 return GetProperty(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
1080 }
1081
1082 public PropertyInfo GetProperty(string name, BindingFlags bindingAttr)
1083 {
1084 return GetMemberByName<PropertyInfo>(name, bindingAttr);
1085 }
1086
1087 public PropertyInfo GetProperty(string name, Type returnType)
1088 {
1089 const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static;
1090
1091 return GetMemberByName<PropertyInfo>(name, flags, delegate (PropertyInfo prop) { return prop.PropertyType.Equals(returnType); })
1092 ?? GetPropertyWithBinder(name, flags, DefaultBinder, returnType, null, null);
1093 }
1094
1095 public PropertyInfo GetProperty(string name, Type[] types)
1096 {
1097 const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static;
1098
1099 return GetMemberByName<PropertyInfo>(name, flags, delegate (PropertyInfo prop) { return prop.PropertySignature.MatchParameterTypes(types); })
1100 ?? GetPropertyWithBinder(name, flags, DefaultBinder, null, types, null);
1101 }
1102
1103 public PropertyInfo GetProperty(string name, Type returnType, Type[] types)
1104 {
1105 return GetProperty(name, returnType, types, null);
1106 }
1107
1108 public PropertyInfo GetProperty(string name, Type returnType, Type[] types, ParameterModifier[] modifiers)
1109 {
1110 return GetProperty(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static, null, returnType, types, modifiers);
1111 }
1112
1113 public PropertyInfo GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
1114 {
1115 return GetMemberByName<PropertyInfo>(name, bindingAttr,
1116 delegate (PropertyInfo prop)
1117 {
1118 return prop.PropertyType.Equals(returnType) && prop.PropertySignature.MatchParameterTypes(types);
1119 })
1120 ?? GetPropertyWithBinder(name, bindingAttr, binder ?? DefaultBinder, returnType, types, modifiers);
1121 }
1122
1123 private PropertyInfo GetPropertyWithBinder(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
1124 {
1125 List<PropertyInfo> list = new List<PropertyInfo>();
1126 GetMemberByName<PropertyInfo>(name, bindingAttr, delegate (PropertyInfo property)
1127 {
1128 list.Add(property);
1129 return false;
1130 });
1131 return binder.SelectProperty(bindingAttr, list.ToArray(), returnType, types, modifiers);
1132 }
1133
1134 public Type GetInterface(string name)
1135 {
1136 return GetInterface(name, false);
1137 }
1138
1139 public Type GetInterface(string name, bool ignoreCase)
1140 {
1141 if (ignoreCase)
1142 name = name.ToLowerInvariant();
1143
1144 Type found = null;
1145
1146 foreach (var type in GetInterfaces())
1147 {
1148 var typeName = type.FullName;
1149 if (ignoreCase)
1150 typeName = typeName.ToLowerInvariant();
1151
1152 if (typeName == name)
1153 {
1154 if (found != null)
1155 throw new AmbiguousMatchException();
1156
1157 found = type;
1158 }
1159 }
1160
1161 return found;
1162 }
1163
1164 public Type[] FindInterfaces(TypeFilter filter, object filterCriteria)
1165 {
1166 var list = new List<Type>();
1167 foreach (var type in GetInterfaces())
1168 if (filter(type, filterCriteria))
1169 list.Add(type);
1170
1171 return list.ToArray();
1172 }
1173
1174 public ConstructorInfo TypeInitializer
1175 {
1176 get { return GetConstructor(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); }
1177 }
1178
1179 public bool IsPrimitive
1180 {
1181 get
1182 {
1183 return __IsBuiltIn
1184 && ((sigElementType >= Signature.ELEMENT_TYPE_BOOLEAN && sigElementType <= Signature.ELEMENT_TYPE_R8)
1185 || sigElementType == Signature.ELEMENT_TYPE_I
1186 || sigElementType == Signature.ELEMENT_TYPE_U);
1187 }
1188 }
1189
1190 public bool __IsBuiltIn
1191 {
1192 get
1193 {
1194 return (typeFlags & (TypeFlags.BuiltIn | TypeFlags.PotentialBuiltIn)) != 0
1195 && ((typeFlags & TypeFlags.BuiltIn) != 0 || ResolvePotentialBuiltInType());
1196 }
1197 }
1198
1199 internal byte SigElementType
1200 {
1201 get
1202 {
1203 // this property can only be called after __IsBuiltIn, HasElementType, __IsFunctionPointer or IsGenericParameter returned true
1204 System.Diagnostics.Debug.Assert((typeFlags & TypeFlags.BuiltIn) != 0 || HasElementType || IsFunctionPointer || IsGenericParameter);
1205 return sigElementType;
1206 }
1207 }
1208
1209 bool ResolvePotentialBuiltInType()
1210 {
1211 // [ECMA 335] 8.2.2 Built-in value and reference types
1212 typeFlags &= ~TypeFlags.PotentialBuiltIn;
1213
1214 return __Name switch
1215 {
1216 "Boolean" => ResolvePotentialBuiltInType(Universe.System_Boolean, Signature.ELEMENT_TYPE_BOOLEAN),
1217 "Char" => ResolvePotentialBuiltInType(Universe.System_Char, Signature.ELEMENT_TYPE_CHAR),
1218 "Object" => ResolvePotentialBuiltInType(Universe.System_Object, Signature.ELEMENT_TYPE_OBJECT),
1219 "String" => ResolvePotentialBuiltInType(Universe.System_String, Signature.ELEMENT_TYPE_STRING),
1220 "Single" => ResolvePotentialBuiltInType(Universe.System_Single, Signature.ELEMENT_TYPE_R4),
1221 "Double" => ResolvePotentialBuiltInType(Universe.System_Double, Signature.ELEMENT_TYPE_R8),
1222 "SByte" => ResolvePotentialBuiltInType(Universe.System_SByte, Signature.ELEMENT_TYPE_I1),
1223 "Int16" => ResolvePotentialBuiltInType(Universe.System_Int16, Signature.ELEMENT_TYPE_I2),
1224 "Int32" => ResolvePotentialBuiltInType(Universe.System_Int32, Signature.ELEMENT_TYPE_I4),
1225 "Int64" => ResolvePotentialBuiltInType(Universe.System_Int64, Signature.ELEMENT_TYPE_I8),
1226 "IntPtr" => ResolvePotentialBuiltInType(Universe.System_IntPtr, Signature.ELEMENT_TYPE_I),
1227 "UIntPtr" => ResolvePotentialBuiltInType(Universe.System_UIntPtr, Signature.ELEMENT_TYPE_U),
1228 "TypedReference" => ResolvePotentialBuiltInType(Universe.System_TypedReference, Signature.ELEMENT_TYPE_TYPEDBYREF),
1229 "Byte" => ResolvePotentialBuiltInType(Universe.System_Byte, Signature.ELEMENT_TYPE_U1),
1230 "UInt16" => ResolvePotentialBuiltInType(Universe.System_UInt16, Signature.ELEMENT_TYPE_U2),
1231 "UInt32" => ResolvePotentialBuiltInType(Universe.System_UInt32, Signature.ELEMENT_TYPE_U4),
1232 "UInt64" => ResolvePotentialBuiltInType(Universe.System_UInt64, Signature.ELEMENT_TYPE_U8),
1233 // [LAMESPEC] missing from ECMA list for some reason
1234 "Void" => ResolvePotentialBuiltInType(Universe.System_Void, Signature.ELEMENT_TYPE_VOID),
1235 _ => throw new InvalidOperationException(),
1236 };
1237 }
1238
1239 bool ResolvePotentialBuiltInType(Type builtIn, byte elementType)
1240 {
1241 if (this == builtIn)
1242 {
1243 typeFlags |= TypeFlags.BuiltIn;
1244 this.sigElementType = elementType;
1245 return true;
1246 }
1247
1248 return false;
1249 }
1250
1251 public bool IsEnum
1252 {
1253 get
1254 {
1255 var baseType = BaseType;
1256 return baseType != null
1257 && baseType.IsEnumOrValueType
1258 && baseType.__Name[0] == 'E';
1259 }
1260 }
1261
1262 public bool IsSealed
1263 {
1264 get { return (Attributes & TypeAttributes.Sealed) != 0; }
1265 }
1266
1267 public bool IsAbstract
1268 {
1269 get { return (Attributes & TypeAttributes.Abstract) != 0; }
1270 }
1271
1272 private bool CheckVisibility(TypeAttributes access)
1273 {
1274 return (Attributes & TypeAttributes.VisibilityMask) == access;
1275 }
1276
1277 public bool IsPublic
1278 {
1279 get { return CheckVisibility(TypeAttributes.Public); }
1280 }
1281
1282 public bool IsNestedPublic
1283 {
1284 get { return CheckVisibility(TypeAttributes.NestedPublic); }
1285 }
1286
1287 public bool IsNestedPrivate
1288 {
1289 get { return CheckVisibility(TypeAttributes.NestedPrivate); }
1290 }
1291
1292 public bool IsNestedFamily
1293 {
1294 get { return CheckVisibility(TypeAttributes.NestedFamily); }
1295 }
1296
1297 public bool IsNestedAssembly
1298 {
1299 get { return CheckVisibility(TypeAttributes.NestedAssembly); }
1300 }
1301
1302 public bool IsNestedFamANDAssem
1303 {
1304 get { return CheckVisibility(TypeAttributes.NestedFamANDAssem); }
1305 }
1306
1307 public bool IsNestedFamORAssem
1308 {
1309 get { return CheckVisibility(TypeAttributes.NestedFamORAssem); }
1310 }
1311
1312 public bool IsNotPublic
1313 {
1314 get { return CheckVisibility(TypeAttributes.NotPublic); }
1315 }
1316
1317 public bool IsImport
1318 {
1319 get { return (Attributes & TypeAttributes.Import) != 0; }
1320 }
1321
1322 public bool IsCOMObject
1323 {
1324 get { return IsClass && IsImport; }
1325 }
1326
1327 public bool IsContextful
1328 {
1329 get { return IsSubclassOf(this.Module.Universe.System_ContextBoundObject); }
1330 }
1331
1332 public bool IsMarshalByRef
1333 {
1334 get { return IsSubclassOf(this.Module.Universe.System_MarshalByRefObject); }
1335 }
1336
1337 public virtual bool IsVisible
1338 {
1339 get { return IsPublic || (IsNestedPublic && this.DeclaringType.IsVisible); }
1340 }
1341
1342 public bool IsAnsiClass
1343 {
1344 get { return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass; }
1345 }
1346
1347 public bool IsUnicodeClass
1348 {
1349 get { return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass; }
1350 }
1351
1352 public bool IsAutoClass
1353 {
1354 get { return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass; }
1355 }
1356
1357 public bool IsAutoLayout
1358 {
1359 get { return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout; }
1360 }
1361
1362 public bool IsLayoutSequential
1363 {
1364 get { return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout; }
1365 }
1366
1367 public bool IsExplicitLayout
1368 {
1369 get { return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout; }
1370 }
1371
1372 public bool IsSpecialName
1373 {
1374 get { return (Attributes & TypeAttributes.SpecialName) != 0; }
1375 }
1376
1377 public bool IsSerializable
1378 {
1379 get { return (Attributes & TypeAttributes.Serializable) != 0; }
1380 }
1381
1382 public bool IsClass
1383 {
1384 get { return !IsInterface && !IsValueType; }
1385 }
1386
1387 public bool IsInterface
1388 {
1389 get { return (Attributes & TypeAttributes.Interface) != 0; }
1390 }
1391
1392 public bool IsNested
1393 {
1394 // FXBUG we check the declaring type (like .NET) and this results
1395 // in IsNested returning true for a generic type parameter
1396 get { return this.DeclaringType != null; }
1397 }
1398
1399 public bool __ContainsMissingType
1400 {
1401 get
1402 {
1403 if ((typeFlags & TypeFlags.ContainsMissingType_Mask) == TypeFlags.ContainsMissingType_Unknown)
1404 {
1405 // Generic parameter constraints can refer back to the type parameter they are part of,
1406 // so to prevent infinite recursion, we set the Pending flag during computation.
1407 typeFlags |= TypeFlags.ContainsMissingType_Pending;
1408 typeFlags = (typeFlags & ~TypeFlags.ContainsMissingType_Mask) | (ContainsMissingTypeImpl ? TypeFlags.ContainsMissingType_Yes : TypeFlags.ContainsMissingType_No);
1409 }
1410
1411 return (typeFlags & TypeFlags.ContainsMissingType_Mask) == TypeFlags.ContainsMissingType_Yes;
1412 }
1413 }
1414
1415 internal static bool ContainsMissingType(Type[] types)
1416 {
1417 if (types == null)
1418 return false;
1419
1420 foreach (var type in types)
1421 if (type.__ContainsMissingType)
1422 return true;
1423
1424 return false;
1425 }
1426
1427 protected virtual bool ContainsMissingTypeImpl
1428 {
1429 get
1430 {
1431 return __IsMissing
1432 || ContainsMissingType(GetGenericArguments())
1433 || __GetCustomModifiers().ContainsMissingType;
1434 }
1435 }
1436
1437 public Type MakeArrayType()
1438 {
1439 return ArrayType.Make(this, new CustomModifiers());
1440 }
1441
1442 public Type __MakeArrayType(CustomModifiers customModifiers)
1443 {
1444 return ArrayType.Make(this, customModifiers);
1445 }
1446
1447 [Obsolete("Please use __MakeArrayType(CustomModifiers) instead.")]
1448 public Type __MakeArrayType(Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1449 {
1450 return __MakeArrayType(CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers));
1451 }
1452
1453 public Type MakeArrayType(int rank)
1454 {
1455 return __MakeArrayType(rank, new CustomModifiers());
1456 }
1457
1458 public Type __MakeArrayType(int rank, CustomModifiers customModifiers)
1459 {
1460 return MultiArrayType.Make(this, rank, Array.Empty<int>(), new int[rank], customModifiers);
1461 }
1462
1463 [Obsolete("Please use __MakeArrayType(int, CustomModifiers) instead.")]
1464 public Type __MakeArrayType(int rank, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1465 {
1466 return __MakeArrayType(rank, CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers));
1467 }
1468
1469 public Type __MakeArrayType(int rank, int[] sizes, int[] lobounds, CustomModifiers customModifiers)
1470 {
1471 return MultiArrayType.Make(this, rank, sizes ?? Array.Empty<int>(), lobounds ?? Array.Empty<int>(), customModifiers);
1472 }
1473
1474 [Obsolete("Please use __MakeArrayType(int, int[], int[], CustomModifiers) instead.")]
1475 public Type __MakeArrayType(int rank, int[] sizes, int[] lobounds, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1476 {
1477 return __MakeArrayType(rank, sizes, lobounds, CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers));
1478 }
1479
1480 public Type MakeByRefType()
1481 {
1482 return ByRefType.Make(this, new CustomModifiers());
1483 }
1484
1485 public Type __MakeByRefType(CustomModifiers customModifiers)
1486 {
1487 return ByRefType.Make(this, customModifiers);
1488 }
1489
1490 [Obsolete("Please use __MakeByRefType(CustomModifiers) instead.")]
1491 public Type __MakeByRefType(Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1492 {
1493 return __MakeByRefType(CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers));
1494 }
1495
1496 public Type MakePointerType()
1497 {
1498 return PointerType.Make(this, new CustomModifiers());
1499 }
1500
1501 public Type __MakePointerType(CustomModifiers customModifiers)
1502 {
1503 return PointerType.Make(this, customModifiers);
1504 }
1505
1506 [Obsolete("Please use __MakeByRefType(CustomModifiers) instead.")]
1507 public Type __MakePointerType(Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1508 {
1509 return __MakePointerType(CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers));
1510 }
1511
1512 public Type MakeGenericType(params Type[] typeArguments)
1513 {
1514 return __MakeGenericType(typeArguments, null);
1515 }
1516
1517 public Type __MakeGenericType(Type[] typeArguments, CustomModifiers[] customModifiers)
1518 {
1519 if (!this.__IsMissing && !this.IsGenericTypeDefinition)
1520 {
1521 throw new InvalidOperationException();
1522 }
1523 return GenericTypeInstance.Make(this, Util.Copy(typeArguments), customModifiers == null ? null : (CustomModifiers[])customModifiers.Clone());
1524 }
1525
1526 [Obsolete("Please use __MakeGenericType(Type[], CustomModifiers[]) instead.")]
1527 public Type __MakeGenericType(Type[] typeArguments, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
1528 {
1529 if (!this.__IsMissing && !this.IsGenericTypeDefinition)
1530 throw new InvalidOperationException();
1531
1532 CustomModifiers[] mods = null;
1533 if (requiredCustomModifiers != null || optionalCustomModifiers != null)
1534 {
1535 mods = new CustomModifiers[typeArguments.Length];
1536 for (int i = 0; i < mods.Length; i++)
1537 mods[i] = CustomModifiers.FromReqOpt(Util.NullSafeElementAt(requiredCustomModifiers, i), Util.NullSafeElementAt(optionalCustomModifiers, i));
1538 }
1539
1540 return GenericTypeInstance.Make(this, Util.Copy(typeArguments), mods);
1541 }
1542
1543 public static System.Type __GetSystemType(TypeCode typeCode)
1544 {
1545 return typeCode switch
1546 {
1547 TypeCode.Boolean => typeof(System.Boolean),
1548 TypeCode.Byte => typeof(System.Byte),
1549 TypeCode.Char => typeof(System.Char),
1550 TypeCode.DBNull => typeof(System.DBNull),
1551 TypeCode.DateTime => typeof(System.DateTime),
1552 TypeCode.Decimal => typeof(System.Decimal),
1553 TypeCode.Double => typeof(System.Double),
1554 TypeCode.Empty => null,
1555 TypeCode.Int16 => typeof(System.Int16),
1556 TypeCode.Int32 => typeof(System.Int32),
1557 TypeCode.Int64 => typeof(System.Int64),
1558 TypeCode.Object => typeof(System.Object),
1559 TypeCode.SByte => typeof(System.SByte),
1560 TypeCode.Single => typeof(System.Single),
1561 TypeCode.String => typeof(System.String),
1562 TypeCode.UInt16 => typeof(System.UInt16),
1563 TypeCode.UInt32 => typeof(System.UInt32),
1564 TypeCode.UInt64 => typeof(System.UInt64),
1565 _ => throw new ArgumentOutOfRangeException(),
1566 };
1567 }
1568
1569 public static TypeCode GetTypeCode(Type type)
1570 {
1571 if (type == null)
1572 return TypeCode.Empty;
1573
1574 if (!type.__IsMissing && type.IsEnum)
1575 type = type.GetEnumUnderlyingType();
1576
1577 Universe u = type.Module.Universe;
1578 if (type == u.System_Boolean)
1579 {
1580 return TypeCode.Boolean;
1581 }
1582 else if (type == u.System_Char)
1583 {
1584 return TypeCode.Char;
1585 }
1586 else if (type == u.System_SByte)
1587 {
1588 return TypeCode.SByte;
1589 }
1590 else if (type == u.System_Byte)
1591 {
1592 return TypeCode.Byte;
1593 }
1594 else if (type == u.System_Int16)
1595 {
1596 return TypeCode.Int16;
1597 }
1598 else if (type == u.System_UInt16)
1599 {
1600 return TypeCode.UInt16;
1601 }
1602 else if (type == u.System_Int32)
1603 {
1604 return TypeCode.Int32;
1605 }
1606 else if (type == u.System_UInt32)
1607 {
1608 return TypeCode.UInt32;
1609 }
1610 else if (type == u.System_Int64)
1611 {
1612 return TypeCode.Int64;
1613 }
1614 else if (type == u.System_UInt64)
1615 {
1616 return TypeCode.UInt64;
1617 }
1618 else if (type == u.System_Single)
1619 {
1620 return TypeCode.Single;
1621 }
1622 else if (type == u.System_Double)
1623 {
1624 return TypeCode.Double;
1625 }
1626 else if (type == u.System_DateTime)
1627 {
1628 return TypeCode.DateTime;
1629 }
1630 else if (type == u.System_DBNull)
1631 {
1632 return TypeCode.DBNull;
1633 }
1634 else if (type == u.System_Decimal)
1635 {
1636 return TypeCode.Decimal;
1637 }
1638 else if (type == u.System_String)
1639 {
1640 return TypeCode.String;
1641 }
1642 else if (type.__IsMissing)
1643 {
1644 throw new MissingMemberException(type);
1645 }
1646 else
1647 {
1648 return TypeCode.Object;
1649 }
1650 }
1651
1652 public Assembly Assembly
1653 {
1654 get { return Module.Assembly; }
1655 }
1656
1657 public bool IsAssignableFrom(Type type)
1658 {
1659 if (Equals(type))
1660 {
1661 return true;
1662 }
1663 else if (type == null)
1664 {
1665 return false;
1666 }
1667 else if (this.IsArray && type.IsArray)
1668 {
1669 if (GetArrayRank() != type.GetArrayRank())
1670 {
1671 return false;
1672 }
1673 else if (this.IsSZArray && !type.IsSZArray)
1674 {
1675 return false;
1676 }
1677
1678 var e1 = this.GetElementType();
1679 var e2 = type.GetElementType();
1680 return e1.IsValueType == e2.IsValueType && e1.IsAssignableFrom(e2);
1681 }
1682 else if (this.IsCovariant(type))
1683 {
1684 return true;
1685 }
1686 else if (this.IsSealed)
1687 {
1688 return false;
1689 }
1690 else if (this.IsInterface)
1691 {
1692 foreach (Type iface in type.GetInterfaces())
1693 {
1694 if (this.Equals(iface) || this.IsCovariant(iface))
1695 {
1696 return true;
1697 }
1698 }
1699 return false;
1700 }
1701 else if (type.IsInterface)
1702 {
1703 return this == this.Module.Universe.System_Object;
1704 }
1705 else if (type.IsPointer)
1706 {
1707 return this == this.Module.Universe.System_Object || this == this.Module.Universe.System_ValueType;
1708 }
1709 else
1710 {
1711 return type.IsSubclassOf(this);
1712 }
1713 }
1714
1715 bool IsCovariant(Type other)
1716 {
1717 if (this.IsConstructedGenericType
1718 && other.IsConstructedGenericType
1719 && this.GetGenericTypeDefinition() == other.GetGenericTypeDefinition())
1720 {
1721 Type[] typeParameters = GetGenericTypeDefinition().GetGenericArguments();
1722 for (int i = 0; i < typeParameters.Length; i++)
1723 {
1724 Type t1 = this.GetGenericTypeArgument(i);
1725 Type t2 = other.GetGenericTypeArgument(i);
1726 if (t1.IsValueType != t2.IsValueType)
1727 {
1728 return false;
1729 }
1730 switch (typeParameters[i].GenericParameterAttributes & GenericParameterAttributes.VarianceMask)
1731 {
1732 case GenericParameterAttributes.Covariant:
1733 if (!t1.IsAssignableFrom(t2))
1734 {
1735 return false;
1736 }
1737 break;
1738 case GenericParameterAttributes.Contravariant:
1739 if (!t2.IsAssignableFrom(t1))
1740 {
1741 return false;
1742 }
1743 break;
1744 case GenericParameterAttributes.None:
1745 if (t1 != t2)
1746 {
1747 return false;
1748 }
1749 break;
1750 }
1751 }
1752 return true;
1753 }
1754 return false;
1755 }
1756
1757 public bool IsSubclassOf(Type type)
1758 {
1759 Type thisType = this.BaseType;
1760 while (thisType != null)
1761 {
1762 if (thisType.Equals(type))
1763 return true;
1764
1765 thisType = thisType.BaseType;
1766 }
1767 return false;
1768 }
1769
1778 bool IsDirectlyImplementedInterface(Type interfaceType)
1779 {
1780 foreach (var iface in __GetDeclaredInterfaces())
1781 if (interfaceType.IsAssignableFrom(iface))
1782 return true;
1783
1784 return false;
1785 }
1786
1787 public InterfaceMapping GetInterfaceMap(Type interfaceType)
1788 {
1789 CheckBaked();
1790
1791 var map = new InterfaceMapping();
1792 map.InterfaceMethods = interfaceType.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
1793 map.InterfaceType = interfaceType;
1794 map.TargetMethods = new MethodInfo[map.InterfaceMethods.Length];
1795 map.TargetType = this;
1796 FillInInterfaceMethods(interfaceType, map.InterfaceMethods, map.TargetMethods);
1797 return map;
1798 }
1799
1800 void FillInInterfaceMethods(Type interfaceType, MethodInfo[] interfaceMethods, MethodInfo[] targetMethods)
1801 {
1802 FillInExplicitInterfaceMethods(interfaceMethods, targetMethods);
1803
1804 var direct = IsDirectlyImplementedInterface(interfaceType);
1805 if (direct)
1806 FillInImplicitInterfaceMethods(interfaceMethods, targetMethods);
1807
1808 var baseType = BaseType;
1809 if (baseType != null)
1810 {
1811 baseType.FillInInterfaceMethods(interfaceType, interfaceMethods, targetMethods);
1812 ReplaceOverriddenMethods(targetMethods);
1813 }
1814
1815 if (direct)
1816 for (var type = BaseType; type != null && type.Module == Module; type = type.BaseType)
1817 type.FillInImplicitInterfaceMethods(interfaceMethods, targetMethods);
1818 }
1819
1820 void FillInImplicitInterfaceMethods(MethodInfo[] interfaceMethods, MethodInfo[] targetMethods)
1821 {
1822 MethodBase[] methods = null;
1823
1824 for (int i = 0; i < targetMethods.Length; i++)
1825 {
1826 if (targetMethods[i] == null)
1827 {
1828 methods ??= __GetDeclaredMethods();
1829
1830 for (int j = 0; j < methods.Length; j++)
1831 {
1832 if (methods[j].IsVirtual && methods[j].Name == interfaceMethods[i].Name && methods[j].MethodSignature.Equals(interfaceMethods[i].MethodSignature))
1833 {
1834 targetMethods[i] = (MethodInfo)methods[j];
1835 break;
1836 }
1837 }
1838 }
1839 }
1840 }
1841
1842 void ReplaceOverriddenMethods(MethodInfo[] baseMethods)
1843 {
1844 var impl = __GetMethodImplMap();
1845 for (int i = 0; i < baseMethods.Length; i++)
1846 {
1847 if (baseMethods[i] != null && !baseMethods[i].IsFinal)
1848 {
1849 var def = baseMethods[i].GetBaseDefinition();
1850 for (int j = 0; j < impl.MethodDeclarations.Length; j++)
1851 {
1852 for (int k = 0; k < impl.MethodDeclarations[j].Length; k++)
1853 {
1854 if (impl.MethodDeclarations[j][k].GetBaseDefinition() == def)
1855 {
1856 baseMethods[i] = impl.MethodBodies[j];
1857 goto next;
1858 }
1859 }
1860 }
1861
1862 var candidate = FindMethod(def.Name, def.MethodSignature) as MethodInfo;
1863 if (candidate != null && candidate.IsVirtual && !candidate.IsNewSlot)
1864 baseMethods[i] = candidate;
1865 }
1866 next:;
1867 }
1868 }
1869
1870 internal void FillInExplicitInterfaceMethods(MethodInfo[] interfaceMethods, MethodInfo[] targetMethods)
1871 {
1872 var impl = __GetMethodImplMap();
1873 for (int i = 0; i < impl.MethodDeclarations.Length; i++)
1874 {
1875 for (int j = 0; j < impl.MethodDeclarations[i].Length; j++)
1876 {
1877 int index = Array.IndexOf(interfaceMethods, impl.MethodDeclarations[i][j]);
1878 if (index != -1 && targetMethods[index] == null)
1879 targetMethods[index] = impl.MethodBodies[i];
1880 }
1881 }
1882 }
1883
1884 Type IGenericContext.GetGenericTypeArgument(int index)
1885 {
1886 return GetGenericTypeArgument(index);
1887 }
1888
1889 Type IGenericContext.GetGenericMethodArgument(int index)
1890 {
1891 throw new BadImageFormatException();
1892 }
1893
1894 Type IGenericBinder.BindTypeParameter(Type type)
1895 {
1896 return GetGenericTypeArgument(type.GenericParameterPosition);
1897 }
1898
1899 Type IGenericBinder.BindMethodParameter(Type type)
1900 {
1901 throw new BadImageFormatException();
1902 }
1903
1904 internal virtual Type BindTypeParameters(IGenericBinder binder)
1905 {
1906 if (IsGenericTypeDefinition)
1907 {
1908 var args = GetGenericArguments();
1909 Type.InplaceBindTypeParameters(binder, args);
1910 return GenericTypeInstance.Make(this, args, null);
1911 }
1912 else
1913 {
1914 return this;
1915 }
1916 }
1917
1918 static void InplaceBindTypeParameters(IGenericBinder binder, Type[] types)
1919 {
1920 for (int i = 0; i < types.Length; i++)
1921 types[i] = types[i].BindTypeParameters(binder);
1922 }
1923
1924 internal virtual MethodBase FindMethod(string name, MethodSignature signature)
1925 {
1926 foreach (var method in __GetDeclaredMethods())
1927 if (method.Name == name && method.MethodSignature.Equals(signature))
1928 return method;
1929
1930 return null;
1931 }
1932
1933 internal virtual FieldInfo FindField(string name, FieldSignature signature)
1934 {
1935 foreach (var field in __GetDeclaredFields())
1936 if (field.Name == name && field.FieldSignature.Equals(signature))
1937 return field;
1938
1939 return null;
1940 }
1941
1942 internal bool IsAllowMultipleCustomAttribute
1943 {
1944 get
1945 {
1946 var cad = CustomAttributeData.__GetCustomAttributes(this, this.Module.Universe.System_AttributeUsageAttribute, false);
1947 if (cad.Count == 1)
1948 foreach (CustomAttributeNamedArgument arg in cad[0].NamedArguments)
1949 if (arg.MemberInfo.Name == "AllowMultiple")
1950 return (bool)arg.TypedValue.Value;
1951
1952 return false;
1953 }
1954 }
1955
1956 internal Type MarkNotValueType()
1957 {
1958 typeFlags |= TypeFlags.NotValueType;
1959 return this;
1960 }
1961
1962 internal Type MarkValueType()
1963 {
1964 typeFlags |= TypeFlags.ValueType;
1965 return this;
1966 }
1967
1968 internal ConstructorInfo GetPseudoCustomAttributeConstructor(params Type[] parameterTypes)
1969 {
1970 var u = Module.Universe;
1971 var methodSig = MethodSignature.MakeFromBuilder(u.System_Void, parameterTypes, new PackedCustomModifiers(), CallingConventions.Standard | CallingConventions.HasThis, 0);
1972 var mb = FindMethod(".ctor", methodSig) ?? u.GetMissingMethodOrThrow(null, this, ".ctor", methodSig);
1973 return (ConstructorInfo)mb;
1974 }
1975
1976 public MethodBase __CreateMissingMethod(string name, CallingConventions callingConvention, Type returnType, CustomModifiers returnTypeCustomModifiers, Type[] parameterTypes, CustomModifiers[] parameterTypeCustomModifiers)
1977 {
1978 return CreateMissingMethod(name, callingConvention, returnType, parameterTypes, PackedCustomModifiers.CreateFromExternal(returnTypeCustomModifiers, parameterTypeCustomModifiers, parameterTypes.Length));
1979 }
1980
1981 MethodBase CreateMissingMethod(string name, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, PackedCustomModifiers customModifiers)
1982 {
1983 var sig = new MethodSignature(returnType ?? Module.Universe.System_Void, Util.Copy(parameterTypes), customModifiers, callingConvention, 0);
1984 var method = new MissingMethod(this, name, sig);
1985
1986 if (name == ".ctor" || name == ".cctor")
1987 return new ConstructorInfoImpl(method);
1988
1989 return method;
1990 }
1991
1992 [Obsolete("Please use __CreateMissingMethod(string, CallingConventions, Type, CustomModifiers, Type[], CustomModifiers[]) instead")]
1993 public MethodBase __CreateMissingMethod(string name, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
1994 {
1995 return CreateMissingMethod(name, callingConvention, returnType, parameterTypes, PackedCustomModifiers.CreateFromExternal(returnTypeOptionalCustomModifiers, returnTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, parameterTypeRequiredCustomModifiers, parameterTypes.Length));
1996 }
1997
1998 public FieldInfo __CreateMissingField(string name, Type fieldType, CustomModifiers customModifiers)
1999 {
2000 return new MissingField(this, name, FieldSignature.Create(fieldType, customModifiers));
2001 }
2002
2003 [Obsolete("Please use __CreateMissingField(string, Type, CustomModifiers) instead")]
2004 public FieldInfo __CreateMissingField(string name, Type fieldType, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
2005 {
2006 return __CreateMissingField(name, fieldType, CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers));
2007 }
2008
2009 public PropertyInfo __CreateMissingProperty(string name, CallingConventions callingConvention, Type propertyType, CustomModifiers propertyTypeCustomModifiers, Type[] parameterTypes, CustomModifiers[] parameterTypeCustomModifiers)
2010 {
2011 var sig = PropertySignature.Create(callingConvention, propertyType, parameterTypes, PackedCustomModifiers.CreateFromExternal(propertyTypeCustomModifiers, parameterTypeCustomModifiers, Util.NullSafeLength(parameterTypes)));
2012 return new MissingProperty(this, name, sig);
2013 }
2014
2015 internal virtual Type SetMetadataTokenForMissing(int token, int flags)
2016 {
2017 return this;
2018 }
2019
2020 internal virtual Type SetCyclicTypeForwarder()
2021 {
2022 return this;
2023 }
2024
2025 internal virtual Type SetCyclicTypeSpec()
2026 {
2027 return this;
2028 }
2029
2030 protected void MarkKnownType(string typeNamespace, string typeName)
2031 {
2032 // we assume that mscorlib won't have nested types with these names,
2033 // so we don't check that we're not a nested type
2034 if (typeNamespace == "System")
2035 {
2036 switch (typeName)
2037 {
2038 case "Boolean":
2039 case "Char":
2040 case "Object":
2041 case "String":
2042 case "Single":
2043 case "Double":
2044 case "SByte":
2045 case "Int16":
2046 case "Int32":
2047 case "Int64":
2048 case "IntPtr":
2049 case "UIntPtr":
2050 case "TypedReference":
2051 case "Byte":
2052 case "UInt16":
2053 case "UInt32":
2054 case "UInt64":
2055 case "Void":
2056 typeFlags |= TypeFlags.PotentialBuiltIn;
2057 break;
2058 case "Enum":
2059 case "ValueType":
2060 typeFlags |= TypeFlags.PotentialEnumOrValueType;
2061 break;
2062 }
2063 }
2064 }
2065
2066 bool ResolvePotentialEnumOrValueType()
2067 {
2068 if (Assembly == Universe.CoreLib || Assembly.GetName().Name.Equals("mscorlib", StringComparison.OrdinalIgnoreCase)
2069 // check if mscorlib forwards the type (.NETCore profile reference mscorlib forwards System.Enum and System.ValueType to System.Runtime.dll)
2070 || Universe.CoreLib.FindType(TypeName) == this)
2071 {
2072 typeFlags = (typeFlags & ~TypeFlags.PotentialEnumOrValueType) | TypeFlags.EnumOrValueType;
2073 return true;
2074 }
2075 else
2076 {
2077 typeFlags &= ~TypeFlags.PotentialEnumOrValueType;
2078 return false;
2079 }
2080 }
2081
2082 internal bool IsEnumOrValueType
2083 {
2084 get
2085 {
2086 return (typeFlags & (TypeFlags.EnumOrValueType | TypeFlags.PotentialEnumOrValueType)) != 0
2087 && ((typeFlags & TypeFlags.EnumOrValueType) != 0 || ResolvePotentialEnumOrValueType());
2088 }
2089 }
2090
2091 internal virtual Universe Universe
2092 {
2093 get { return Module.Universe; }
2094 }
2095
2096 internal sealed override bool BindingFlagsMatch(BindingFlags flags)
2097 {
2098 return BindingFlagsMatch(IsNestedPublic, flags, BindingFlags.Public, BindingFlags.NonPublic);
2099 }
2100
2101 internal sealed override MemberInfo SetReflectedType(Type type)
2102 {
2103 throw new InvalidOperationException();
2104 }
2105
2106 internal override int GetCurrentToken()
2107 {
2108 return MetadataToken;
2109 }
2110
2111 internal sealed override List<CustomAttributeData> GetPseudoCustomAttributes(Type attributeType)
2112 {
2113 // types don't have pseudo custom attributes
2114 return null;
2115 }
2116
2117 // in .NET this is an extension method, but we target .NET 2.0, so we have an instance method
2118 public TypeInfo GetTypeInfo()
2119 {
2120 return this as TypeInfo ?? throw new MissingMemberException(this);
2121 }
2122
2123 public virtual bool __IsTypeForwarder
2124 {
2125 get { return false; }
2126 }
2127
2128 public virtual bool __IsCyclicTypeForwarder
2129 {
2130 get { return false; }
2131 }
2132
2133 public virtual bool __IsCyclicTypeSpec
2134 {
2135 get { return false; }
2136 }
2137
2138 }
2139
2140}
IKVM.Reflection.Module Module
IKVM.Reflection.Type Type
IKVM.Reflection.Assembly Assembly
IKVM.Reflection.ConstructorInfo ConstructorInfo
IKVM.Reflection.EventInfo EventInfo
IKVM.Reflection.FieldInfo FieldInfo
IKVM.Reflection.MemberInfo MemberInfo
IKVM.Reflection.PropertyInfo PropertyInfo
IKVM.Reflection.MethodInfo MethodInfo
IKVM.Reflection.MethodBase MethodBase
global::java.lang.invoke.LambdaForm.Name Name