2 Copyright (C) 2009-2012 Jeroen Frijters
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.
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:
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.
25 using System.Runtime.InteropServices;
27 using System.Collections.Generic;
28 using IKVM.Reflection.Emit;
30 namespace IKVM.Reflection
32 interface IGenericContext
34 Type GetGenericTypeArgument(int index);
35 Type GetGenericMethodArgument(int index);
38 interface IGenericBinder
40 Type BindTypeParameter(Type type);
41 Type BindMethodParameter(Type type);
44 public abstract class Type : MemberInfo, IGenericContext, IGenericBinder
46 public static readonly Type[] EmptyTypes = Empty<Type>.Array;
47 protected readonly Type underlyingType;
48 protected TypeFlags typeFlags;
51 protected enum TypeFlags
53 // for use by TypeBuilder or TypeDefImpl
54 IsGenericTypeDefinition = 1,
56 // for use by TypeBuilder
60 // for use by MissingType
64 // for use by TypeDefImpl, TypeBuilder or MissingType
65 PotentialEnumOrValueType = 32,
68 // for use by TypeDefImpl
69 NotGenericTypeDefinition = 128,
72 // prevent subclassing by outsiders
75 this.underlyingType = this;
78 internal Type(Type underlyingType)
80 System.Diagnostics.Debug.Assert(underlyingType.underlyingType == underlyingType);
81 this.underlyingType = underlyingType;
82 this.typeFlags = underlyingType.typeFlags;
85 public static Binder DefaultBinder
87 get { return new DefaultBinder(); }
90 public sealed override MemberTypes MemberType
92 get { return IsNested ? MemberTypes.NestedType : MemberTypes.TypeInfo; }
95 public virtual string AssemblyQualifiedName
97 // NOTE the assembly name is not escaped here, only when used in a generic type instantiation
98 get { return this.FullName + ", " + this.Assembly.FullName; }
101 public abstract Type BaseType
106 public abstract TypeAttributes Attributes
111 public virtual Type GetElementType()
116 internal virtual void CheckBaked()
120 public virtual Type[] __GetDeclaredTypes()
122 return Type.EmptyTypes;
125 public virtual Type[] __GetDeclaredInterfaces()
127 return Type.EmptyTypes;
130 public virtual MethodBase[] __GetDeclaredMethods()
132 return Empty<MethodBase>.Array;
135 public virtual __MethodImplMap __GetMethodImplMap()
137 throw new NotSupportedException();
140 public virtual FieldInfo[] __GetDeclaredFields()
142 return Empty<FieldInfo>.Array;
145 public virtual EventInfo[] __GetDeclaredEvents()
147 return Empty<EventInfo>.Array;
150 public virtual PropertyInfo[] __GetDeclaredProperties()
152 return Empty<PropertyInfo>.Array;
155 public virtual CustomModifiers __GetCustomModifiers()
157 return new CustomModifiers();
160 [Obsolete("Please use __GetCustomModifiers() instead.")]
161 public Type[] __GetRequiredCustomModifiers()
163 return __GetCustomModifiers().GetRequired();
166 [Obsolete("Please use __GetCustomModifiers() instead.")]
167 public Type[] __GetOptionalCustomModifiers()
169 return __GetCustomModifiers().GetOptional();
172 public virtual __StandAloneMethodSig __MethodSignature
174 get { throw new InvalidOperationException(); }
177 public virtual bool HasElementType
179 get { return false; }
182 public virtual bool IsArray
184 get { return false; }
187 public virtual bool __IsVector
189 get { return false; }
192 public virtual bool IsByRef
194 get { return false; }
197 public virtual bool IsPointer
199 get { return false; }
202 public virtual bool __IsFunctionPointer
204 get { return false; }
207 public virtual bool IsValueType
211 Type baseType = this.BaseType;
212 return baseType != null
213 && baseType.IsEnumOrValueType
214 && !this.IsEnumOrValueType;
218 public virtual bool IsGenericParameter
220 get { return false; }
223 public virtual int GenericParameterPosition
225 get { throw new NotSupportedException(); }
228 public virtual MethodBase DeclaringMethod
233 public Type UnderlyingSystemType
235 get { return underlyingType; }
238 public override Type DeclaringType
243 public virtual string __Name
245 get { throw new InvalidOperationException(); }
248 public virtual string __Namespace
250 get { throw new InvalidOperationException(); }
253 public abstract override string Name
258 public virtual string Namespace
264 return DeclaringType.Namespace;
270 internal virtual int GetModuleBuilderToken()
272 throw new InvalidOperationException();
275 public static bool operator ==(Type t1, Type t2)
277 // Casting to object results in smaller code than calling ReferenceEquals and makes
278 // this method more likely to be inlined.
279 // On CLR v2 x86, microbenchmarks show this to be faster than calling ReferenceEquals.
280 return (object)t1 == (object)t2
281 || ((object)t1 != null && (object)t2 != null && (object)t1.underlyingType == (object)t2.underlyingType);
284 public static bool operator !=(Type t1, Type t2)
289 public bool Equals(Type type)
294 public override bool Equals(object obj)
296 return Equals(obj as Type);
299 public override int GetHashCode()
301 Type type = this.UnderlyingSystemType;
302 return ReferenceEquals(type, this) ? base.GetHashCode() : type.GetHashCode();
305 public virtual Type[] GetGenericArguments()
307 return Type.EmptyTypes;
310 public virtual CustomModifiers[] __GetGenericArgumentsCustomModifiers()
312 return Empty<CustomModifiers>.Array;
315 [Obsolete("Please use __GetGenericArgumentsCustomModifiers() instead")]
316 public Type[][] __GetGenericArgumentsRequiredCustomModifiers()
318 CustomModifiers[] customModifiers = __GetGenericArgumentsCustomModifiers();
319 Type[][] array = new Type[customModifiers.Length][];
320 for (int i = 0; i < array.Length; i++)
322 array[i] = customModifiers[i].GetRequired();
327 [Obsolete("Please use __GetGenericArgumentsCustomModifiers() instead")]
328 public Type[][] __GetGenericArgumentsOptionalCustomModifiers()
330 CustomModifiers[] customModifiers = __GetGenericArgumentsCustomModifiers();
331 Type[][] array = new Type[customModifiers.Length][];
332 for (int i = 0; i < array.Length; i++)
334 array[i] = customModifiers[i].GetOptional();
339 public virtual Type GetGenericTypeDefinition()
341 throw new InvalidOperationException();
344 public virtual StructLayoutAttribute StructLayoutAttribute
349 public virtual bool __GetLayout(out int packingSize, out int typeSize)
356 public virtual bool IsGenericType
358 get { return false; }
361 public virtual bool IsGenericTypeDefinition
363 get { return false; }
367 public virtual bool IsConstructedGenericType
369 get { return false; }
372 public virtual bool ContainsGenericParameters
376 if (this.IsGenericParameter)
380 foreach (Type arg in this.GetGenericArguments())
382 if (arg.ContainsGenericParameters)
391 public virtual Type[] GetGenericParameterConstraints()
393 throw new InvalidOperationException();
396 public virtual GenericParameterAttributes GenericParameterAttributes
398 get { throw new InvalidOperationException(); }
401 public virtual int GetArrayRank()
403 throw new NotSupportedException();
406 public virtual int[] __GetArraySizes()
408 throw new NotSupportedException();
411 public virtual int[] __GetArrayLowerBounds()
413 throw new NotSupportedException();
417 public virtual Type GetEnumUnderlyingType()
421 throw new ArgumentException();
424 return GetEnumUnderlyingTypeImpl();
427 internal Type GetEnumUnderlyingTypeImpl()
429 foreach (FieldInfo field in __GetDeclaredFields())
433 // the CLR assumes that an enum has only one instance field, so we can do the same
434 return field.FieldType;
437 throw new InvalidOperationException();
440 public override string ToString()
445 public abstract string FullName
450 protected string GetFullName()
452 string ns = TypeNameParser.Escape(this.__Namespace);
453 Type decl = this.DeclaringType;
462 return ns + "." + this.Name;
469 return decl.FullName + "+" + this.Name;
473 return decl.FullName + "+" + ns + "." + this.Name;
478 internal virtual bool IsModulePseudoType
480 get { return false; }
483 internal virtual Type GetGenericTypeArgument(int index)
485 throw new InvalidOperationException();
488 public MemberInfo[] GetDefaultMembers()
490 Type defaultMemberAttribute = this.Module.universe.Import(typeof(System.Reflection.DefaultMemberAttribute));
491 foreach (CustomAttributeData cad in CustomAttributeData.GetCustomAttributes(this))
493 if (cad.Constructor.DeclaringType.Equals(defaultMemberAttribute))
495 return GetMember((string)cad.ConstructorArguments[0].Value);
498 return Empty<MemberInfo>.Array;
501 public MemberInfo[] GetMember(string name)
503 return GetMember(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
506 public MemberInfo[] GetMember(string name, BindingFlags bindingAttr)
508 return GetMember(name, MemberTypes.All, bindingAttr);
511 public MemberInfo[] GetMembers()
513 return GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
516 public MemberInfo[] GetMembers(BindingFlags bindingAttr)
518 List<MemberInfo> members = new List<MemberInfo>();
519 members.AddRange(GetConstructors(bindingAttr));
520 members.AddRange(GetMethods(bindingAttr));
521 members.AddRange(GetFields(bindingAttr));
522 members.AddRange(GetProperties(bindingAttr));
523 members.AddRange(GetEvents(bindingAttr));
524 members.AddRange(GetNestedTypes(bindingAttr));
525 return members.ToArray();
528 public MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr)
531 if ((bindingAttr & BindingFlags.IgnoreCase) != 0)
533 name = name.ToLowerInvariant();
534 filter = delegate(MemberInfo member, object filterCriteria) { return member.Name.ToLowerInvariant().Equals(filterCriteria); };
538 filter = delegate(MemberInfo member, object filterCriteria) { return member.Name.Equals(filterCriteria); };
540 return FindMembers(type, bindingAttr, filter, name);
543 private static void AddMembers(List<MemberInfo> list, MemberFilter filter, object filterCriteria, MemberInfo[] members)
545 foreach (MemberInfo member in members)
547 if (filter == null || filter(member, filterCriteria))
554 public MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria)
556 List<MemberInfo> members = new List<MemberInfo>();
557 if ((memberType & MemberTypes.Constructor) != 0)
559 AddMembers(members, filter, filterCriteria, GetConstructors(bindingAttr));
561 if ((memberType & MemberTypes.Method) != 0)
563 AddMembers(members, filter, filterCriteria, GetMethods(bindingAttr));
565 if ((memberType & MemberTypes.Field) != 0)
567 AddMembers(members, filter, filterCriteria, GetFields(bindingAttr));
569 if ((memberType & MemberTypes.Property) != 0)
571 AddMembers(members, filter, filterCriteria, GetProperties(bindingAttr));
573 if ((memberType & MemberTypes.Event) != 0)
575 AddMembers(members, filter, filterCriteria, GetEvents(bindingAttr));
577 if ((memberType & MemberTypes.NestedType) != 0)
579 AddMembers(members, filter, filterCriteria, GetNestedTypes(bindingAttr));
581 return members.ToArray();
584 private MemberInfo[] GetMembers<T>()
586 if (typeof(T) == typeof(ConstructorInfo) || typeof(T) == typeof(MethodInfo))
588 return __GetDeclaredMethods();
590 else if (typeof(T) == typeof(FieldInfo))
592 return __GetDeclaredFields();
594 else if (typeof(T) == typeof(PropertyInfo))
596 return __GetDeclaredProperties();
598 else if (typeof(T) == typeof(EventInfo))
600 return __GetDeclaredEvents();
602 else if (typeof(T) == typeof(Type))
604 return __GetDeclaredTypes();
608 throw new InvalidOperationException();
612 private T[] GetMembers<T>(BindingFlags flags)
616 List<T> list = new List<T>();
617 foreach (MemberInfo member in GetMembers<T>())
619 if (member is T && member.BindingFlagsMatch(flags))
624 if ((flags & BindingFlags.DeclaredOnly) == 0)
626 for (Type type = this.BaseType; type != null; type = type.BaseType)
629 foreach (MemberInfo member in type.GetMembers<T>())
631 if (member is T && member.BindingFlagsMatchInherited(flags))
633 list.Add((T)member.SetReflectedType(this));
638 return list.ToArray();
641 private T GetMemberByName<T>(string name, BindingFlags flags, Predicate<T> filter)
645 if ((flags & BindingFlags.IgnoreCase) != 0)
647 name = name.ToLowerInvariant();
650 foreach (MemberInfo member in GetMembers<T>())
652 if (member is T && member.BindingFlagsMatch(flags))
654 string memberName = member.Name;
655 if ((flags & BindingFlags.IgnoreCase) != 0)
657 memberName = memberName.ToLowerInvariant();
659 if (memberName == name && (filter == null || filter((T)member)))
663 throw new AmbiguousMatchException();
669 if ((flags & BindingFlags.DeclaredOnly) == 0)
671 for (Type type = this.BaseType; (found == null || typeof(T) == typeof(MethodInfo)) && type != null; type = type.BaseType)
674 foreach (MemberInfo member in type.GetMembers<T>())
676 if (member is T && member.BindingFlagsMatchInherited(flags))
678 string memberName = member.Name;
679 if ((flags & BindingFlags.IgnoreCase) != 0)
681 memberName = memberName.ToLowerInvariant();
683 if (memberName == name && (filter == null || filter((T)member)))
688 // TODO does this depend on HideBySig vs HideByName?
689 if ((mi = found as MethodInfo) != null
690 && mi.MethodSignature.MatchParameterTypes(((MethodBase)member).MethodSignature))
694 throw new AmbiguousMatchException();
696 found = (T)member.SetReflectedType(this);
705 private T GetMemberByName<T>(string name, BindingFlags flags)
708 return GetMemberByName<T>(name, flags, null);
711 public EventInfo GetEvent(string name)
713 return GetEvent(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
716 public EventInfo GetEvent(string name, BindingFlags bindingAttr)
718 return GetMemberByName<EventInfo>(name, bindingAttr);
721 public EventInfo[] GetEvents()
723 return GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
726 public EventInfo[] GetEvents(BindingFlags bindingAttr)
728 return GetMembers<EventInfo>(bindingAttr);
731 public FieldInfo GetField(string name)
733 return GetField(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
736 public FieldInfo GetField(string name, BindingFlags bindingAttr)
738 return GetMemberByName<FieldInfo>(name, bindingAttr);
741 public FieldInfo[] GetFields()
743 return GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
746 public FieldInfo[] GetFields(BindingFlags bindingAttr)
748 return GetMembers<FieldInfo>(bindingAttr);
751 public Type[] GetInterfaces()
753 List<Type> list = new List<Type>();
754 for (Type type = this; type != null; type = type.BaseType)
756 AddInterfaces(list, type);
758 return list.ToArray();
761 private static void AddInterfaces(List<Type> list, Type type)
763 foreach (Type iface in type.__GetDeclaredInterfaces())
765 if (!list.Contains(iface))
768 AddInterfaces(list, iface);
773 public MethodInfo[] GetMethods(BindingFlags bindingAttr)
776 List<MethodInfo> list = new List<MethodInfo>();
777 foreach (MethodBase mb in __GetDeclaredMethods())
779 MethodInfo mi = mb as MethodInfo;
780 if (mi != null && mi.BindingFlagsMatch(bindingAttr))
785 if ((bindingAttr & BindingFlags.DeclaredOnly) == 0)
787 List<MethodInfo> baseMethods = new List<MethodInfo>();
788 foreach (MethodInfo mi in list)
792 baseMethods.Add(mi.GetBaseDefinition());
795 for (Type type = this.BaseType; type != null; type = type.BaseType)
798 foreach (MethodBase mb in type.__GetDeclaredMethods())
800 MethodInfo mi = mb as MethodInfo;
801 if (mi != null && mi.BindingFlagsMatchInherited(bindingAttr))
805 if (baseMethods == null)
807 baseMethods = new List<MethodInfo>();
809 else if (baseMethods.Contains(mi.GetBaseDefinition()))
813 baseMethods.Add(mi.GetBaseDefinition());
815 list.Add((MethodInfo)mi.SetReflectedType(this));
820 return list.ToArray();
823 public MethodInfo[] GetMethods()
825 return GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
828 public MethodInfo GetMethod(string name)
830 return GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
833 public MethodInfo GetMethod(string name, BindingFlags bindingAttr)
835 return GetMemberByName<MethodInfo>(name, bindingAttr);
838 public MethodInfo GetMethod(string name, Type[] types)
840 return GetMethod(name, types, null);
843 public MethodInfo GetMethod(string name, Type[] types, ParameterModifier[] modifiers)
845 return GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, null, types, modifiers);
848 public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
850 // first we try an exact match and only if that fails we fall back to using the binder
851 return GetMemberByName<MethodInfo>(name, bindingAttr,
852 delegate(MethodInfo method) { return method.MethodSignature.MatchParameterTypes(types); })
853 ?? GetMethodWithBinder<MethodInfo>(name, bindingAttr, binder ?? DefaultBinder, types, modifiers);
856 private T GetMethodWithBinder<T>(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
859 List<MethodBase> list = new List<MethodBase>();
860 GetMemberByName<T>(name, bindingAttr, delegate(T method) {
864 return (T)binder.SelectMethod(bindingAttr, list.ToArray(), types, modifiers);
867 public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
869 // FXBUG callConvention seems to be ignored
870 return GetMethod(name, bindingAttr, binder, types, modifiers);
873 public ConstructorInfo[] GetConstructors()
875 return GetConstructors(BindingFlags.Public | BindingFlags.Instance);
878 public ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
880 return GetMembers<ConstructorInfo>(bindingAttr | BindingFlags.DeclaredOnly);
883 public ConstructorInfo GetConstructor(Type[] types)
885 return GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, CallingConventions.Standard, types, null);
888 public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
890 ConstructorInfo ci1 = null;
891 if ((bindingAttr & BindingFlags.Instance) != 0)
893 ci1 = GetConstructorImpl(ConstructorInfo.ConstructorName, bindingAttr, binder, types, modifiers);
895 if ((bindingAttr & BindingFlags.Static) != 0)
897 ConstructorInfo ci2 = GetConstructorImpl(ConstructorInfo.TypeConstructorName, bindingAttr, binder, types, modifiers);
902 throw new AmbiguousMatchException();
910 private ConstructorInfo GetConstructorImpl(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
912 // first we try an exact match and only if that fails we fall back to using the binder
913 return GetMemberByName<ConstructorInfo>(name, bindingAttr | BindingFlags.DeclaredOnly,
914 delegate(ConstructorInfo ctor) { return ctor.MethodSignature.MatchParameterTypes(types); })
915 ?? GetMethodWithBinder<ConstructorInfo>(name, bindingAttr, binder ?? DefaultBinder, types, modifiers);
918 public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, CallingConventions callingConvention, Type[] types, ParameterModifier[] modifiers)
920 // FXBUG callConvention seems to be ignored
921 return GetConstructor(bindingAttr, binder, types, modifiers);
924 internal Type ResolveNestedType(TypeName typeName)
926 return FindNestedType(typeName) ?? Module.universe.GetMissingTypeOrThrow(Module, this, typeName);
929 // unlike the public API, this takes the namespace and name into account
930 internal virtual Type FindNestedType(TypeName name)
932 foreach (Type type in __GetDeclaredTypes())
934 if (type.__Namespace == name.Namespace && type.__Name == name.Name)
942 internal virtual Type FindNestedTypeIgnoreCase(TypeName lowerCaseName)
944 foreach (Type type in __GetDeclaredTypes())
946 if (new TypeName(type.__Namespace, type.__Name).ToLowerInvariant() == lowerCaseName)
954 public Type GetNestedType(string name)
956 return GetNestedType(name, BindingFlags.Public);
959 public Type GetNestedType(string name, BindingFlags bindingAttr)
961 // FXBUG the namespace is ignored, so we can use GetMemberByName
962 return GetMemberByName<Type>(name, bindingAttr | BindingFlags.DeclaredOnly);
965 public Type[] GetNestedTypes()
967 return GetNestedTypes(BindingFlags.Public);
970 public Type[] GetNestedTypes(BindingFlags bindingAttr)
972 // FXBUG the namespace is ignored, so we can use GetMember
973 return GetMembers<Type>(bindingAttr | BindingFlags.DeclaredOnly);
976 public PropertyInfo[] GetProperties()
978 return GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
981 public PropertyInfo[] GetProperties(BindingFlags bindingAttr)
983 return GetMembers<PropertyInfo>(bindingAttr);
986 public PropertyInfo GetProperty(string name)
988 return GetProperty(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
991 public PropertyInfo GetProperty(string name, BindingFlags bindingAttr)
993 return GetMemberByName<PropertyInfo>(name, bindingAttr);
996 public PropertyInfo GetProperty(string name, Type returnType)
998 const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static;
999 return GetMemberByName<PropertyInfo>(name, flags, delegate(PropertyInfo prop) { return prop.PropertyType.Equals(returnType); })
1000 ?? GetPropertyWithBinder(name, flags, DefaultBinder, returnType, null, null);
1003 public PropertyInfo GetProperty(string name, Type[] types)
1005 const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static;
1006 return GetMemberByName<PropertyInfo>(name, flags, delegate(PropertyInfo prop) { return prop.PropertySignature.MatchParameterTypes(types); })
1007 ?? GetPropertyWithBinder(name, flags, DefaultBinder, null, types, null);
1010 public PropertyInfo GetProperty(string name, Type returnType, Type[] types)
1012 return GetProperty(name, returnType, types, null);
1015 public PropertyInfo GetProperty(string name, Type returnType, Type[] types, ParameterModifier[] modifiers)
1017 return GetProperty(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static, null, returnType, types, modifiers);
1020 public PropertyInfo GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
1022 return GetMemberByName<PropertyInfo>(name, bindingAttr,
1023 delegate(PropertyInfo prop) {
1024 return prop.PropertyType.Equals(returnType) && prop.PropertySignature.MatchParameterTypes(types);
1026 ?? GetPropertyWithBinder(name, bindingAttr, binder ?? DefaultBinder, returnType, types, modifiers);
1029 private PropertyInfo GetPropertyWithBinder(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
1031 List<PropertyInfo> list = new List<PropertyInfo>();
1032 GetMemberByName<PropertyInfo>(name, bindingAttr, delegate(PropertyInfo property) {
1036 return binder.SelectProperty(bindingAttr, list.ToArray(), returnType, types, modifiers);
1039 public Type GetInterface(string name)
1041 return GetInterface(name, false);
1044 public Type GetInterface(string name, bool ignoreCase)
1048 name = name.ToLowerInvariant();
1051 foreach (Type type in GetInterfaces())
1053 string typeName = type.FullName;
1056 typeName = typeName.ToLowerInvariant();
1058 if (typeName == name)
1062 throw new AmbiguousMatchException();
1070 public Type[] FindInterfaces(TypeFilter filter, object filterCriteria)
1072 List<Type> list = new List<Type>();
1073 foreach (Type type in GetInterfaces())
1075 if (filter(type, filterCriteria))
1080 return list.ToArray();
1083 public ConstructorInfo TypeInitializer
1085 get { return GetConstructor(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); }
1088 public bool IsPrimitive
1092 Universe u = this.Universe;
1093 return this == u.System_Boolean
1094 || this == u.System_Byte
1095 || this == u.System_SByte
1096 || this == u.System_Int16
1097 || this == u.System_UInt16
1098 || this == u.System_Int32
1099 || this == u.System_UInt32
1100 || this == u.System_Int64
1101 || this == u.System_UInt64
1102 || this == u.System_IntPtr
1103 || this == u.System_UIntPtr
1104 || this == u.System_Char
1105 || this == u.System_Double
1106 || this == u.System_Single
1115 Type baseType = this.BaseType;
1116 return baseType != null
1117 && baseType.IsEnumOrValueType
1118 && baseType.__Name[0] == 'E';
1122 public bool IsSealed
1124 get { return (Attributes & TypeAttributes.Sealed) != 0; }
1127 public bool IsAbstract
1129 get { return (Attributes & TypeAttributes.Abstract) != 0; }
1132 private bool CheckVisibility(TypeAttributes access)
1134 return (Attributes & TypeAttributes.VisibilityMask) == access;
1137 public bool IsPublic
1139 get { return CheckVisibility(TypeAttributes.Public); }
1142 public bool IsNestedPublic
1144 get { return CheckVisibility(TypeAttributes.NestedPublic); }
1147 public bool IsNestedPrivate
1149 get { return CheckVisibility(TypeAttributes.NestedPrivate); }
1152 public bool IsNestedFamily
1154 get { return CheckVisibility(TypeAttributes.NestedFamily); }
1157 public bool IsNestedAssembly
1159 get { return CheckVisibility(TypeAttributes.NestedAssembly); }
1162 public bool IsNestedFamANDAssem
1164 get { return CheckVisibility(TypeAttributes.NestedFamANDAssem); }
1167 public bool IsNestedFamORAssem
1169 get { return CheckVisibility(TypeAttributes.NestedFamORAssem); }
1172 public bool IsNotPublic
1174 get { return CheckVisibility(TypeAttributes.NotPublic); }
1177 public bool IsImport
1179 get { return (Attributes & TypeAttributes.Import) != 0; }
1182 public bool IsCOMObject
1184 get { return IsClass && IsImport; }
1187 public bool IsContextful
1189 get { return IsSubclassOf(this.Module.universe.Import(typeof(ContextBoundObject))); }
1192 public bool IsMarshalByRef
1194 get { return IsSubclassOf(this.Module.universe.Import(typeof(MarshalByRefObject))); }
1197 public virtual bool IsVisible
1199 get { return IsPublic || (IsNestedPublic && this.DeclaringType.IsVisible); }
1202 public bool IsAnsiClass
1204 get { return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass; }
1207 public bool IsUnicodeClass
1209 get { return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass; }
1212 public bool IsAutoClass
1214 get { return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass; }
1217 public bool IsAutoLayout
1219 get { return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout; }
1222 public bool IsLayoutSequential
1224 get { return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout; }
1227 public bool IsExplicitLayout
1229 get { return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout; }
1232 public bool IsSpecialName
1234 get { return (Attributes & TypeAttributes.SpecialName) != 0; }
1237 public bool IsSerializable
1239 get { return (Attributes & TypeAttributes.Serializable) != 0; }
1244 get { return !IsInterface && !IsValueType; }
1247 public bool IsInterface
1249 get { return (Attributes & TypeAttributes.Interface) != 0; }
1252 public bool IsNested
1254 // FXBUG we check the declaring type (like .NET) and this results
1255 // in IsNested returning true for a generic type parameter
1256 get { return this.DeclaringType != null; }
1259 public virtual bool __ContainsMissingType
1263 if (this.__IsMissing)
1267 foreach (Type arg in this.GetGenericArguments())
1269 if (arg.__ContainsMissingType)
1278 public Type MakeArrayType()
1280 return ArrayType.Make(this, new CustomModifiers());
1283 public Type __MakeArrayType(CustomModifiers customModifiers)
1285 return ArrayType.Make(this, customModifiers);
1288 [Obsolete("Please use __MakeArrayType(CustomModifiers) instead.")]
1289 public Type __MakeArrayType(Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1291 return __MakeArrayType(CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers));
1294 public Type MakeArrayType(int rank)
1296 return __MakeArrayType(rank, new CustomModifiers());
1299 public Type __MakeArrayType(int rank, CustomModifiers customModifiers)
1301 return MultiArrayType.Make(this, rank, Empty<int>.Array, new int[rank], customModifiers);
1304 [Obsolete("Please use __MakeArrayType(int, CustomModifiers) instead.")]
1305 public Type __MakeArrayType(int rank, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1307 return __MakeArrayType(rank, CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers));
1310 public Type __MakeArrayType(int rank, int[] sizes, int[] lobounds, CustomModifiers customModifiers)
1312 return MultiArrayType.Make(this, rank, sizes ?? Empty<int>.Array, lobounds ?? Empty<int>.Array, customModifiers);
1315 [Obsolete("Please use __MakeArrayType(int, int[], int[], CustomModifiers) instead.")]
1316 public Type __MakeArrayType(int rank, int[] sizes, int[] lobounds, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1318 return __MakeArrayType(rank, sizes, lobounds, CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers));
1321 public Type MakeByRefType()
1323 return ByRefType.Make(this, new CustomModifiers());
1326 public Type __MakeByRefType(CustomModifiers customModifiers)
1328 return ByRefType.Make(this, customModifiers);
1331 [Obsolete("Please use __MakeByRefType(CustomModifiers) instead.")]
1332 public Type __MakeByRefType(Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1334 return __MakeByRefType(CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers));
1337 public Type MakePointerType()
1339 return PointerType.Make(this, new CustomModifiers());
1342 public Type __MakePointerType(CustomModifiers customModifiers)
1344 return PointerType.Make(this, customModifiers);
1347 [Obsolete("Please use __MakeByRefType(CustomModifiers) instead.")]
1348 public Type __MakePointerType(Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1350 return __MakePointerType(CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers));
1353 public Type MakeGenericType(params Type[] typeArguments)
1355 return __MakeGenericType(typeArguments, null);
1358 public Type __MakeGenericType(Type[] typeArguments, CustomModifiers[] customModifiers)
1360 if (!this.__IsMissing && !this.IsGenericTypeDefinition)
1362 throw new InvalidOperationException();
1364 return GenericTypeInstance.Make(this, Util.Copy(typeArguments), customModifiers == null ? null : (CustomModifiers[])customModifiers.Clone());
1367 [Obsolete("Please use __MakeGenericType(Type[], CustomModifiers[]) instead.")]
1368 public Type __MakeGenericType(Type[] typeArguments, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
1370 if (!this.__IsMissing && !this.IsGenericTypeDefinition)
1372 throw new InvalidOperationException();
1374 CustomModifiers[] mods = null;
1375 if (requiredCustomModifiers != null || optionalCustomModifiers != null)
1377 mods = new CustomModifiers[typeArguments.Length];
1378 for (int i = 0; i < mods.Length; i++)
1380 mods[i] = CustomModifiers.FromReqOpt(Util.NullSafeElementAt(requiredCustomModifiers, i), Util.NullSafeElementAt(optionalCustomModifiers, i));
1383 return GenericTypeInstance.Make(this, Util.Copy(typeArguments), mods);
1386 public static System.Type __GetSystemType(TypeCode typeCode)
1390 case TypeCode.Boolean:
1391 return typeof(System.Boolean);
1393 return typeof(System.Byte);
1395 return typeof(System.Char);
1396 case TypeCode.DBNull:
1397 return typeof(System.DBNull);
1398 case TypeCode.DateTime:
1399 return typeof(System.DateTime);
1400 case TypeCode.Decimal:
1401 return typeof(System.Decimal);
1402 case TypeCode.Double:
1403 return typeof(System.Double);
1404 case TypeCode.Empty:
1406 case TypeCode.Int16:
1407 return typeof(System.Int16);
1408 case TypeCode.Int32:
1409 return typeof(System.Int32);
1410 case TypeCode.Int64:
1411 return typeof(System.Int64);
1412 case TypeCode.Object:
1413 return typeof(System.Object);
1414 case TypeCode.SByte:
1415 return typeof(System.SByte);
1416 case TypeCode.Single:
1417 return typeof(System.Single);
1418 case TypeCode.String:
1419 return typeof(System.String);
1420 case TypeCode.UInt16:
1421 return typeof(System.UInt16);
1422 case TypeCode.UInt32:
1423 return typeof(System.UInt32);
1424 case TypeCode.UInt64:
1425 return typeof(System.UInt64);
1427 throw new ArgumentOutOfRangeException();
1431 public static TypeCode GetTypeCode(Type type)
1435 return TypeCode.Empty;
1437 if (!type.__IsMissing && type.IsEnum)
1439 type = type.GetEnumUnderlyingType();
1441 Universe u = type.Module.universe;
1442 if (type == u.System_Boolean)
1444 return TypeCode.Boolean;
1446 else if (type == u.System_Char)
1448 return TypeCode.Char;
1450 else if (type == u.System_SByte)
1452 return TypeCode.SByte;
1454 else if (type == u.System_Byte)
1456 return TypeCode.Byte;
1458 else if (type == u.System_Int16)
1460 return TypeCode.Int16;
1462 else if (type == u.System_UInt16)
1464 return TypeCode.UInt16;
1466 else if (type == u.System_Int32)
1468 return TypeCode.Int32;
1470 else if (type == u.System_UInt32)
1472 return TypeCode.UInt32;
1474 else if (type == u.System_Int64)
1476 return TypeCode.Int64;
1478 else if (type == u.System_UInt64)
1480 return TypeCode.UInt64;
1482 else if (type == u.System_Single)
1484 return TypeCode.Single;
1486 else if (type == u.System_Double)
1488 return TypeCode.Double;
1490 else if (type == u.System_DateTime)
1492 return TypeCode.DateTime;
1494 else if (type == u.System_DBNull)
1496 return TypeCode.DBNull;
1498 else if (type == u.System_Decimal)
1500 return TypeCode.Decimal;
1502 else if (type == u.System_String)
1504 return TypeCode.String;
1506 else if (type.__IsMissing)
1508 throw new MissingMemberException(type);
1512 return TypeCode.Object;
1516 public Assembly Assembly
1518 get { return Module.Assembly; }
1521 public bool IsAssignableFrom(Type type)
1523 if (this.Equals(type))
1527 else if (type == null)
1531 else if (this.IsArray && type.IsArray)
1533 if (this.GetArrayRank() != type.GetArrayRank())
1537 else if (this.__IsVector && !type.__IsVector)
1541 Type e1 = this.GetElementType();
1542 Type e2 = type.GetElementType();
1543 return e1.IsValueType == e2.IsValueType && e1.IsAssignableFrom(e2);
1545 else if (this.IsCovariant(type))
1549 else if (this.IsSealed)
1553 else if (this.IsInterface)
1555 foreach (Type iface in type.GetInterfaces())
1557 if (this.Equals(iface) || this.IsCovariant(iface))
1564 else if (type.IsInterface)
1566 return this == this.Module.universe.System_Object;
1568 else if (type.IsPointer)
1570 return this == this.Module.universe.System_Object || this == this.Module.universe.System_ValueType;
1574 return type.IsSubclassOf(this);
1578 private bool IsCovariant(Type other)
1580 if (this.IsConstructedGenericType
1581 && other.IsConstructedGenericType
1582 && this.GetGenericTypeDefinition() == other.GetGenericTypeDefinition())
1584 Type[] typeParameters = GetGenericTypeDefinition().GetGenericArguments();
1585 for (int i = 0; i < typeParameters.Length; i++)
1587 Type t1 = this.GetGenericTypeArgument(i);
1588 Type t2 = other.GetGenericTypeArgument(i);
1589 if (t1.IsValueType != t2.IsValueType)
1593 switch (typeParameters[i].GenericParameterAttributes & GenericParameterAttributes.VarianceMask)
1595 case GenericParameterAttributes.Covariant:
1596 if (!t1.IsAssignableFrom(t2))
1601 case GenericParameterAttributes.Contravariant:
1602 if (!t2.IsAssignableFrom(t1))
1607 case GenericParameterAttributes.None:
1620 public bool IsSubclassOf(Type type)
1622 Type thisType = this.BaseType;
1623 while (thisType != null)
1625 if (thisType.Equals(type))
1629 thisType = thisType.BaseType;
1634 // This returns true if this type directly (i.e. not inherited from the base class) implements the interface.
1635 // Note that a complicating factor is that the interface itself can be implemented by an interface that extends it.
1636 private bool IsDirectlyImplementedInterface(Type interfaceType)
1638 foreach (Type iface in __GetDeclaredInterfaces())
1640 if (interfaceType.IsAssignableFrom(iface))
1648 public InterfaceMapping GetInterfaceMap(Type interfaceType)
1651 InterfaceMapping map = new InterfaceMapping();
1652 if (!IsDirectlyImplementedInterface(interfaceType))
1654 Type baseType = this.BaseType;
1655 if (baseType == null)
1657 throw new ArgumentException();
1661 map = baseType.GetInterfaceMap(interfaceType);
1666 map.InterfaceMethods = interfaceType.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
1667 map.InterfaceType = interfaceType;
1668 map.TargetMethods = new MethodInfo[map.InterfaceMethods.Length];
1669 FillInExplicitInterfaceMethods(map.InterfaceMethods, map.TargetMethods);
1670 MethodInfo[] methods = GetMethods(BindingFlags.Instance | BindingFlags.Public);
1671 for (int i = 0; i < map.TargetMethods.Length; i++)
1673 if (map.TargetMethods[i] == null)
1675 // TODO use proper method resolution (also take into account that no implicit base class implementation is used across assembly boundaries)
1676 for (int j = 0; j < methods.Length; j++)
1678 if (methods[j].Name == map.InterfaceMethods[i].Name
1679 && methods[j].MethodSignature.Equals(map.InterfaceMethods[i].MethodSignature))
1681 map.TargetMethods[i] = methods[j];
1686 for (Type baseType = this.BaseType; baseType != null && interfaceType.IsAssignableFrom(baseType); baseType = baseType.BaseType)
1688 baseType.FillInExplicitInterfaceMethods(map.InterfaceMethods, map.TargetMethods);
1691 map.TargetType = this;
1695 internal void FillInExplicitInterfaceMethods(MethodInfo[] interfaceMethods, MethodInfo[] targetMethods)
1697 __MethodImplMap impl = __GetMethodImplMap();
1698 for (int i = 0; i < impl.MethodDeclarations.Length; i++)
1700 for (int j = 0; j < impl.MethodDeclarations[i].Length; j++)
1702 int index = Array.IndexOf(interfaceMethods, impl.MethodDeclarations[i][j]);
1703 if (index != -1 && targetMethods[index] == null)
1705 targetMethods[index] = impl.MethodBodies[i];
1711 Type IGenericContext.GetGenericTypeArgument(int index)
1713 return GetGenericTypeArgument(index);
1716 Type IGenericContext.GetGenericMethodArgument(int index)
1718 throw new BadImageFormatException();
1721 Type IGenericBinder.BindTypeParameter(Type type)
1723 return GetGenericTypeArgument(type.GenericParameterPosition);
1726 Type IGenericBinder.BindMethodParameter(Type type)
1728 throw new BadImageFormatException();
1731 internal virtual Type BindTypeParameters(IGenericBinder binder)
1733 if (IsGenericTypeDefinition)
1735 Type[] args = GetGenericArguments();
1736 Type.InplaceBindTypeParameters(binder, args);
1737 return GenericTypeInstance.Make(this, args, null);
1745 private static void InplaceBindTypeParameters(IGenericBinder binder, Type[] types)
1747 for (int i = 0; i < types.Length; i++)
1749 types[i] = types[i].BindTypeParameters(binder);
1753 internal virtual MethodBase FindMethod(string name, MethodSignature signature)
1755 foreach (MethodBase method in __GetDeclaredMethods())
1757 if (method.Name == name && method.MethodSignature.Equals(signature))
1765 internal virtual FieldInfo FindField(string name, FieldSignature signature)
1767 foreach (FieldInfo field in __GetDeclaredFields())
1769 if (field.Name == name && field.FieldSignature.Equals(signature))
1777 internal bool IsAllowMultipleCustomAttribute
1781 IList<CustomAttributeData> cad = CustomAttributeData.__GetCustomAttributes(this, this.Module.universe.System_AttributeUsageAttribute, false);
1784 foreach (CustomAttributeNamedArgument arg in cad[0].NamedArguments)
1786 if (arg.MemberInfo.Name == "AllowMultiple")
1788 return (bool)arg.TypedValue.Value;
1796 internal bool IsPseudoCustomAttribute
1800 Universe u = this.Module.universe;
1801 return this == u.System_NonSerializedAttribute
1802 || this == u.System_SerializableAttribute
1803 || this == u.System_Runtime_InteropServices_DllImportAttribute
1804 || this == u.System_Runtime_InteropServices_FieldOffsetAttribute
1805 || this == u.System_Runtime_InteropServices_InAttribute
1806 || this == u.System_Runtime_InteropServices_MarshalAsAttribute
1807 || this == u.System_Runtime_InteropServices_OutAttribute
1808 || this == u.System_Runtime_InteropServices_StructLayoutAttribute
1809 || this == u.System_Runtime_InteropServices_OptionalAttribute
1810 || this == u.System_Runtime_InteropServices_PreserveSigAttribute
1811 || this == u.System_Runtime_InteropServices_ComImportAttribute
1812 || this == u.System_Runtime_CompilerServices_SpecialNameAttribute
1813 || this == u.System_Runtime_CompilerServices_MethodImplAttribute
1818 internal Type MarkNotValueType()
1820 typeFlags |= TypeFlags.NotValueType;
1824 internal Type MarkValueType()
1826 typeFlags |= TypeFlags.ValueType;
1830 internal ConstructorInfo GetPseudoCustomAttributeConstructor(params Type[] parameterTypes)
1832 Universe u = this.Module.universe;
1833 MethodSignature methodSig = MethodSignature.MakeFromBuilder(u.System_Void, parameterTypes, new PackedCustomModifiers(), CallingConventions.Standard | CallingConventions.HasThis, 0);
1835 FindMethod(".ctor", methodSig) ??
1836 u.GetMissingMethodOrThrow(this, ".ctor", methodSig);
1837 return (ConstructorInfo)mb;
1840 public MethodBase __CreateMissingMethod(string name, CallingConventions callingConvention, Type returnType, CustomModifiers returnTypeCustomModifiers, Type[] parameterTypes, CustomModifiers[] parameterTypeCustomModifiers)
1842 return CreateMissingMethod(name, callingConvention, returnType, parameterTypes, PackedCustomModifiers.CreateFromExternal(returnTypeCustomModifiers, parameterTypeCustomModifiers, parameterTypes.Length));
1845 private MethodBase CreateMissingMethod(string name, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, PackedCustomModifiers customModifiers)
1847 MethodSignature sig = new MethodSignature(
1848 returnType ?? this.Module.universe.System_Void,
1849 Util.Copy(parameterTypes),
1853 MethodInfo method = new MissingMethod(this, name, sig);
1854 if (name == ".ctor" || name == ".cctor")
1856 return new ConstructorInfoImpl(method);
1861 [Obsolete("Please use __CreateMissingMethod(string, CallingConventions, Type, CustomModifiers, Type[], CustomModifiers[]) instead")]
1862 public MethodBase __CreateMissingMethod(string name, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
1864 return CreateMissingMethod(name, callingConvention, returnType, parameterTypes, PackedCustomModifiers.CreateFromExternal(returnTypeOptionalCustomModifiers, returnTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, parameterTypeRequiredCustomModifiers, parameterTypes.Length));
1867 public FieldInfo __CreateMissingField(string name, Type fieldType, CustomModifiers customModifiers)
1869 return new MissingField(this, name, FieldSignature.Create(fieldType, customModifiers));
1872 [Obsolete("Please use __CreateMissingField(string, Type, CustomModifiers) instead")]
1873 public FieldInfo __CreateMissingField(string name, Type fieldType, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1875 return __CreateMissingField(name, fieldType, CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers));
1878 public PropertyInfo __CreateMissingProperty(string name, CallingConventions callingConvention, Type propertyType, CustomModifiers propertyTypeCustomModifiers, Type[] parameterTypes, CustomModifiers[] parameterTypeCustomModifiers)
1880 PropertySignature sig = PropertySignature.Create(callingConvention,
1883 PackedCustomModifiers.CreateFromExternal(propertyTypeCustomModifiers, parameterTypeCustomModifiers, Util.NullSafeLength(parameterTypes)));
1884 return new MissingProperty(this, name, sig);
1887 internal virtual Type SetMetadataTokenForMissing(int token)
1892 protected void MarkEnumOrValueType(string typeNamespace, string typeName)
1894 // we assume that mscorlib won't have nested types with these names,
1895 // so we don't check that we're not a nested type
1896 if (typeNamespace == "System"
1897 && (typeName == "Enum" || typeName == "ValueType"))
1899 typeFlags |= TypeFlags.PotentialEnumOrValueType;
1903 private bool ResolvePotentialEnumOrValueType()
1905 if (this.Assembly == this.Universe.Mscorlib
1906 || this.Assembly.GetName().Name.Equals("mscorlib", StringComparison.OrdinalIgnoreCase)
1907 // check if mscorlib forwards the type (.NETCore profile reference mscorlib forwards System.Enum and System.ValueType to System.Runtime.dll)
1908 || this.Universe.Mscorlib.FindType(new TypeName(__Namespace, __Name)) == this)
1910 typeFlags = (typeFlags & ~TypeFlags.PotentialEnumOrValueType) | TypeFlags.EnumOrValueType;
1915 typeFlags &= ~TypeFlags.PotentialEnumOrValueType;
1920 private bool IsEnumOrValueType
1924 return (typeFlags & (TypeFlags.EnumOrValueType | TypeFlags.PotentialEnumOrValueType)) != 0
1925 && ((typeFlags & TypeFlags.EnumOrValueType) != 0 || ResolvePotentialEnumOrValueType());
1929 internal virtual Universe Universe
1931 get { return Module.universe; }
1934 internal sealed override bool BindingFlagsMatch(BindingFlags flags)
1936 return BindingFlagsMatch(IsNestedPublic, flags, BindingFlags.Public, BindingFlags.NonPublic);
1939 internal sealed override MemberInfo SetReflectedType(Type type)
1941 throw new InvalidOperationException();
1944 internal override int GetCurrentToken()
1946 return this.MetadataToken;
1949 internal sealed override List<CustomAttributeData> GetPseudoCustomAttributes(Type attributeType)
1951 // types don't have pseudo custom attributes
1955 // in .NET this is an extension method, but we target .NET 2.0, so we have an instance method
1956 public TypeInfo GetTypeInfo()
1958 TypeInfo type = this as TypeInfo;
1961 throw new MissingMemberException(this);
1967 abstract class ElementHolderType : TypeInfo
1969 protected readonly Type elementType;
1971 private readonly CustomModifiers mods;
1973 protected ElementHolderType(Type elementType, CustomModifiers mods)
1975 this.elementType = elementType;
1979 protected bool EqualsHelper(ElementHolderType other)
1981 return other != null
1982 && other.elementType.Equals(elementType)
1983 && other.mods.Equals(mods);
1986 public override CustomModifiers __GetCustomModifiers()
1991 public sealed override string Name
1993 get { return elementType.Name + GetSuffix(); }
1996 public sealed override string Namespace
1998 get { return elementType.Namespace; }
2001 public sealed override string FullName
2003 get { return elementType.FullName + GetSuffix(); }
2006 public sealed override string ToString()
2008 return elementType.ToString() + GetSuffix();
2011 public sealed override Type GetElementType()
2016 public sealed override bool HasElementType
2018 get { return true; }
2021 public sealed override Module Module
2023 get { return elementType.Module; }
2026 internal sealed override int GetModuleBuilderToken()
2030 token = ((ModuleBuilder)elementType.Module).ImportType(this);
2035 public sealed override bool ContainsGenericParameters
2039 Type type = elementType;
2040 while (type.HasElementType)
2042 type = type.GetElementType();
2044 return type.ContainsGenericParameters;
2048 public sealed override bool __ContainsMissingType
2052 Type type = elementType;
2053 while (type.HasElementType)
2055 type = type.GetElementType();
2057 return type.__ContainsMissingType;
2061 internal sealed override Type BindTypeParameters(IGenericBinder binder)
2063 Type type = elementType.BindTypeParameters(binder);
2064 CustomModifiers mods = this.mods.Bind(binder);
2065 if (ReferenceEquals(type, elementType)
2066 && mods.Equals(this.mods))
2070 return Wrap(type, mods);
2073 internal override void CheckBaked()
2075 elementType.CheckBaked();
2078 internal sealed override Universe Universe
2080 get { return elementType.Universe; }
2083 internal sealed override bool IsBaked
2085 get { return elementType.IsBaked; }
2088 internal sealed override int GetCurrentToken()
2090 // we don't have a token, so we return 0 (which is never a valid token)
2094 internal abstract string GetSuffix();
2096 protected abstract Type Wrap(Type type, CustomModifiers mods);
2099 sealed class ArrayType : ElementHolderType
2101 internal static Type Make(Type type, CustomModifiers mods)
2103 return type.Universe.CanonicalizeType(new ArrayType(type, mods));
2106 private ArrayType(Type type, CustomModifiers mods)
2111 public override Type BaseType
2113 get { return elementType.Module.universe.System_Array; }
2116 public override Type[] __GetDeclaredInterfaces()
2119 this.Module.universe.Import(typeof(IList<>)).MakeGenericType(elementType),
2120 this.Module.universe.Import(typeof(ICollection<>)).MakeGenericType(elementType),
2121 this.Module.universe.Import(typeof(IEnumerable<>)).MakeGenericType(elementType)
2125 public override MethodBase[] __GetDeclaredMethods()
2127 Type[] int32 = new Type[] { this.Module.universe.System_Int32 };
2128 List<MethodBase> list = new List<MethodBase>();
2129 list.Add(new BuiltinArrayMethod(this.Module, this, "Set", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, new Type[] { this.Module.universe.System_Int32, elementType }));
2130 list.Add(new BuiltinArrayMethod(this.Module, this, "Address", CallingConventions.Standard | CallingConventions.HasThis, elementType.MakeByRefType(), int32));
2131 list.Add(new BuiltinArrayMethod(this.Module, this, "Get", CallingConventions.Standard | CallingConventions.HasThis, elementType, int32));
2132 list.Add(new ConstructorInfoImpl(new BuiltinArrayMethod(this.Module, this, ".ctor", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, int32)));
2133 for (Type type = elementType; type.__IsVector; type = type.GetElementType())
2135 Array.Resize(ref int32, int32.Length + 1);
2136 int32[int32.Length - 1] = int32[0];
2137 list.Add(new ConstructorInfoImpl(new BuiltinArrayMethod(this.Module, this, ".ctor", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, int32)));
2139 return list.ToArray();
2142 public override TypeAttributes Attributes
2144 get { return TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Serializable; }
2147 public override bool IsArray
2149 get { return true; }
2152 public override bool __IsVector
2154 get { return true; }
2157 public override int GetArrayRank()
2162 public override bool Equals(object o)
2164 return EqualsHelper(o as ArrayType);
2167 public override int GetHashCode()
2169 return elementType.GetHashCode() * 5;
2172 internal override string GetSuffix()
2177 protected override Type Wrap(Type type, CustomModifiers mods)
2179 return Make(type, mods);
2183 sealed class MultiArrayType : ElementHolderType
2185 private readonly int rank;
2186 private readonly int[] sizes;
2187 private readonly int[] lobounds;
2189 internal static Type Make(Type type, int rank, int[] sizes, int[] lobounds, CustomModifiers mods)
2191 return type.Universe.CanonicalizeType(new MultiArrayType(type, rank, sizes, lobounds, mods));
2194 private MultiArrayType(Type type, int rank, int[] sizes, int[] lobounds, CustomModifiers mods)
2199 this.lobounds = lobounds;
2202 public override Type BaseType
2204 get { return elementType.Module.universe.System_Array; }
2207 public override MethodBase[] __GetDeclaredMethods()
2209 Type int32 = this.Module.universe.System_Int32;
2210 Type[] setArgs = new Type[rank + 1];
2211 Type[] getArgs = new Type[rank];
2212 Type[] ctorArgs = new Type[rank * 2];
2213 for (int i = 0; i < rank; i++)
2217 ctorArgs[i * 2 + 0] = int32;
2218 ctorArgs[i * 2 + 1] = int32;
2220 setArgs[rank] = elementType;
2221 return new MethodBase[] {
2222 new ConstructorInfoImpl(new BuiltinArrayMethod(this.Module, this, ".ctor", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, getArgs)),
2223 new ConstructorInfoImpl(new BuiltinArrayMethod(this.Module, this, ".ctor", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, ctorArgs)),
2224 new BuiltinArrayMethod(this.Module, this, "Set", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, setArgs),
2225 new BuiltinArrayMethod(this.Module, this, "Address", CallingConventions.Standard | CallingConventions.HasThis, elementType.MakeByRefType(), getArgs),
2226 new BuiltinArrayMethod(this.Module, this, "Get", CallingConventions.Standard | CallingConventions.HasThis, elementType, getArgs),
2230 public override TypeAttributes Attributes
2232 get { return TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Serializable; }
2235 public override bool IsArray
2237 get { return true; }
2240 public override int GetArrayRank()
2245 public override int[] __GetArraySizes()
2247 return Util.Copy(sizes);
2250 public override int[] __GetArrayLowerBounds()
2252 return Util.Copy(lobounds);
2255 public override bool Equals(object o)
2257 MultiArrayType at = o as MultiArrayType;
2258 return EqualsHelper(at)
2260 && ArrayEquals(at.sizes, sizes)
2261 && ArrayEquals(at.lobounds, lobounds);
2264 private static bool ArrayEquals(int[] i1, int[] i2)
2266 if (i1.Length == i2.Length)
2268 for (int i = 0; i < i1.Length; i++)
2280 public override int GetHashCode()
2282 return elementType.GetHashCode() * 9 + rank;
2285 internal override string GetSuffix()
2293 return "[" + new String(',', rank - 1) + "]";
2297 protected override Type Wrap(Type type, CustomModifiers mods)
2299 return Make(type, rank, sizes, lobounds, mods);
2303 sealed class BuiltinArrayMethod : ArrayMethod
2305 internal BuiltinArrayMethod(Module module, Type arrayClass, string methodName, CallingConventions callingConvention, Type returnType, Type[] parameterTypes)
2306 : base(module, arrayClass, methodName, callingConvention, returnType, parameterTypes)
2310 public override MethodAttributes Attributes
2312 get { return this.Name == ".ctor" ? MethodAttributes.RTSpecialName | MethodAttributes.Public : MethodAttributes.Public; }
2315 public override MethodImplAttributes GetMethodImplementationFlags()
2317 return MethodImplAttributes.IL;
2320 public override int MetadataToken
2322 get { return 0x06000000; }
2325 public override MethodBody GetMethodBody()
2330 public override ParameterInfo[] GetParameters()
2332 ParameterInfo[] parameterInfos = new ParameterInfo[parameterTypes.Length];
2333 for (int i = 0; i < parameterInfos.Length; i++)
2335 parameterInfos[i] = new ParameterInfoImpl(this, parameterTypes[i], i);
2337 return parameterInfos;
2340 public override ParameterInfo ReturnParameter
2342 get { return new ParameterInfoImpl(this, this.ReturnType, -1); }
2345 private sealed class ParameterInfoImpl : ParameterInfo
2347 private readonly MethodInfo method;
2348 private readonly Type type;
2349 private readonly int pos;
2351 internal ParameterInfoImpl(MethodInfo method, Type type, int pos)
2353 this.method = method;
2358 public override Type ParameterType
2360 get { return type; }
2363 public override string Name
2365 get { return null; }
2368 public override ParameterAttributes Attributes
2370 get { return ParameterAttributes.None; }
2373 public override int Position
2378 public override object RawDefaultValue
2380 get { return null; }
2383 public override CustomModifiers __GetCustomModifiers()
2385 return new CustomModifiers();
2388 public override bool __TryGetFieldMarshal(out FieldMarshal fieldMarshal)
2390 fieldMarshal = new FieldMarshal();
2394 public override MemberInfo Member
2396 get { return method.IsConstructor ? (MethodBase)new ConstructorInfoImpl(method) : method; }
2399 public override int MetadataToken
2401 get { return 0x08000000; }
2404 internal override Module Module
2406 get { return method.Module; }
2411 sealed class ByRefType : ElementHolderType
2413 internal static Type Make(Type type, CustomModifiers mods)
2415 return type.Universe.CanonicalizeType(new ByRefType(type, mods));
2418 private ByRefType(Type type, CustomModifiers mods)
2423 public override bool Equals(object o)
2425 return EqualsHelper(o as ByRefType);
2428 public override int GetHashCode()
2430 return elementType.GetHashCode() * 3;
2433 public override Type BaseType
2435 get { return null; }
2438 public override TypeAttributes Attributes
2443 public override bool IsByRef
2445 get { return true; }
2448 internal override string GetSuffix()
2453 protected override Type Wrap(Type type, CustomModifiers mods)
2455 return Make(type, mods);
2459 sealed class PointerType : ElementHolderType
2461 internal static Type Make(Type type, CustomModifiers mods)
2463 return type.Universe.CanonicalizeType(new PointerType(type, mods));
2466 private PointerType(Type type, CustomModifiers mods)
2471 public override bool Equals(object o)
2473 return EqualsHelper(o as PointerType);
2476 public override int GetHashCode()
2478 return elementType.GetHashCode() * 7;
2481 public override Type BaseType
2483 get { return null; }
2486 public override TypeAttributes Attributes
2491 public override bool IsPointer
2493 get { return true; }
2496 internal override string GetSuffix()
2501 protected override Type Wrap(Type type, CustomModifiers mods)
2503 return Make(type, mods);
2507 sealed class GenericTypeInstance : TypeInfo
2509 private readonly Type type;
2510 private readonly Type[] args;
2511 private readonly CustomModifiers[] mods;
2512 private Type baseType;
2515 internal static Type Make(Type type, Type[] typeArguments, CustomModifiers[] mods)
2517 bool identity = true;
2518 if (type is TypeBuilder || type is BakedType || type.__IsMissing)
2520 // a TypeBuiler identity must be instantiated
2525 // we must not instantiate the identity instance, because typeof(Foo<>).MakeGenericType(typeof(Foo<>).GetGenericArguments()) == typeof(Foo<>)
2526 for (int i = 0; i < typeArguments.Length; i++)
2528 if (typeArguments[i] != type.GetGenericTypeArgument(i)
2529 || !IsEmpty(mods, i))
2542 return type.Universe.CanonicalizeType(new GenericTypeInstance(type, typeArguments, mods));
2546 private static bool IsEmpty(CustomModifiers[] mods, int i)
2548 // we need to be extra careful, because mods doesn't not need to be in canonical format
2549 // (Signature.ReadGenericInst() calls Make() directly, without copying the modifier arrays)
2550 return mods == null || mods[i].IsEmpty;
2553 private GenericTypeInstance(Type type, Type[] args, CustomModifiers[] mods)
2560 public override bool Equals(object o)
2562 GenericTypeInstance gt = o as GenericTypeInstance;
2563 return gt != null && gt.type.Equals(type) && Util.ArrayEquals(gt.args, args)
2564 && Util.ArrayEquals(gt.mods, mods);
2567 public override int GetHashCode()
2569 return type.GetHashCode() * 3 ^ Util.GetHashCode(args);
2572 public override string AssemblyQualifiedName
2576 string fn = FullName;
2577 return fn == null ? null : fn + ", " + type.Assembly.FullName;
2581 public override Type BaseType
2585 if (baseType == null)
2587 Type rawBaseType = type.BaseType;
2588 if (rawBaseType == null)
2590 baseType = rawBaseType;
2594 baseType = rawBaseType.BindTypeParameters(this);
2601 public override bool IsValueType
2603 get { return type.IsValueType; }
2606 public override bool IsVisible
2612 foreach (Type arg in args)
2625 public override Type DeclaringType
2627 get { return type.DeclaringType; }
2630 public override TypeAttributes Attributes
2632 get { return type.Attributes; }
2635 internal override void CheckBaked()
2640 public override FieldInfo[] __GetDeclaredFields()
2642 FieldInfo[] fields = type.__GetDeclaredFields();
2643 for (int i = 0; i < fields.Length; i++)
2645 fields[i] = fields[i].BindTypeParameters(this);
2650 public override Type[] __GetDeclaredInterfaces()
2652 Type[] interfaces = type.__GetDeclaredInterfaces();
2653 for (int i = 0; i < interfaces.Length; i++)
2655 interfaces[i] = interfaces[i].BindTypeParameters(this);
2660 public override MethodBase[] __GetDeclaredMethods()
2662 MethodBase[] methods = type.__GetDeclaredMethods();
2663 for (int i = 0; i < methods.Length; i++)
2665 methods[i] = methods[i].BindTypeParameters(this);
2670 public override Type[] __GetDeclaredTypes()
2672 return type.__GetDeclaredTypes();
2675 public override EventInfo[] __GetDeclaredEvents()
2677 EventInfo[] events = type.__GetDeclaredEvents();
2678 for (int i = 0; i < events.Length; i++)
2680 events[i] = events[i].BindTypeParameters(this);
2685 public override PropertyInfo[] __GetDeclaredProperties()
2687 PropertyInfo[] properties = type.__GetDeclaredProperties();
2688 for (int i = 0; i < properties.Length; i++)
2690 properties[i] = properties[i].BindTypeParameters(this);
2695 public override __MethodImplMap __GetMethodImplMap()
2697 __MethodImplMap map = type.__GetMethodImplMap();
2698 map.TargetType = this;
2699 for (int i = 0; i < map.MethodBodies.Length; i++)
2701 map.MethodBodies[i] = (MethodInfo)map.MethodBodies[i].BindTypeParameters(this);
2702 for (int j = 0; j < map.MethodDeclarations[i].Length; j++)
2704 Type interfaceType = map.MethodDeclarations[i][j].DeclaringType;
2705 if (interfaceType.IsGenericType)
2707 map.MethodDeclarations[i][j] = (MethodInfo)map.MethodDeclarations[i][j].BindTypeParameters(this);
2714 public override string Namespace
2716 get { return type.Namespace; }
2719 public override string Name
2721 get { return type.Name; }
2724 public override string FullName
2728 if (!this.__ContainsMissingType && this.ContainsGenericParameters)
2732 StringBuilder sb = new StringBuilder(this.type.FullName);
2735 foreach (Type type in args)
2737 sb.Append(sep).Append('[').Append(type.FullName).Append(", ").Append(type.Assembly.FullName.Replace("]", "\\]")).Append(']');
2741 return sb.ToString();
2745 public override string ToString()
2747 StringBuilder sb = new StringBuilder(type.FullName);
2750 foreach (Type arg in args)
2757 return sb.ToString();
2760 public override Module Module
2762 get { return type.Module; }
2765 public override bool IsGenericType
2767 get { return true; }
2770 public override bool IsConstructedGenericType
2772 get { return true; }
2775 public override Type GetGenericTypeDefinition()
2780 public override Type[] GetGenericArguments()
2782 return Util.Copy(args);
2785 public override CustomModifiers[] __GetGenericArgumentsCustomModifiers()
2787 return mods != null ? (CustomModifiers[])mods.Clone() : new CustomModifiers[args.Length];
2790 internal override Type GetGenericTypeArgument(int index)
2795 public override bool ContainsGenericParameters
2799 foreach (Type type in args)
2801 if (type.ContainsGenericParameters)
2810 public override bool __ContainsMissingType
2814 foreach (Type type in args)
2816 if (type.__ContainsMissingType)
2821 return this.type.__IsMissing;
2825 public override StructLayoutAttribute StructLayoutAttribute
2827 get { return type.StructLayoutAttribute; }
2830 internal override int GetModuleBuilderToken()
2834 token = ((ModuleBuilder)type.Module).ImportType(this);
2839 internal override Type BindTypeParameters(IGenericBinder binder)
2841 for (int i = 0; i < args.Length; i++)
2843 Type xarg = args[i].BindTypeParameters(binder);
2844 if (!ReferenceEquals(xarg, args[i]))
2846 Type[] xargs = new Type[args.Length];
2847 Array.Copy(args, xargs, i);
2849 for (; i < args.Length; i++)
2851 xargs[i] = args[i].BindTypeParameters(binder);
2853 return Make(type, xargs, null);
2859 internal override int GetCurrentToken()
2861 return type.GetCurrentToken();
2864 internal override bool IsBaked
2866 get { return type.IsBaked; }
2870 sealed class FunctionPointerType : TypeInfo
2872 private readonly Universe universe;
2873 private readonly __StandAloneMethodSig sig;
2875 internal static Type Make(Universe universe, __StandAloneMethodSig sig)
2877 return universe.CanonicalizeType(new FunctionPointerType(universe, sig));
2880 private FunctionPointerType(Universe universe, __StandAloneMethodSig sig)
2882 this.universe = universe;
2886 public override bool Equals(object obj)
2888 FunctionPointerType other = obj as FunctionPointerType;
2889 return other != null
2890 && other.universe == universe
2891 && other.sig.Equals(sig);
2894 public override int GetHashCode()
2896 return sig.GetHashCode();
2899 public override bool __IsFunctionPointer
2901 get { return true; }
2904 public override __StandAloneMethodSig __MethodSignature
2909 public override Type BaseType
2911 get { return null; }
2914 public override TypeAttributes Attributes
2919 public override string Name
2921 get { throw new InvalidOperationException(); }
2924 public override string FullName
2926 get { throw new InvalidOperationException(); }
2929 public override Module Module
2931 get { throw new InvalidOperationException(); }
2934 internal override Universe Universe
2936 get { return universe; }
2939 public override string ToString()
2941 return "<FunctionPtr>";
2944 internal override bool IsBaked
2946 get { return true; }
2950 sealed class MarkerType : Type
2952 // used by ILGenerator
2953 internal static readonly Type Fault = new MarkerType();
2954 internal static readonly Type Finally = new MarkerType();
2955 internal static readonly Type Filter = new MarkerType();
2956 // used by CustomModifiers and SignatureHelper
2957 internal static readonly Type ModOpt = new MarkerType();
2958 internal static readonly Type ModReq = new MarkerType();
2959 // used by SignatureHelper
2960 internal static readonly Type Sentinel = new MarkerType();
2961 internal static readonly Type Pinned = new MarkerType();
2963 private MarkerType() { }
2965 public override Type BaseType
2967 get { throw new InvalidOperationException(); }
2970 public override TypeAttributes Attributes
2972 get { throw new InvalidOperationException(); }
2975 public override string Name
2977 get { throw new InvalidOperationException(); }
2980 public override string FullName
2982 get { throw new InvalidOperationException(); }
2985 public override Module Module
2987 get { throw new InvalidOperationException(); }
2990 internal override bool IsBaked
2992 get { throw new InvalidOperationException(); }
2995 public override bool __IsMissing
2997 get { throw new InvalidOperationException(); }