static public Type iasyncresult_type;
static public Type asynccallback_type;
static public Type intptr_type;
+ static public Type uintptr_type;
static public Type monitor_type;
static public Type interlocked_type;
static public Type runtime_field_handle_type;
builder_to_declspace = null;
builder_to_member_cache = null;
builder_to_ifaces = null;
+ builder_to_type_param = null;
indexer_arguments = null;
method_params = null;
builder_to_method = null;
#if GMCS_SOURCE
assembly_internals_vis_attrs = null;
-
- CleanUpGenerics ();
#endif
TypeHandle.CleanUp ();
if (!(mi is MethodBase))
return false;
-
+
if (mi.Name != sig.name)
return false;
builder_to_declspace = new PtrHashtable ();
builder_to_member_cache = new PtrHashtable ();
builder_to_method = new PtrHashtable ();
+ builder_to_type_param = new PtrHashtable ();
method_params = new PtrHashtable ();
method_overrides = new PtrHashtable ();
indexer_arguments = new PtrHashtable ();
#if GMCS_SOURCE
assembly_internals_vis_attrs = new PtrHashtable ();
-
- InitGenerics ();
#endif
// to uncover regressions
public static MemberCache LookupMemberCache (Type t)
{
+#if GMCS_SOURCE && MS_COMPATIBLE
+ if (t.IsGenericType && !t.IsGenericTypeDefinition)
+ t = t.GetGenericTypeDefinition ();
+#endif
+
if (t is TypeBuilder) {
IMemberContainer container = builder_to_declspace [t] as IMemberContainer;
if (container != null)
return GetMethod (t, name, args, false, report_errors);
}
- static MethodInfo GetMethod (Type t, string name, Type [] args)
+ public static MethodInfo GetMethod (Type t, string name, Type [] args)
{
return GetMethod (t, name, args, true);
}
interlocked_type = CoreLookupType ("System.Threading", "Interlocked");
monitor_type = CoreLookupType ("System.Threading", "Monitor");
intptr_type = CoreLookupType ("System", "IntPtr");
+ uintptr_type = CoreLookupType ("System", "UIntPtr");
attribute_type = CoreLookupType ("System", "Attribute");
attribute_usage_type = CoreLookupType ("System", "AttributeUsageAttribute");
MemberFilter filter, object criteria)
{
#if MS_COMPATIBLE && GMCS_SOURCE
- if (t.IsGenericType)
+ if (t.IsGenericType && !t.IsGenericTypeDefinition)
t = t.GetGenericTypeDefinition ();
#endif
{
MemberCache cache;
+#if GMCS_SOURCE && MS_COMPATIBLE
+ if (t.IsGenericType && !t.IsGenericTypeDefinition)
+ t = t.GetGenericTypeDefinition();
+#endif
+
//
// If this is a dynamic type, it's always in the `builder_to_declspace' hash table
// and we can ask the DeclSpace for the MemberCache.
// a TypeBuilder array will return a Type, not a TypeBuilder,
// and we can not call FindMembers on this type.
//
- if (t == TypeManager.array_type || t.IsSubclassOf (TypeManager.array_type)) {
+ if (t.IsArray) { // == TypeManager.array_type || t.IsSubclassOf (TypeManager.array_type)) {
used_cache = true;
return TypeHandle.ArrayType.MemberCache.FindMembers (
mt, bf, name, FilterWithClosure_delegate, null);
used_cache = true;
return (MemberInfo []) list;
}
+#endif
- if (t.IsGenericType && (mt == MemberTypes.NestedType)) {
+ if (IsGenericType (t) && (mt == MemberTypes.NestedType)) {
//
// This happens if we're resolving a class'es base class and interfaces
// in TypeContainer.DefineType(). At this time, the types aren't
used_cache = false;
return info;
}
-#endif
//
// This call will always succeed. There is exactly one TypeHandle instance per
return true;
#if MS_COMPATIBLE && GMCS_SOURCE
- if (t.IsGenericParameter)
+ if (t.IsGenericParameter || t.IsGenericType)
return false;
#endif
return t.IsEnum;
public static bool IsSubclassOf (Type type, Type base_type)
{
-#if GMCS_SOURCE
TypeParameter tparam = LookupTypeParameter (type);
TypeParameter pparam = LookupTypeParameter (base_type);
return tparam.IsSubclassOf (base_type);
}
-#if MS_COMPATIBLE
+#if MS_COMPATIBLE && GMCS_SOURCE
if (type.IsGenericType)
type = type.GetGenericTypeDefinition ();
-#endif
#endif
if (type.IsSubclassOf (base_type))
public static bool IsFamilyAccessible (Type type, Type parent)
{
-#if GMCS_SOURCE
TypeParameter tparam = LookupTypeParameter (type);
TypeParameter pparam = LookupTypeParameter (parent);
return tparam.IsSubclassOf (parent);
}
-#endif
do {
if (IsInstantiationOfSameGenericType (type, parent))
return target_list;
}
+#region Generics
+ // <remarks>
+ // Tracks the generic parameters.
+ // </remarks>
+ static PtrHashtable builder_to_type_param;
+
+ public static void AddTypeParameter (Type t, TypeParameter tparam)
+ {
+ if (!builder_to_type_param.Contains (t))
+ builder_to_type_param.Add (t, tparam);
+ }
+
+ public static TypeParameter LookupTypeParameter (Type t)
+ {
+ return (TypeParameter) builder_to_type_param [t];
+ }
+
// This method always return false for non-generic compiler,
// while Type.IsGenericParameter is returned if it is supported.
public static bool IsGenericParameter (Type type)
#endif
}
-#if !GMCS_SOURCE
+ public static bool IsGenericTypeDefinition (Type type)
+ {
+#if GMCS_SOURCE
+ return type.IsGenericTypeDefinition;
+#else
+ return false;
+#endif
+ }
+
+ public static bool ContainsGenericParameters (Type type)
+ {
+#if GMCS_SOURCE
+ return type.ContainsGenericParameters;
+#else
+ return false;
+#endif
+ }
+
+ public static FieldInfo GetGenericFieldDefinition (FieldInfo fi)
+ {
+#if GMCS_SOURCE
+ if (fi.DeclaringType.IsGenericTypeDefinition ||
+ !fi.DeclaringType.IsGenericType)
+ return fi;
+
+ Type t = fi.DeclaringType.GetGenericTypeDefinition ();
+ BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic |
+ BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
+
+ foreach (FieldInfo f in t.GetFields (bf))
+ if (f.MetadataToken == fi.MetadataToken)
+ return f;
+#endif
+
+ return fi;
+ }
+
public static bool IsEqual (Type a, Type b)
{
- return a.Equals (b);
+ if (a.Equals (b))
+ return true;
+
+#if GMCS_SOURCE
+ if (a.IsGenericParameter && b.IsGenericParameter) {
+ if (a.DeclaringMethod != b.DeclaringMethod &&
+ (a.DeclaringMethod == null || b.DeclaringMethod == null))
+ return false;
+ return a.GenericParameterPosition == b.GenericParameterPosition;
+ }
+
+ if (a.IsArray && b.IsArray) {
+ if (a.GetArrayRank () != b.GetArrayRank ())
+ return false;
+ return IsEqual (a.GetElementType (), b.GetElementType ());
+ }
+
+ if (a.IsByRef && b.IsByRef)
+ return IsEqual (a.GetElementType (), b.GetElementType ());
+
+ if (a.IsGenericType && b.IsGenericType) {
+ if (a.GetGenericTypeDefinition () != b.GetGenericTypeDefinition ())
+ return false;
+
+ Type[] aargs = a.GetGenericArguments ();
+ Type[] bargs = b.GetGenericArguments ();
+
+ if (aargs.Length != bargs.Length)
+ return false;
+
+ for (int i = 0; i < aargs.Length; i++) {
+ if (!IsEqual (aargs [i], bargs [i]))
+ return false;
+ }
+
+ return true;
+ }
+#endif
+
+ return false;
}
public static Type DropGenericTypeArguments (Type t)
{
+#if GMCS_SOURCE
+ if (!t.IsGenericType)
+ return t;
+ // Micro-optimization: a generic typebuilder is always a generic type definition
+ if (t is TypeBuilder)
+ return t;
+ return t.GetGenericTypeDefinition ();
+#else
return t;
+#endif
}
public static MethodBase DropGenericMethodArguments (MethodBase m)
{
+#if GMCS_SOURCE
+ if (m.IsGenericMethodDefinition)
+ return m;
+ if (m.IsGenericMethod)
+ return ((MethodInfo) m).GetGenericMethodDefinition ();
+ if (!m.DeclaringType.IsGenericType)
+ return m;
+
+ Type t = m.DeclaringType.GetGenericTypeDefinition ();
+ BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic |
+ BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
+
+#if MS_COMPATIBLE
+ return m;
+#endif
+
+ if (m is ConstructorInfo) {
+ foreach (ConstructorInfo c in t.GetConstructors (bf))
+ if (c.MetadataToken == m.MetadataToken)
+ return c;
+ } else {
+ foreach (MethodBase mb in t.GetMethods (bf))
+ if (mb.MetadataToken == m.MetadataToken)
+ return mb;
+ }
+#endif
+
return m;
}
+
+ public static Type[] GetGenericArguments (MethodInfo mi)
+ {
+#if GMCS_SOURCE
+ return mi.GetGenericArguments ();
+#else
+ return Type.EmptyTypes;
#endif
+ }
+
+ public static Type[] GetTypeArguments (Type t)
+ {
+#if GMCS_SOURCE
+ DeclSpace tc = LookupDeclSpace (t);
+ if (tc != null) {
+ if (!tc.IsGeneric)
+ return Type.EmptyTypes;
+
+ TypeParameter[] tparam = tc.TypeParameters;
+ Type[] ret = new Type [tparam.Length];
+ for (int i = 0; i < tparam.Length; i++) {
+ ret [i] = tparam [i].Type;
+ if (ret [i] == null)
+ throw new InternalErrorException ();
+ }
+
+ return ret;
+ } else
+ return t.GetGenericArguments ();
+#else
+ throw new InternalErrorException ();
+#endif
+ }
+
+ public static bool HasGenericArguments (Type t)
+ {
+ return GetNumberOfTypeArguments (t) > 0;
+ }
public static int GetNumberOfTypeArguments (Type t)
{
return type.Equals (parent);
}
+ /// <summary>
+ /// Whether `mb' is a generic method definition.
+ /// </summary>
+ public static bool IsGenericMethodDefinition (MethodBase mb)
+ {
+#if GMCS_SOURCE
+ if (mb.DeclaringType is TypeBuilder) {
+ IMethodData method = (IMethodData) builder_to_method [mb];
+ if (method == null)
+ return false;
+
+ return method.GenericMethod != null;
+ }
+
+ return mb.IsGenericMethodDefinition;
+#else
+ return false;
+#endif
+ }
+
+ /// <summary>
+ /// Whether `mb' is a generic method.
+ /// </summary>
+ public static bool IsGenericMethod (MethodBase mb)
+ {
+#if GMCS_SOURCE
+ if (mb.DeclaringType is TypeBuilder) {
+ IMethodData method = (IMethodData) builder_to_method [mb];
+ if (method == null)
+ return false;
+
+ return method.GenericMethod != null;
+ }
+
+ return mb.IsGenericMethod;
+#else
+ return false;
+#endif
+ }
+
+ public static bool IsNullableType (Type t)
+ {
+#if GMCS_SOURCE
+ return generic_nullable_type == DropGenericTypeArguments (t);
+#else
+ return false;
+#endif
+ }
+
+ public static bool IsNullableTypeOf (Type t, Type nullable)
+ {
+#if GMCS_SOURCE
+ if (!IsNullableType (t))
+ return false;
+
+ return GetTypeArguments (t) [0] == nullable;
+#else
+ return false;
+#endif
+ }
+
+ public static bool IsNullableValueType (Type t)
+ {
+#if GMCS_SOURCE
+ if (!IsNullableType (t))
+ return false;
+
+ return GetTypeArguments (t) [0].IsValueType;
+#else
+ return false;
+#endif
+ }
+#endregion
+
#region MemberLookup implementation
//
if (ma == MethodAttributes.Public)
return true;
-
+
+ if (ma == MethodAttributes.PrivateScope)
+ return false;
+
if (ma == MethodAttributes.Private)
return private_ok ||
IsPrivateAccessible (invocation_type, m.DeclaringType) ||
if (fa == FieldAttributes.Public)
return true;
-
+
+ if (fa == FieldAttributes.PrivateScope)
+ return false;
+
if (fa == FieldAttributes.Private)
return private_ok ||
IsPrivateAccessible (invocation_type, m.DeclaringType) ||
public MemberList GetMembers (MemberTypes mt, BindingFlags bf)
{
MemberInfo [] members;
+
#if GMCS_SOURCE
if (type is GenericTypeParameterBuilder)
return MemberList.Empty;
#endif
+
if (mt == MemberTypes.Event)
members = type.GetEvents (bf | BindingFlags.DeclaredOnly);
else