X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Ftypemanager.cs;h=308faf58212b6d1db024b322a0a3047d32450a89;hb=e0df8328d11d79623c1b0369cf15544b26a18db0;hp=967a23de1558fdf3234f7ec566d39bb04f2d2b58;hpb=505e4ef0ada0a6ddf5f9c512f1c7588d2f8ce112;p=mono.git diff --git a/mcs/mcs/typemanager.cs b/mcs/mcs/typemanager.cs index 967a23de155..308faf58212 100644 --- a/mcs/mcs/typemanager.cs +++ b/mcs/mcs/typemanager.cs @@ -70,6 +70,7 @@ public partial class TypeManager { 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; @@ -269,6 +270,7 @@ public partial class TypeManager { 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; @@ -282,8 +284,6 @@ public partial class TypeManager { #if GMCS_SOURCE assembly_internals_vis_attrs = null; - - CleanUpGenerics (); #endif TypeHandle.CleanUp (); @@ -299,7 +299,7 @@ public partial class TypeManager { if (!(mi is MethodBase)) return false; - + if (mi.Name != sig.name) return false; @@ -373,6 +373,7 @@ public partial class TypeManager { 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 (); @@ -385,8 +386,6 @@ public partial class TypeManager { #if GMCS_SOURCE assembly_internals_vis_attrs = new PtrHashtable (); - - InitGenerics (); #endif // to uncover regressions @@ -438,6 +437,11 @@ public partial class TypeManager { 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) @@ -901,7 +905,7 @@ public partial class TypeManager { 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); } @@ -1020,6 +1024,7 @@ public partial class TypeManager { 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"); @@ -1340,7 +1345,7 @@ public partial class TypeManager { MemberFilter filter, object criteria) { #if MS_COMPATIBLE && GMCS_SOURCE - if (t.IsGenericType) + if (t.IsGenericType && !t.IsGenericTypeDefinition) t = t.GetGenericTypeDefinition (); #endif @@ -1430,6 +1435,11 @@ public partial class TypeManager { { 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. @@ -1465,7 +1475,7 @@ public partial class TypeManager { // 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); @@ -1483,8 +1493,9 @@ public partial class TypeManager { 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 @@ -1495,7 +1506,6 @@ public partial class TypeManager { used_cache = false; return info; } -#endif // // This call will always succeed. There is exactly one TypeHandle instance per @@ -1552,7 +1562,7 @@ public partial class TypeManager { return true; #if MS_COMPATIBLE && GMCS_SOURCE - if (t.IsGenericParameter) + if (t.IsGenericParameter || t.IsGenericType) return false; #endif return t.IsEnum; @@ -1669,7 +1679,6 @@ public partial class TypeManager { public static bool IsSubclassOf (Type type, Type base_type) { -#if GMCS_SOURCE TypeParameter tparam = LookupTypeParameter (type); TypeParameter pparam = LookupTypeParameter (base_type); @@ -1680,10 +1689,9 @@ public partial class TypeManager { 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)) @@ -1712,7 +1720,6 @@ public partial class TypeManager { public static bool IsFamilyAccessible (Type type, Type parent) { -#if GMCS_SOURCE TypeParameter tparam = LookupTypeParameter (type); TypeParameter pparam = LookupTypeParameter (parent); @@ -1722,7 +1729,6 @@ public partial class TypeManager { return tparam.IsSubclassOf (parent); } -#endif do { if (IsInstantiationOfSameGenericType (type, parent)) @@ -2639,6 +2645,23 @@ public partial class TypeManager { return target_list; } +#region Generics + // + // Tracks the generic parameters. + // + 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) @@ -2668,22 +2691,170 @@ public partial class TypeManager { #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) { @@ -2718,6 +2889,80 @@ public partial class TypeManager { return type.Equals (parent); } + /// + /// Whether `mb' is a generic method definition. + /// + 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 + } + + /// + /// Whether `mb' is a generic method. + /// + 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 // @@ -2796,7 +3041,10 @@ public partial class TypeManager { if (ma == MethodAttributes.Public) return true; - + + if (ma == MethodAttributes.PrivateScope) + return false; + if (ma == MethodAttributes.Private) return private_ok || IsPrivateAccessible (invocation_type, m.DeclaringType) || @@ -2821,7 +3069,10 @@ public partial class TypeManager { if (fa == FieldAttributes.Public) return true; - + + if (fa == FieldAttributes.PrivateScope) + return false; + if (fa == FieldAttributes.Private) return private_ok || IsPrivateAccessible (invocation_type, m.DeclaringType) || @@ -3226,10 +3477,12 @@ public sealed class TypeHandle : IMemberContainer { 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