X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fgmcs%2Ftypemanager.cs;h=7e08cc98e869e2dc961c620cfd63933cef7e337e;hb=2ce246b7a6ce1690c9c866a59b098c82442c0841;hp=8bb5b151b955e3b927a7e800d291cf91c3125a51;hpb=9db6f795b5e607b9976d1701a50abf131906cfdd;p=mono.git diff --git a/mcs/gmcs/typemanager.cs b/mcs/gmcs/typemanager.cs index 8bb5b151b95..7e08cc98e86 100755 --- a/mcs/gmcs/typemanager.cs +++ b/mcs/gmcs/typemanager.cs @@ -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 @@ -184,6 +185,7 @@ public class TypeManager { static public ConstructorInfo void_decimal_ctor_five_args; static public ConstructorInfo unverifiable_code_ctor; static public ConstructorInfo invalid_operation_ctor; + static public ConstructorInfo default_member_ctor; // // Holds the Array of Assemblies that have been loaded @@ -360,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 () @@ -495,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) { @@ -544,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); } /// @@ -818,9 +834,6 @@ public class TypeManager { /// public static void LoadAllImportedTypes () { - if (!CodeGen.Assembly.IsClsCompliant) - return; - all_imported_types = new Hashtable (); foreach (Assembly a in assemblies) { foreach (Type t in a.GetExportedTypes ()) { @@ -850,7 +863,7 @@ public class TypeManager { @"^System\." + @"(Int32|UInt32|Int16|UInt16|Int64|UInt64|" + @"Single|Double|Char|Decimal|Byte|SByte|Object|" + - @"Boolean|String|Void)" + + @"Boolean|String|Void|Null)" + @"(\W+|\b)", new MatchEvaluator (CSharpNameMatch)); } @@ -965,7 +978,7 @@ public class TypeManager { iparams = new ReflectionParameters (mb); // Is property - if (mb.IsSpecialName && iparams.Count == 0) + if (mb.IsSpecialName && iparams.Count == 0 && !mb.IsConstructor) return GetFullNameSignature (mb); for (int i = 0; i < iparams.Count; i++) { @@ -977,7 +990,7 @@ public class TypeManager { sig.Append (")"); // Is indexer - if (mb.IsSpecialName && iparams.Count == 1) { + if (mb.IsSpecialName && iparams.Count == 1 && !mb.IsConstructor) { sig.Replace ('(', '['); sig.Replace (')', ']'); } @@ -1384,6 +1397,8 @@ public class TypeManager { unverifiable_code_ctor = GetConstructor ( unverifiable_code_type, void_arg); + default_member_ctor = GetConstructor (default_member_type, string_); + // // InvalidOperationException // @@ -1430,6 +1445,16 @@ public class TypeManager { if (t.IsSubclassOf (TypeManager.array_type)) return new MemberList (TypeManager.array_type.FindMembers (mt, bf, filter, criteria)); + if (t is GenericTypeParameterBuilder) { + TypeParameter tparam = (TypeParameter) builder_to_type_param [t]; + + Timer.StartTimer (TimerType.FindMembers); + MemberList list = tparam.FindMembers ( + mt, bf | BindingFlags.DeclaredOnly, filter, criteria); + Timer.StopTimer (TimerType.FindMembers); + return list; + } + // // Since FindMembers will not lookup both static and instance // members, we emulate this behaviour here. @@ -1702,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 @@ -1719,6 +1747,9 @@ public class TypeManager { // The first argument of `Test' will be the generic instance // "Stack" - 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; @@ -1729,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) @@ -1870,6 +1926,80 @@ public class TypeManager { public static bool IsSubclassOf (Type type, Type parent) { + TypeParameter tparam = LookupTypeParameter (type); + TypeParameter pparam = LookupTypeParameter (parent); + + if ((tparam != null) && (pparam != null)) { + if (tparam == pparam) + return true; + + return tparam.IsSubclassOf (parent); + } + + do { + if (type.Equals (parent)) + return true; + + type = type.BaseType; + } while (type != null); + + 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 + // { + // void Test (Stack stack) { } + // } + // + // The first argument of `Test' will be the generic instance + // "Stack" - 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); + TypeParameter pparam = LookupTypeParameter (parent); + + if ((tparam != null) && (pparam != null)) { + if (tparam == pparam) + return true; + + return tparam.IsSubclassOf (parent); + } + do { if (IsEqualGenericInstance (type, parent)) return true; @@ -1883,10 +2013,10 @@ public class TypeManager { // // Checks whether `type' is a subclass or nested child of `parent'. // - public static bool IsSubclassOrNestedChildOf (Type type, Type parent) + public static bool IsNestedFamilyAccessible (Type type, Type parent) { do { - if (IsSubclassOf (type, parent)) + if (IsFamilyAccessible (type, parent)) return true; // Handle nested types. @@ -1972,15 +2102,13 @@ public class TypeManager { /// for anything which is dynamic, and we need this in a number of places, /// we register this information here, and use it afterwards. /// - static public bool RegisterMethod (MethodBase mb, InternalParameters ip, Type [] args) + static public void RegisterMethod (MethodBase mb, InternalParameters ip, Type [] args) { if (args == null) args = NoTypes; method_arguments.Add (mb, args); method_internal_params.Add (mb, ip); - - return true; } static public InternalParameters LookupParametersByBuilder (MethodBase mb) @@ -2096,17 +2224,14 @@ public class TypeManager { static Hashtable events; - static public bool RegisterEvent (MyEventBuilder eb, MethodBase add, MethodBase remove) + static public void RegisterEvent (MyEventBuilder eb, MethodBase add, MethodBase remove) { if (events == null) events = new Hashtable (); - if (events.Contains (eb)) - return false; - + if (!events.Contains (eb)) { events.Add (eb, new Pair (add, remove)); - - return true; + } } static public MethodInfo GetAddMethod (EventInfo ei) @@ -2115,8 +2240,8 @@ public class TypeManager { Pair pair = (Pair) events [ei]; return (MethodInfo) pair.First; - } else - return ei.GetAddMethod (); + } + return ei.GetAddMethod (true); } static public MethodInfo GetRemoveMethod (EventInfo ei) @@ -2125,8 +2250,8 @@ public class TypeManager { Pair pair = (Pair) events [ei]; return (MethodInfo) pair.Second; - } else - return ei.GetRemoveMethod (); + } + return ei.GetRemoveMethod (true); } static Hashtable priv_fields_events; @@ -2566,7 +2691,7 @@ public class TypeManager { /// /// /// The default is not always `Item'. The user can change this behaviour by - /// using the DefaultMemberAttribute in the class. + /// using the IndexerNameAttribute in the container. /// /// For example, the String class indexer is named `Chars' not `Item' /// @@ -2576,21 +2701,8 @@ public class TypeManager { t = t.GetGenericTypeDefinition (); if (t is TypeBuilder) { - if (t.IsInterface) { - TypeContainer i = LookupInterface (t); - - if ((i == null) || (i.IndexerName == null)) - return "Item"; - - return i.IndexerName; - } else { - TypeContainer tc = LookupTypeContainer (t); - - if ((tc == null) || (tc.IndexerName == null)) - return "Item"; - - return tc.IndexerName; - } + TypeContainer tc = t.IsInterface ? LookupInterface (t) : LookupTypeContainer (t); + return tc == null ? TypeContainer.DefaultIndexerName : tc.IndexerName; } System.Attribute attr = System.Attribute.GetCustomAttribute ( @@ -2600,7 +2712,7 @@ public class TypeManager { return dma.MemberName; } - return "Item"; + return TypeContainer.DefaultIndexerName; } static MethodInfo declare_local_method = null; @@ -2764,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); // @@ -2791,14 +2903,14 @@ public class TypeManager { if (invocation_type == null) return false; - if (!IsSubclassOrNestedChildOf (invocation_type, mb.DeclaringType)) + if (!IsNestedFamilyAccessible (invocation_type, mb.DeclaringType)) return false; // Although a derived class can access protected members of its base class // it cannot do so through an instance of the base class (CS1540). if (!mb.IsStatic && (qualifier_type != null) && !IsEqualGenericInstance (invocation_type, qualifier_type) && - TypeManager.IsSubclassOf (invocation_type, qualifier_type) && + TypeManager.IsFamilyAccessible (invocation_type, qualifier_type) && !TypeManager.IsNestedChildOf (invocation_type, qualifier_type)) return false; @@ -2815,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); // @@ -2842,14 +2954,14 @@ public class TypeManager { if (invocation_type == null) return false; - if (!IsSubclassOrNestedChildOf (invocation_type, fi.DeclaringType)) + if (!IsNestedFamilyAccessible (invocation_type, fi.DeclaringType)) return false; // Although a derived class can access protected members of its base class // it cannot do so through an instance of the base class (CS1540). if (!fi.IsStatic && (qualifier_type != null) && !IsEqualGenericInstance (invocation_type, qualifier_type) && - TypeManager.IsSubclassOf (invocation_type, qualifier_type) && + TypeManager.IsFamilyAccessible (invocation_type, qualifier_type) && !TypeManager.IsNestedChildOf (invocation_type, qualifier_type)) return false; @@ -2876,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; // @@ -2899,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 @@ -3139,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; } @@ -3317,7 +3373,7 @@ public sealed class TypeHandle : IMemberContainer { } } - public IMemberContainer Parent { + public IMemberContainer ParentContainer { get { return BaseType; }