[Flags]
protected enum TypeFlags
{
- // for use by TypeBuilder
+ // for use by TypeBuilder or TypeDefImpl
IsGenericTypeDefinition = 1,
+
+ // for use by TypeBuilder
HasNestedTypes = 2,
Baked = 4,
ValueType = 8,
NotValueType = 16,
- // for use by TypeDef, TypeBuilder or MissingType
+ // for use by TypeDefImpl, TypeBuilder or MissingType
PotentialEnumOrValueType = 32,
EnumOrValueType = 64,
+
+ // for use by TypeDefImpl
+ NotGenericTypeDefinition = 128,
}
// prevent subclassing by outsiders
get { return false; }
}
- internal virtual bool IsGenericTypeInstance
+ // .NET 4.5 API
+ public virtual bool IsConstructedGenericType
{
get { return false; }
}
private static void AddInterfaces(List<Type> list, Type type)
{
- type.CheckBaked();
foreach (Type iface in type.__GetDeclaredInterfaces())
{
if (!list.Contains(iface))
{
baseMethods = new List<MethodInfo>();
}
- else if (FindMethod(baseMethods, mi.GetBaseDefinition()))
+ else if (baseMethods.Contains(mi.GetBaseDefinition()))
{
continue;
}
return list.ToArray();
}
- private static bool FindMethod(List<MethodInfo> methods, MethodInfo method)
- {
- foreach (MethodInfo m in methods)
- {
- if (m.Name == method.Name && m.MethodSignature.Equals(method.MethodSignature))
- {
- return true;
- }
- }
- return false;
- }
-
public MethodInfo[] GetMethods()
{
return GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
}
public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
+ {
+ ConstructorInfo ci1 = null;
+ if ((bindingAttr & BindingFlags.Instance) != 0)
+ {
+ ci1 = GetConstructorImpl(ConstructorInfo.ConstructorName, bindingAttr, binder, types, modifiers);
+ }
+ if ((bindingAttr & BindingFlags.Static) != 0)
+ {
+ ConstructorInfo ci2 = GetConstructorImpl(ConstructorInfo.TypeConstructorName, bindingAttr, binder, types, modifiers);
+ if (ci2 != null)
+ {
+ if (ci1 != null)
+ {
+ throw new AmbiguousMatchException();
+ }
+ return ci2;
+ }
+ }
+ return ci1;
+ }
+
+ private ConstructorInfo GetConstructorImpl(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
{
// first we try an exact match and only if that fails we fall back to using the binder
- return GetMemberByName<ConstructorInfo>(ConstructorInfo.ConstructorName, bindingAttr | BindingFlags.DeclaredOnly,
+ return GetMemberByName<ConstructorInfo>(name, bindingAttr | BindingFlags.DeclaredOnly,
delegate(ConstructorInfo ctor) { return ctor.MethodSignature.MatchParameterTypes(types); })
- ?? GetMethodWithBinder<ConstructorInfo>(ConstructorInfo.ConstructorName, bindingAttr, binder ?? DefaultBinder, types, modifiers);
+ ?? GetMethodWithBinder<ConstructorInfo>(name, bindingAttr, binder ?? DefaultBinder, types, modifiers);
}
public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, CallingConventions callingConvention, Type[] types, ParameterModifier[] modifiers)
get { return Module.Assembly; }
}
- // note that interface/delegate co- and contravariance is not considered
public bool IsAssignableFrom(Type type)
{
if (this.Equals(type))
Type e2 = type.GetElementType();
return e1.IsValueType == e2.IsValueType && e1.IsAssignableFrom(e2);
}
+ else if (this.IsCovariant(type))
+ {
+ return true;
+ }
else if (this.IsSealed)
{
return false;
}
else if (this.IsInterface)
{
- return Array.IndexOf(type.GetInterfaces(), this) != -1;
+ foreach (Type iface in type.GetInterfaces())
+ {
+ if (this.Equals(iface) || this.IsCovariant(iface))
+ {
+ return true;
+ }
+ }
+ return false;
}
else if (type.IsInterface)
{
}
}
+ private bool IsCovariant(Type other)
+ {
+ if (this.IsConstructedGenericType
+ && other.IsConstructedGenericType
+ && this.GetGenericTypeDefinition() == other.GetGenericTypeDefinition())
+ {
+ Type[] typeParameters = GetGenericTypeDefinition().GetGenericArguments();
+ for (int i = 0; i < typeParameters.Length; i++)
+ {
+ Type t1 = this.GetGenericTypeArgument(i);
+ Type t2 = other.GetGenericTypeArgument(i);
+ if (t1.IsValueType != t2.IsValueType)
+ {
+ return false;
+ }
+ switch (typeParameters[i].GenericParameterAttributes & GenericParameterAttributes.VarianceMask)
+ {
+ case GenericParameterAttributes.Covariant:
+ if (!t1.IsAssignableFrom(t2))
+ {
+ return false;
+ }
+ break;
+ case GenericParameterAttributes.Contravariant:
+ if (!t2.IsAssignableFrom(t1))
+ {
+ return false;
+ }
+ break;
+ case GenericParameterAttributes.None:
+ if (t1 != t2)
+ {
+ return false;
+ }
+ break;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
public bool IsSubclassOf(Type type)
{
Type thisType = this.BaseType;
{
get
{
- IList<CustomAttributeData> cad = GetCustomAttributesData(this.Module.universe.System_AttributeUsageAttribute);
+ IList<CustomAttributeData> cad = CustomAttributeData.__GetCustomAttributes(this, this.Module.universe.System_AttributeUsageAttribute, false);
if (cad.Count == 1)
{
foreach (CustomAttributeNamedArgument arg in cad[0].NamedArguments)
private bool ResolvePotentialEnumOrValueType()
{
- if (this.Assembly == this.Universe.Mscorlib || this.Assembly.GetName().Name.Equals("mscorlib", StringComparison.OrdinalIgnoreCase))
+ if (this.Assembly == this.Universe.Mscorlib
+ || this.Assembly.GetName().Name.Equals("mscorlib", StringComparison.OrdinalIgnoreCase)
+ // check if mscorlib forwards the type (.NETCore profile reference mscorlib forwards System.Enum and System.ValueType to System.Runtime.dll)
+ || this.Universe.Mscorlib.FindType(new TypeName(__Namespace, __Name)) == this)
{
typeFlags = (typeFlags & ~TypeFlags.PotentialEnumOrValueType) | TypeFlags.EnumOrValueType;
return true;
}
}
- internal virtual IList<CustomAttributeData> GetInterfaceImplCustomAttributes(Type interfaceType, Type attributeType)
- {
- throw new NotSupportedException();
- }
-
internal virtual Universe Universe
{
get { return Module.universe; }
{
throw new InvalidOperationException();
}
+
+ internal override int GetCurrentToken()
+ {
+ return this.MetadataToken;
+ }
+
+ internal sealed override List<CustomAttributeData> GetPseudoCustomAttributes(Type attributeType)
+ {
+ // types don't have pseudo custom attributes
+ return null;
+ }
+
+ // in .NET this is an extension method, but we target .NET 2.0, so we have an instance method
+ public TypeInfo GetTypeInfo()
+ {
+ TypeInfo type = this as TypeInfo;
+ if (type == null)
+ {
+ throw new MissingMemberException(this);
+ }
+ return type;
+ }
}
- abstract class ElementHolderType : Type
+ abstract class ElementHolderType : TypeInfo
{
protected readonly Type elementType;
private int token;
elementType.CheckBaked();
}
- internal sealed override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
+ internal sealed override Universe Universe
{
- return CustomAttributeData.EmptyList;
+ get { return elementType.Universe; }
}
- internal sealed override Universe Universe
+ internal sealed override bool IsBaked
{
- get { return elementType.Universe; }
+ get { return elementType.IsBaked; }
+ }
+
+ internal sealed override int GetCurrentToken()
+ {
+ // we don't have a token, so we return 0 (which is never a valid token)
+ return 0;
}
internal abstract string GetSuffix();
return new CustomModifiers();
}
+ public override bool __TryGetFieldMarshal(out FieldMarshal fieldMarshal)
+ {
+ fieldMarshal = new FieldMarshal();
+ return false;
+ }
+
public override MemberInfo Member
{
get { return method.IsConstructor ? (MethodBase)new ConstructorInfoImpl(method) : method; }
public override int MetadataToken
{
- get { return 0x8000000; }
+ get { return 0x08000000; }
}
internal override Module Module
}
}
- sealed class GenericTypeInstance : Type
+ sealed class GenericTypeInstance : TypeInfo
{
private readonly Type type;
private readonly Type[] args;
get { return true; }
}
- internal override bool IsGenericTypeInstance
+ public override bool IsConstructedGenericType
{
get { return true; }
}
return this;
}
- internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
+ internal override int GetCurrentToken()
+ {
+ return type.GetCurrentToken();
+ }
+
+ internal override bool IsBaked
{
- return type.GetCustomAttributesData(attributeType);
+ get { return type.IsBaked; }
}
}
- sealed class FunctionPointerType : Type
+ sealed class FunctionPointerType : TypeInfo
{
private readonly Universe universe;
private readonly __StandAloneMethodSig sig;
{
return "<FunctionPtr>";
}
+
+ internal override bool IsBaked
+ {
+ get { return true; }
+ }
}
sealed class MarkerType : Type
{
get { throw new InvalidOperationException(); }
}
+
+ internal override bool IsBaked
+ {
+ get { throw new InvalidOperationException(); }
+ }
+
+ public override bool __IsMissing
+ {
+ get { throw new InvalidOperationException(); }
+ }
}
}