2004-11-10 Martin Baulig <martin@localhost>
[mono.git] / mcs / gmcs / typemanager.cs
index 00e763f5c5f6030a503f9ae461501d9208d72061..7e08cc98e869e2dc961c620cfd63933cef7e337e 100755 (executable)
@@ -121,6 +121,7 @@ public class TypeManager {
        static public TypeExpr system_asynccallback_expr;
        static public TypeExpr system_iasyncresult_expr;
        static public TypeExpr system_valuetype_expr;
+       static public TypeExpr system_intptr_expr;
 
        //
        // This is only used when compiling corlib
@@ -361,6 +362,7 @@ public class TypeManager {
                system_asynccallback_expr = new TypeLookupExpression ("System.AsyncCallback");
                system_iasyncresult_expr = new TypeLookupExpression ("System.IAsyncResult");
                system_valuetype_expr  = new TypeLookupExpression ("System.ValueType");
+               system_intptr_expr  = new TypeLookupExpression ("System.IntPtr");
        }
 
        static TypeManager ()
@@ -496,6 +498,14 @@ public class TypeManager {
        {
                return builder_to_declspace [t] as TypeContainer;
        }
+
+       public static TypeContainer LookupGenericTypeContainer (Type t)
+       {
+               while (t.IsGenericInstance)
+                       t = t.GetGenericTypeDefinition ();
+
+               return LookupTypeContainer (t);
+       }
        
        public static IMemberContainer LookupMemberContainer (Type t)
        {
@@ -545,19 +555,24 @@ public class TypeManager {
        }
 
        public static bool HasConstructorConstraint (Type t)
+       {
+               GenericConstraints gc = GetTypeParameterConstraints (t);
+               if (gc == null)
+                       return false;
+
+               return (gc.Attributes & GenericParameterAttributes.DefaultConstructorConstraint) != 0;
+       }
+
+       public static GenericConstraints GetTypeParameterConstraints (Type t)
        {
                if (!t.IsGenericParameter)
                        throw new InvalidOperationException ();
 
                TypeParameter tparam = LookupTypeParameter (t);
                if (tparam != null)
-                       return tparam.HasConstructorConstraint;
-               else {
-                       object[] attrs = t.GetCustomAttributes (
-                               TypeManager.new_constraint_attr_type, false);
+                       return tparam.GenericConstraints;
 
-                       return attrs.Length > 0;
-               }
+               return new ReflectionConstraints (t);
        }
        
        /// <summary>
@@ -1712,8 +1727,11 @@ public class TypeManager {
                return tc.Kind == Kind.Interface;
        }
 
-       public static bool IsEqualGenericType (Type a, Type b)
+       public static bool IsEqual (Type a, Type b)
        {
+               if (a.Equals (b))
+                       return true;
+
                if ((a is TypeBuilder) && a.IsGenericTypeDefinition && b.IsGenericInstance) {
                        //
                        // `a' is a generic type definition's TypeBuilder and `b' is a
@@ -1729,6 +1747,9 @@ public class TypeManager {
                        // The first argument of `Test' will be the generic instance
                        // "Stack<!0>" - which is the same type than the "Stack" TypeBuilder.
                        //
+                       //
+                       // We hit this via Closure.Filter() for gen-82.cs.
+                       //
                        if (a != b.GetGenericTypeDefinition ())
                                return false;
 
@@ -1739,21 +1760,46 @@ public class TypeManager {
                                return false;
 
                        for (int i = 0; i < aparams.Length; i++)
-                               if (!aparams [i].Equals (bparams [i]))
+                               if (!IsEqual (aparams [i], bparams [i]))
                                        return false;
 
                        return true;
                }
 
-               return false;
-       }
+               if (a.IsGenericParameter && b.IsGenericParameter) {
+                       if ((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.IsGenericInstance && b.IsGenericInstance) {
+                       Type at = a.GetGenericTypeDefinition ();
+                       Type bt = b.GetGenericTypeDefinition ();
+
+                       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;
+                       }
 
-       public static bool IsEqual (Type a, Type b)
-       {
-               if (a.Equals (b))
                        return true;
-               else
-                       return IsEqualGenericType (a, b);
+               }
+
+               return false;
        }
 
        public static bool MayBecomeEqualGenericTypes (Type a, Type b)
@@ -1900,6 +1946,48 @@ public class TypeManager {
                return false;
        }
 
+       public static bool IsPrivateAccessible (Type type, Type parent)
+       {
+               if (type.Equals (parent))
+                       return true;
+
+               if ((type is TypeBuilder) && type.IsGenericTypeDefinition && parent.IsGenericInstance) {
+                       //
+                       // `a' is a generic type definition's TypeBuilder and `b' is a
+                       // generic instance of the same type.
+                       //
+                       // Example:
+                       //
+                       // class Stack<T>
+                       // {
+                       //     void Test (Stack<T> stack) { }
+                       // }
+                       //
+                       // The first argument of `Test' will be the generic instance
+                       // "Stack<!0>" - which is the same type than the "Stack" TypeBuilder.
+                       //
+                       //
+                       // We hit this via Closure.Filter() for gen-82.cs.
+                       //
+                       if (type != parent.GetGenericTypeDefinition ())
+                               return false;
+
+                       return true;
+               }
+
+               if (type.IsGenericInstance && parent.IsGenericInstance) {
+                       Type tdef = type.GetGenericTypeDefinition ();
+                       Type pdef = parent.GetGenericTypeDefinition ();
+
+                       if (type.GetGenericTypeDefinition () != parent.GetGenericTypeDefinition ())
+                               return false;
+
+                       return true;
+               }
+
+               return false;
+       }
+
        public static bool IsFamilyAccessible (Type type, Type parent)
        {
                TypeParameter tparam = LookupTypeParameter (type);
@@ -2788,7 +2876,7 @@ public class TypeManager {
 
                        if (ma == MethodAttributes.Private)
                                return private_ok ||
-                                       IsEqual (invocation_type, mb.DeclaringType) ||
+                                       IsPrivateAccessible (invocation_type, mb.DeclaringType) ||
                                        IsNestedChildOf (invocation_type, mb.DeclaringType);
 
                        //
@@ -2839,7 +2927,7 @@ public class TypeManager {
 
                        if (fa == FieldAttributes.Private)
                                return private_ok ||
-                                       IsEqual (invocation_type, fi.DeclaringType) ||
+                                       IsPrivateAccessible (invocation_type, fi.DeclaringType) ||
                                        IsNestedChildOf (invocation_type, fi.DeclaringType);
 
                        //
@@ -2900,7 +2988,7 @@ public class TypeManager {
 
                        if (((qualifier_type == null) || (qualifier_type == invocation_type)) &&
                            (invocation_type != null) &&
-                           IsEqual (m.DeclaringType, invocation_type))
+                           IsPrivateAccessible (m.DeclaringType, invocation_type))
                                return true;
 
                        //
@@ -2923,7 +3011,6 @@ public class TypeManager {
 
        static Closure closure = new Closure ();
        static MemberFilter FilterWithClosure_delegate = new MemberFilter (closure.Filter);
-       static MemberFilter FilterNone_delegate = new MemberFilter (FilterNone);
 
        //
        // Looks up a member called `name' in the `queried_type'.  This lookup
@@ -3163,85 +3250,30 @@ public class TypeManager {
                return null;
        }
 
-       //
-       // This is used to extract properties and event declarations from a type
-       //
-       static MemberInfo [] SpecialContainerLookup (Type t, bool is_static)
-       {
-               BindingFlags bf = BindingFlags.DeclaredOnly | (is_static ? BindingFlags.Static : BindingFlags.Instance);
-
-               bf |= BindingFlags.Public | BindingFlags.NonPublic;
-               
-               if (t is TypeBuilder) {
-                       DeclSpace decl = (DeclSpace) builder_to_declspace [t];
-
-                       return (MemberInfo []) decl.FindMembers (
-                               MemberTypes.Property | MemberTypes.Event,
-                               bf, FilterNone_delegate, null);
-               } else {
-                       return t.FindMembers (MemberTypes.Property | MemberTypes.Event,
-                                             bf, FilterNone_delegate, null);
-
-               }
-       }
-       
+       // Tests whether external method is really special
        public static bool IsSpecialMethod (MethodBase mb)
        {
-               Type t = mb.DeclaringType;
-               
-               MemberInfo [] matches = TypeManager.SpecialContainerLookup (t, mb.IsStatic);
-               if (matches == null)
-                       return false;
-               
-               foreach (MemberInfo mi in matches){
-                       if (mi is PropertyBuilder){
-                               Pair p = (Pair) properties [mi];
-
-                               if (p.First == mb || p.Second == mb)
-                                       return true;
-                       } else if (mi is PropertyInfo){
-                               MethodInfo [] methods = ((PropertyInfo) mi).GetAccessors (true);
-                               
-                               foreach (MethodInfo m in methods){
-                                       if (m == mb)
-                                               return true;
-                               }
-                       } else if (mi is MyEventBuilder){
-                               Pair p = (Pair) events [mi];
-
-                               if (p.First == mb || p.Second == mb)
-                                       return true;
-                       } else if (mi is EventInfo){
-                               EventInfo ei = ((EventInfo) mi);
-                               
-                               if (ei.GetAddMethod (true) == mb)
-                                       return true;
-                               
-                               if (ei.GetRemoveMethod (true) == mb)
-                                       return true;
+               string name = mb.Name;
+               if (name.StartsWith ("get_") || name.StartsWith ("set_"))
+                       return mb.DeclaringType.GetProperty (name.Substring (4)) != null;
                                
-                               if (ei.GetRaiseMethod (true) == mb)
-                                       return true;
-                       }
-               }
+               if (name.StartsWith ("add_"))
+                       return mb.DeclaringType.GetEvent (name.Substring (4)) != null;
 
-               //
-               // Now check if it is an operator method
-               //
-               string s = mb.Name;
+               if (name.StartsWith ("remove_"))
+                       return mb.DeclaringType.GetEvent (name.Substring (7)) != null;
 
-               if (s.StartsWith ("op_")){
-                       foreach (string name in Unary.oper_names){
-                               if (s == name)
+               if (name.StartsWith ("op_")){
+                       foreach (string oname in Unary.oper_names) {
+                               if (oname == name)
                                        return true;
                        }
 
-                       foreach (string name in Binary.oper_names){
-                               if (s == name)
+                       foreach (string oname in Binary.oper_names) {
+                               if (oname == name)
                                        return true;
                        }
                }
-               
                return false;
        }