Tue Nov 14 16:06:37 CET 2006 Paolo Molaro <lupus@ximian.com>
[mono.git] / mcs / mcs / typemanager.cs
index 615741ffae3290b7642394df06e4c2b045ebec4e..308faf58212b6d1db024b322a0a3047d32450a89 100644 (file)
@@ -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;
@@ -298,7 +299,7 @@ public partial class TypeManager {
 
                if (!(mi is MethodBase))
                        return false;
-               
+
                if (mi.Name != sig.name)
                        return false;
 
@@ -436,18 +437,25 @@ 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)
                                return container.MemberCache;
                }
 
+#if GMCS_SOURCE
                if (t is GenericTypeParameterBuilder) {
                        IMemberContainer container = builder_to_type_param [t] as IMemberContainer;
 
                        if (container != null)
                                return container.MemberCache;
                }
+#endif
 
                return TypeHandle.GetMemberCache (t);
        }
@@ -897,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);
        }
@@ -1016,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");
@@ -1336,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
 
@@ -1365,6 +1374,7 @@ public partial class TypeManager {
                        t.IsSubclassOf (TypeManager.array_type))
                        return new MemberList (TypeManager.array_type.FindMembers (mt, bf, filter, criteria));
 
+#if GMCS_SOURCE
                if (t is GenericTypeParameterBuilder) {
                        TypeParameter tparam = (TypeParameter) builder_to_type_param [t];
 
@@ -1374,6 +1384,7 @@ public partial class TypeManager {
                        Timer.StopTimer (TimerType.FindMembers);
                        return list;
                }
+#endif
 
                //
                // Since FindMembers will not lookup both static and instance
@@ -1424,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.
@@ -1459,12 +1475,13 @@ 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);
                }
 
+#if GMCS_SOURCE
                if (t is GenericTypeParameterBuilder) {
                        TypeParameter tparam = (TypeParameter) builder_to_type_param [t];
 
@@ -1476,6 +1493,7 @@ public partial class TypeManager {
                        used_cache = true;
                        return (MemberInfo []) list;
                }
+#endif
 
                if (IsGenericType (t) && (mt == MemberTypes.NestedType)) {
                        //
@@ -1544,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;
@@ -2211,6 +2229,7 @@ public partial class TypeManager {
 
                        iface_cache [t] = result;
                        return result;
+#if GMCS_SOURCE
                } else if (t is GenericTypeParameterBuilder){
                        Type[] type_ifaces = (Type []) builder_to_ifaces [t];
                        if (type_ifaces == null || type_ifaces.Length == 0)
@@ -2218,6 +2237,7 @@ public partial class TypeManager {
 
                        iface_cache [t] = type_ifaces;
                        return type_ifaces;
+#endif
                } else {
                        Type[] ifaces = t.GetInterfaces ();
                        iface_cache [t] = ifaces;
@@ -2671,6 +2691,15 @@ public partial class TypeManager {
 #endif
        }
 
+       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
@@ -2680,6 +2709,25 @@ public partial class TypeManager {
 #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)
        {
                if (a.Equals (b))
@@ -2752,6 +2800,10 @@ public partial class TypeManager {
                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)
@@ -2874,6 +2926,39 @@ public partial class TypeManager {
                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
@@ -2956,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) ||
@@ -2981,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) ||
@@ -3387,8 +3478,10 @@ public sealed class TypeHandle : IMemberContainer {
        {
                 MemberInfo [] members;
 
+#if GMCS_SOURCE
                if (type is GenericTypeParameterBuilder)
                        return MemberList.Empty;
+#endif
 
                if (mt == MemberTypes.Event)
                         members = type.GetEvents (bf | BindingFlags.DeclaredOnly);