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