X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fgmcs%2Ftypemanager.cs;h=6fa5127dbe0a066c3309ff3a1668d2375a957174;hb=215c1cd77483d5c0018469905265023f3f8df7ee;hp=8bb5b151b955e3b927a7e800d291cf91c3125a51;hpb=9db6f795b5e607b9976d1701a50abf131906cfdd;p=mono.git diff --git a/mcs/gmcs/typemanager.cs b/mcs/gmcs/typemanager.cs old mode 100755 new mode 100644 index 8bb5b151b95..6fa5127dbe0 --- a/mcs/gmcs/typemanager.cs +++ b/mcs/gmcs/typemanager.cs @@ -30,7 +30,7 @@ using System.Diagnostics; namespace Mono.CSharp { -public class TypeManager { +public partial class TypeManager { // // A list of core types that the compiler requires or uses // @@ -55,6 +55,7 @@ public class TypeManager { static public Type delegate_type; static public Type multicast_delegate_type; static public Type void_type; + static public Type null_type; static public Type enumeration_type; static public Type array_type; static public Type runtime_handle_type; @@ -73,31 +74,37 @@ public class TypeManager { static public Type runtime_argument_handle_type; static public Type attribute_type; static public Type attribute_usage_type; + static public Type decimal_constant_attribute_type; static public Type dllimport_type; static public Type unverifiable_code_type; static public Type methodimpl_attr_type; static public Type marshal_as_attr_type; - static public Type new_constraint_attr_type; static public Type param_array_type; - static public Type guid_attr_type; static public Type void_ptr_type; static public Type indexer_name_type; static public Type exception_type; - static public Type activator_type; static public Type invalid_operation_exception_type; static public Type not_supported_exception_type; static public Type obsolete_attribute_type; static public Type conditional_attribute_type; static public Type in_attribute_type; + static public Type out_attribute_type; + static public Type anonymous_method_type; static public Type cls_compliant_attribute_type; static public Type typed_reference_type; static public Type arg_iterator_type; static public Type mbr_type; static public Type struct_layout_attribute_type; static public Type field_offset_attribute_type; + static public Type security_attr_type; + static public Type required_attr_type; - static public Type generic_ienumerator_type; - static public Type generic_ienumerable_type; + /// + /// .NET 2.0 + /// + static internal Type compiler_generated_attr_type; + static internal Type fixed_buffer_attr_type; + static internal Type default_charset_type; // // An empty array of types @@ -121,6 +128,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 @@ -174,7 +182,6 @@ public class TypeManager { static public MethodInfo int_array_get_lower_bound_int; static public MethodInfo int_array_get_upper_bound_int; static public MethodInfo void_array_copyto_array_int; - static public MethodInfo activator_create_instance; // // The attribute constructors. @@ -182,9 +189,19 @@ public class TypeManager { static public ConstructorInfo object_ctor; static public ConstructorInfo cons_param_array_attribute; static public ConstructorInfo void_decimal_ctor_five_args; + static public ConstructorInfo void_decimal_ctor_int_arg; static public ConstructorInfo unverifiable_code_ctor; - static public ConstructorInfo invalid_operation_ctor; + static public ConstructorInfo default_member_ctor; + static public ConstructorInfo decimal_constant_attribute_ctor; + static internal ConstructorInfo struct_layout_attribute_ctor; + static public ConstructorInfo field_offset_attribute_ctor; + /// + /// A new in C# 2.0 + /// + static internal CustomAttributeBuilder compiler_generated_attr; + static internal ConstructorInfo fixed_buffer_attr_ctor; + // // Holds the Array of Assemblies that have been loaded // (either because it is the default or the user used the @@ -218,17 +235,14 @@ public class TypeManager { static PtrHashtable builder_to_declspace; + static PtrHashtable builder_to_member_cache; + // // Tracks the interfaces implemented by typebuilders. We only // enter those who do implement or or more interfaces // static PtrHashtable builder_to_ifaces; - // - // Tracks the generic parameters. - // - static PtrHashtable builder_to_type_param; - // // Maps MethodBase.RuntimeTypeHandle to a Type array that contains // the arguments to the method @@ -242,10 +256,9 @@ public class TypeManager { static Hashtable indexer_arguments; // - // Maybe `method_arguments' should be replaced and only - // method_internal_params should be kept? + // Maps a MethodBase to its ParameterData (either InternalParameters or ReflectionParameters) // - static Hashtable method_internal_params; + static Hashtable method_params; // // Keeps track of methods @@ -259,6 +272,9 @@ public class TypeManager { // public static Hashtable all_imported_types; + static Hashtable fieldbuilders_to_fields; + static Hashtable fields; + struct Signature { public string name; public Type [] args; @@ -273,22 +289,23 @@ public class TypeManager { typecontainers = null; user_types = null; builder_to_declspace = null; + builder_to_member_cache = null; builder_to_ifaces = null; method_arguments = null; indexer_arguments = null; - method_internal_params = null; + method_params = null; builder_to_method = null; - builder_to_type_param = null; fields = null; - references = null; - negative_hits = null; builder_to_constant = null; fieldbuilders_to_fields = null; events = null; priv_fields_events = null; properties = null; + + type_hash = null; + CleanUpGenerics (); TypeHandle.CleanUp (); } @@ -360,9 +377,19 @@ 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 () + { + Reset (); + + signature_filter = new MemberFilter (SignatureFilter); + InitExpressionTypes (); + InitGenerics (); + } + + static public void Reset () { assemblies = new Assembly [0]; modules = null; @@ -372,18 +399,19 @@ public class TypeManager { typecontainers = new Hashtable (); builder_to_declspace = new PtrHashtable (); + builder_to_member_cache = new PtrHashtable (); builder_to_method = new PtrHashtable (); method_arguments = new PtrHashtable (); - method_internal_params = new PtrHashtable (); + method_params = new PtrHashtable (); indexer_arguments = new PtrHashtable (); builder_to_ifaces = new PtrHashtable (); - builder_to_type_param = new PtrHashtable (); NoTypes = new Type [0]; NoTypeExprs = new TypeExpr [0]; - signature_filter = new MemberFilter (SignatureFilter); - InitExpressionTypes (); + fieldbuilders_to_fields = new Hashtable (); + fields = new Hashtable (); + type_hash = new DoubleHash (); } public static void HandleDuplicate (string name, Type t) @@ -422,6 +450,7 @@ public class TypeManager { } catch { HandleDuplicate (name, t); } + user_types.Add (t); } @@ -472,12 +501,6 @@ public class TypeManager { return (IMethodData) builder_to_method [builder]; } - public static void AddTypeParameter (Type t, TypeParameter tparam) - { - if (!builder_to_type_param.Contains (t)) - builder_to_type_param.Add (t, tparam); - } - /// /// Returns the DeclSpace whose Type is `t' or null if there is no /// DeclSpace for `t' (ie, the Type comes from a library) @@ -495,23 +518,40 @@ public class TypeManager { { return builder_to_declspace [t] as TypeContainer; } - - public static IMemberContainer LookupMemberContainer (Type t) + + public static MemberCache LookupMemberCache (Type t) { if (t is TypeBuilder) { IMemberContainer container = builder_to_declspace [t] as IMemberContainer; if (container != null) - return container; + return container.MemberCache; } if (t is GenericTypeParameterBuilder) { IMemberContainer container = builder_to_type_param [t] as IMemberContainer; if (container != null) - return container; + return container.MemberCache; } - return TypeHandle.GetTypeHandle (t); + return TypeHandle.GetMemberCache (t); + } + + public static MemberCache LookupBaseInterfacesCache (Type t) + { + Type [] ifaces = t.GetInterfaces (); + + if (ifaces != null && ifaces.Length == 1) + return LookupMemberCache (ifaces [0]); + + // TODO: the builder_to_member_cache should be indexed by 'ifaces', not 't' + MemberCache cache = builder_to_member_cache [t] as MemberCache; + if (cache != null) + return cache; + + cache = new MemberCache (ifaces); + builder_to_member_cache.Add (t, cache); + return cache; } public static TypeContainer LookupInterface (Type t) @@ -537,27 +577,6 @@ public class TypeManager { { return (Class) builder_to_declspace [t]; } - - public static TypeParameter LookupTypeParameter (Type t) - { - return (TypeParameter) builder_to_type_param [t]; - } - - public static bool HasConstructorConstraint (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 attrs.Length > 0; - } - } /// /// Registers an assembly to load types from. @@ -603,8 +622,18 @@ public class TypeManager { } } - static Hashtable references = new Hashtable (); - + // + // We use this hash for multiple kinds of constructed types: + // + // (T, "&") Given T, get T & + // (T, "*") Given T, get T * + // (T, "[]") Given T and a array dimension, get T [] + // (T, X) Given a type T and a simple name X, get the type T+X + // + // Accessibility tests, if necessary, should be done by the user + // + static DoubleHash type_hash = new DoubleHash (); + // // Gets the reference to T version of the Type (T&) // @@ -613,36 +642,82 @@ public class TypeManager { return t.MakeByRefType (); } - static Hashtable pointers = new Hashtable (); - // // Gets the pointer to T version of the Type (T*) // public static Type GetPointerType (Type t) { - string tname = t.FullName + "*"; - - Type ret = t.Assembly.GetType (tname); - - // - // If the type comes from the assembly we are building - // We need the Hashtable, because .NET 1.1 will return different instance types - // every time we call ModuleBuilder.GetType. - // - if (ret == null){ - if (pointers [t] == null) - pointers [t] = CodeGen.Module.Builder.GetType (tname); - - ret = (Type) pointers [t]; + return GetConstructedType (t, "*"); + } + + public static Type GetConstructedType (Type t, string dim) + { + object ret = null; + if (type_hash.Lookup (t, dim, out ret)) + return (Type) ret; + + ret = t.Module.GetType (t.ToString () + dim); + if (ret != null) { + type_hash.Insert (t, dim, ret); + return (Type) ret; } - return ret; + if (dim == "&") { + ret = GetReferenceType (t); + type_hash.Insert (t, dim, ret); + return (Type) ret; + } + + if (t.IsGenericParameter || t.IsGenericInstance) { + int pos = 0; + Type result = t; + while ((pos < dim.Length) && (dim [pos] == '[')) { + pos++; + + if (dim [pos] == ']') { + result = result.MakeArrayType (); + pos++; + + if (pos < dim.Length) + continue; + + type_hash.Insert (t, dim, result); + return result; + } + + int rank = 0; + while (dim [pos] == ',') { + pos++; rank++; + } + + if ((dim [pos] != ']') || (pos != dim.Length-1)) + break; + + result = result.MakeArrayType (rank + 1); + type_hash.Insert (t, dim, result); + return result; + } + } + + type_hash.Insert (t, dim, null); + return null; + } + + public static Type GetNestedType (Type t, string name) + { + object ret = null; + if (!type_hash.Lookup (t, name, out ret)) { + string lookup = t.FullName + "+" + name; + ret = t.Module.GetType (lookup); + type_hash.Insert (t, name, ret); + } + return (Type) ret; } // // Low-level lookup, cache-less // - static Type LookupTypeReflection (string name) + public static Type LookupTypeReflection (string name) { Type t; @@ -682,98 +757,6 @@ public class TypeManager { return null; } - static Hashtable negative_hits = new Hashtable (); - - // - // This function is used when you want to avoid the lookups, and want to go - // directly to the source. This will use the cache. - // - // Notice that bypassing the cache is bad, because on Microsoft.NET runtime - // GetType ("DynamicType[]") != GetType ("DynamicType[]"), and there is no - // way to test things other than doing a fullname compare - // - public static Type LookupTypeDirect (string name) - { - Type t = (Type) types [name]; - if (t != null) - return t; - - t = LookupTypeReflection (name); - if (t == null) - return null; - - types [name] = t; - return t; - } - - static readonly char [] dot_array = { '.' }; - - /// - /// Returns the Type associated with @name, takes care of the fact that - /// reflection expects nested types to be separated from the main type - /// with a "+" instead of a "." - /// - public static Type LookupType (string name) - { - Type t; - - // - // First lookup in user defined and cached values - // - - t = (Type) types [name]; - if (t != null) - return t; - - // Two thirds of the failures are caught here. - if (negative_hits.Contains (name)) - return null; - - // Sadly, split takes a param array, so this ends up allocating *EVERY TIME* - string [] elements = name.Split (dot_array); - int count = elements.Length; - - for (int n = 1; n <= count; n++){ - string top_level_type = String.Join (".", elements, 0, n); - - // One third of the failures are caught here. - if (negative_hits.Contains (top_level_type)) - continue; - - t = (Type) types [top_level_type]; - if (t == null){ - t = LookupTypeReflection (top_level_type); - if (t == null){ - negative_hits [top_level_type] = null; - continue; - } - } - - if (count == n){ - types [name] = t; - return t; - } - - // - // We know that System.Object does not have children, and since its the parent of - // all the objects, it always gets probbed for inner classes. - // - if (top_level_type == "System.Object") - return null; - - string newt = top_level_type + "+" + String.Join ("+", elements, n, count - n); - //Console.WriteLine ("Looking up: " + newt + " " + name); - t = LookupTypeReflection (newt); - if (t == null) - negative_hits [name] = null; - else - types [name] = t; - return t; - } - negative_hits [name] = null; - return null; - } - /// /// Computes the namespaces that we import from the assemblies we reference. /// @@ -781,6 +764,8 @@ public class TypeManager { { MethodInfo assembly_get_namespaces = typeof (Assembly).GetMethod ("GetNamespaces", BindingFlags.Instance|BindingFlags.NonPublic); + Hashtable cache = null; + // // First add the assembly namespaces // @@ -797,7 +782,7 @@ public class TypeManager { } } } else { - Hashtable cache = new Hashtable (); + cache = new Hashtable (); cache.Add ("", null); foreach (Assembly a in assemblies) { foreach (Type t in a.GetExportedTypes ()) { @@ -810,6 +795,25 @@ public class TypeManager { } } } + + // + // Then add module namespaces + // + foreach (Module m in modules) { + if (m == CodeGen.Module.Builder) + continue; + if (cache == null) { + cache = new Hashtable (); + cache.Add ("", null); + } + foreach (Type t in m.GetTypes ()) { + string ns = t.Namespace; + if (ns == null || cache.Contains (ns)) + continue; + Namespace.LookupNamespace (ns, true); + cache.Add (ns, null); + } + } } /// @@ -818,9 +822,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,10 +851,21 @@ 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)); + new MatchEvaluator (CSharpNameMatch)).Replace ('+', '.'); } + + static public string CSharpName (Type[] types) + { + StringBuilder sb = new StringBuilder (); + foreach (Type t in types) { + sb.Append (CSharpName (t)); + sb.Append (','); + } + sb.Remove (sb.Length - 1, 1); + return sb.ToString (); + } static String CSharpNameMatch (Match match) { @@ -875,7 +887,10 @@ public class TypeManager { /// static public string GetFullNameSignature (MemberInfo mi) { - return mi.DeclaringType.FullName.Replace ('+', '.') + '.' + mi.Name; + // Unfortunately, there's no dynamic dispatch on the arguments of a function. + return (mi is MethodBase) + ? GetFullNameSignature (mi as MethodBase) + : mi.DeclaringType.FullName.Replace ('+', '.') + '.' + mi.Name; } static public string GetFullNameSignature (MethodBase mb) @@ -896,41 +911,45 @@ public class TypeManager { return mb.DeclaringType.FullName.Replace ('+', '.') + '.' + name; } - static public string GetFullName (Type t) + private static void GetFullName_recursed (StringBuilder sb, Type t, bool recursed) { - if (t.FullName == null) - return t.Name; - - string name = t.FullName.Replace ('+', '.'); + if (t.IsGenericParameter) { + sb.Append (t.Name); + return; + } - DeclSpace tc = LookupDeclSpace (t); - if ((tc != null) && tc.IsGeneric) { - TypeParameter[] tparam = tc.TypeParameters; + if (t.DeclaringType != null) { + GetFullName_recursed (sb, t.DeclaringType, true); + sb.Append ("."); + } - StringBuilder sb = new StringBuilder (name); - sb.Append ("<"); - for (int i = 0; i < tparam.Length; i++) { - if (i > 0) - sb.Append (","); - sb.Append (tparam [i].Name); + if (!recursed) { + string ns = t.Namespace; + if ((ns != null) && (ns != "")) { + sb.Append (ns); + sb.Append ("."); } - sb.Append (">"); - return sb.ToString (); - } else if (t.HasGenericArguments && !t.IsGenericInstance) { - Type[] tparam = t.GetGenericArguments (); + } + + sb.Append (SimpleName.RemoveGenericArity (t.Name)); - StringBuilder sb = new StringBuilder (name); + Type[] args = GetTypeArguments (t); + if (args.Length > 0) { sb.Append ("<"); - for (int i = 0; i < tparam.Length; i++) { + for (int i = 0; i < args.Length; i++) { if (i > 0) sb.Append (","); - sb.Append (tparam [i].Name); + sb.Append (GetFullName (args [i])); } sb.Append (">"); - return sb.ToString (); } + } - return name; + static public string GetFullName (Type t) + { + StringBuilder sb = new StringBuilder (); + GetFullName_recursed (sb, t, false); + return sb.ToString (); } /// @@ -944,7 +963,7 @@ public class TypeManager { MethodBase mb = pb.GetSetMethod (true) != null ? pb.GetSetMethod (true) : pb.GetGetMethod (true); string signature = GetFullNameSignature (mb); - string arg = TypeManager.LookupParametersByBuilder (mb).ParameterDesc (0); + string arg = GetParameterData (mb).ParameterDesc (0); return String.Format ("{0}.this[{1}]", signature.Substring (0, signature.LastIndexOf ('.')), arg); } @@ -955,17 +974,10 @@ public class TypeManager { { StringBuilder sig = new StringBuilder ("("); - // - // FIXME: We should really have a single function to do - // everything instead of the following 5 line pattern - // - ParameterData iparams = LookupParametersByBuilder (mb); + ParameterData iparams = GetParameterData (mb); - if (iparams == null) - 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 +989,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 (')', ']'); } @@ -985,19 +997,30 @@ public class TypeManager { return GetFullNameSignature (mb) + sig.ToString (); } + public static string GetMethodName (MethodInfo m) + { + if (!IsGenericMethod (m)) + return m.Name; + + return MemberName.MakeName (m.Name, m.GetGenericArguments ().Length); + } + /// /// Looks up a type, and aborts if it is not found. This is used /// by types required by the compiler /// static Type CoreLookupType (string name) { - Type t = LookupTypeDirect (name); + Type t = null; + if (types.Contains (name)) + t = (Type) types [name]; + else + t = LookupTypeReflection (name); - if (t == null){ + if (t == null) Report.Error (518, "The predefined type `" + name + "' is not defined or imported"); - Environment.Exit (1); - } + types [name] = t; return t; } @@ -1048,7 +1071,7 @@ public class TypeManager { /// /// Returns the ConstructorInfo for "args" /// - static ConstructorInfo GetConstructor (Type t, Type [] args) + public static ConstructorInfo GetConstructor (Type t, Type [] args) { MemberList list; Signature sig; @@ -1134,18 +1157,13 @@ public class TypeManager { dllimport_type = CoreLookupType ("System.Runtime.InteropServices.DllImportAttribute"); methodimpl_attr_type = CoreLookupType ("System.Runtime.CompilerServices.MethodImplAttribute"); marshal_as_attr_type = CoreLookupType ("System.Runtime.InteropServices.MarshalAsAttribute"); - new_constraint_attr_type = CoreLookupType ("System.Runtime.CompilerServices.NewConstraintAttribute"); param_array_type = CoreLookupType ("System.ParamArrayAttribute"); in_attribute_type = CoreLookupType ("System.Runtime.InteropServices.InAttribute"); + out_attribute_type = CoreLookupType ("System.Runtime.InteropServices.OutAttribute"); typed_reference_type = CoreLookupType ("System.TypedReference"); arg_iterator_type = CoreLookupType ("System.ArgIterator"); mbr_type = CoreLookupType ("System.MarshalByRefObject"); - - // - // Sigh. Remove this before the release. Wonder what versions of Mono - // people are running. - // - guid_attr_type = LookupType ("System.Runtime.InteropServices.GuidAttribute"); + decimal_constant_attribute_type = CoreLookupType ("System.Runtime.CompilerServices.DecimalConstantAttribute"); unverifiable_code_type= CoreLookupType ("System.Security.UnverifiableCodeAttribute"); @@ -1154,7 +1172,6 @@ public class TypeManager { indexer_name_type = CoreLookupType ("System.Runtime.CompilerServices.IndexerNameAttribute"); exception_type = CoreLookupType ("System.Exception"); - activator_type = CoreLookupType ("System.Activator"); invalid_operation_exception_type = CoreLookupType ("System.InvalidOperationException"); not_supported_exception_type = CoreLookupType ("System.NotSupportedException"); @@ -1166,14 +1183,17 @@ public class TypeManager { cls_compliant_attribute_type = CoreLookupType ("System.CLSCompliantAttribute"); struct_layout_attribute_type = CoreLookupType ("System.Runtime.InteropServices.StructLayoutAttribute"); field_offset_attribute_type = CoreLookupType ("System.Runtime.InteropServices.FieldOffsetAttribute"); + security_attr_type = CoreLookupType ("System.Security.Permissions.SecurityAttribute"); + required_attr_type = CoreLookupType ("System.Runtime.CompilerServices.RequiredAttributeAttribute"); + + InitGenericCoreTypes (); // - // Generic types + // .NET 2.0 // - generic_ienumerator_type = CoreLookupType (MemberName.MakeName ("System.Collections.Generic.IEnumerator", 1)); - generic_ienumerable_type = CoreLookupType (MemberName.MakeName ("System.Collections.Generic.IEnumerable", 1)); - - + compiler_generated_attr_type = CoreLookupType ("System.Runtime.CompilerServices.CompilerGeneratedAttribute"); + fixed_buffer_attr_type = CoreLookupType ("System.Runtime.CompilerServices.FixedBufferAttribute"); + default_charset_type = CoreLookupType ("System.Runtime.InteropServices.DefaultCharSetAttribute"); // // When compiling corlib, store the "real" types here. // @@ -1259,6 +1279,12 @@ public class TypeManager { system_asynccallback_expr.Type = asynccallback_type; system_iasyncresult_expr.Type = iasyncresult_type; system_valuetype_expr.Type = value_type; + + // + // These are only used for compare purposes + // + anonymous_method_type = typeof (AnonymousMethod); + null_type = typeof (NullType); } // @@ -1278,7 +1304,7 @@ public class TypeManager { Type [] string_string_string_string = { string_type, string_type, string_type, string_type }; string_concat_string_string_string_string = GetMethod ( string_type, "Concat", string_string_string_string); - Type[] params_string = { TypeManager.LookupType ("System.String[]") }; + Type[] params_string = { GetConstructedType (string_type, "[]") }; string_concat_string_dot_dot_dot = GetMethod ( string_type, "Concat", params_string); @@ -1288,7 +1314,7 @@ public class TypeManager { Type [] object_object_object = { object_type, object_type, object_type }; string_concat_object_object_object = GetMethod ( string_type, "Concat", object_object_object); - Type[] params_object = { TypeManager.LookupType ("System.Object[]") }; + Type[] params_object = { GetConstructedType (object_type, "[]") }; string_concat_object_dot_dot_dot = GetMethod ( string_type, "Concat", params_object); @@ -1375,29 +1401,37 @@ public class TypeManager { void_decimal_ctor_five_args = GetConstructor ( decimal_type, dec_arg); + void_decimal_ctor_int_arg = GetConstructor (decimal_type, int_arg); + // // Attributes // - cons_param_array_attribute = GetConstructor ( - param_array_type, void_arg); + cons_param_array_attribute = GetConstructor (param_array_type, void_arg); + unverifiable_code_ctor = GetConstructor (unverifiable_code_type, void_arg); + default_member_ctor = GetConstructor (default_member_type, string_); + + Type[] short_arg = { short_type }; + struct_layout_attribute_ctor = GetConstructor (struct_layout_attribute_type, short_arg); + + decimal_constant_attribute_ctor = GetConstructor (decimal_constant_attribute_type, new Type [] + { byte_type, byte_type, uint32_type, uint32_type, uint32_type } ); - unverifiable_code_ctor = GetConstructor ( - unverifiable_code_type, void_arg); + field_offset_attribute_ctor = GetConstructor (field_offset_attribute_type, new Type [] + { int32_type }); // - // InvalidOperationException + // .NET 2.0 types // - invalid_operation_ctor = GetConstructor ( - invalid_operation_exception_type, void_arg); + compiler_generated_attr = new CustomAttributeBuilder ( + GetConstructor (compiler_generated_attr_type, void_arg), new object[0]); + Type[] type_int_arg = { type_type, int32_type }; + fixed_buffer_attr_ctor = GetConstructor (fixed_buffer_attr_type, type_int_arg); // Object object_ctor = GetConstructor (object_type, void_arg); - // Activator - Type [] type_arg = { type_type }; - activator_create_instance = GetMethod ( - activator_type, "CreateInstance", type_arg); + InitGenericCodeHelpers (); } const BindingFlags instance_and_static = BindingFlags.Static | BindingFlags.Instance; @@ -1430,6 +1464,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. @@ -1477,6 +1521,8 @@ public class TypeManager { private static MemberInfo [] MemberLookup_FindMembers (Type t, MemberTypes mt, BindingFlags bf, string name, out bool used_cache) { + MemberCache cache; + // // We have to take care of arrays specially, because GetType on // a TypeBuilder array will return a Type, not a TypeBuilder, @@ -1494,7 +1540,7 @@ public class TypeManager { // if (t is TypeBuilder) { DeclSpace decl = (DeclSpace) builder_to_declspace [t]; - MemberCache cache = decl.MemberCache; + cache = decl.MemberCache; // // If this DeclSpace has a MemberCache, use it. @@ -1532,13 +1578,13 @@ public class TypeManager { // // This call will always succeed. There is exactly one TypeHandle instance per - // type, TypeHandle.GetTypeHandle() will either return it or create a new one - // if it didn't already exist. + // type, TypeHandle.GetMemberCache() will, if necessary, create a new one, and return + // the corresponding MemberCache. // - TypeHandle handle = TypeHandle.GetTypeHandle (t); + cache = TypeHandle.GetMemberCache (t); used_cache = true; - return handle.MemberCache.FindMembers (mt, bf, name, FilterWithClosure_delegate, null); + return cache.FindMembers (mt, bf, name, FilterWithClosure_delegate, null); } public static bool IsBuiltinType (Type t) @@ -1561,15 +1607,12 @@ public class TypeManager { // This is like IsBuiltinType, but lacks decimal_type, we should also clean up // the pieces in the code where we use IsBuiltinType and special case decimal_type. // - public static bool IsCLRType (Type t) + public static bool IsPrimitiveType (Type t) { - if (t == object_type || t == int32_type || t == uint32_type || + return (t == int32_type || t == uint32_type || t == int64_type || t == uint64_type || t == float_type || t == double_type || t == char_type || t == short_type || t == bool_type || - t == sbyte_type || t == byte_type || t == ushort_type) - return true; - else - return false; + t == sbyte_type || t == byte_type || t == ushort_type); } public static bool IsDelegateType (Type t) @@ -1601,48 +1644,9 @@ public class TypeManager { return false; } - // - // Only a quick hack to get things moving, while real runtime support appears - // - public static bool IsGeneric (Type t) - { - DeclSpace ds = (DeclSpace) builder_to_declspace [t]; - - return ds.IsGeneric; - } - - public static bool HasGenericArguments (Type t) + public static bool IsNullType (Type t) { - return GetNumberOfTypeArguments (t) > 0; - } - - public static int GetNumberOfTypeArguments (Type t) - { - DeclSpace tc = LookupDeclSpace (t); - if (tc != null) - return tc.IsGeneric ? tc.CountTypeParameters : 0; - else - return t.HasGenericArguments ? t.GetGenericArguments ().Length : 0; - } - - public static Type[] GetTypeArguments (Type t) - { - DeclSpace tc = LookupDeclSpace (t); - if (tc != null) { - if (!tc.IsGeneric) - throw new InvalidOperationException (); - - 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 (); + return t == null_type; } // @@ -1650,42 +1654,52 @@ public class TypeManager { // public static bool IsUnmanagedType (Type t) { - if (IsBuiltinType (t) && t != TypeManager.string_type) - return true; + // builtins that are not unmanaged types + if (t == TypeManager.object_type || t == TypeManager.string_type) + return false; - if (IsEnumType (t)) + if (IsBuiltinOrEnum (t)) return true; + // Someone did the work of checking if the ElementType of t is unmanaged. Let's not repeat it. if (t.IsPointer) return true; - if (IsValueType (t)){ - if (t is TypeBuilder){ - TypeContainer tc = LookupTypeContainer (t); + // Arrays are disallowed, even if we mark them with [MarshalAs(UnmanagedType.ByValArray, ...)] + if (t.IsArray) + return false; - if (tc.Fields != null){ - foreach (Field f in tc.Fields){ - if (f.FieldBuilder.IsStatic) - continue; - if (!IsUnmanagedType (f.FieldBuilder.FieldType)) - return false; - } - } else - return true; - } else { - FieldInfo [] fields = t.GetFields (); + if (!IsValueType (t)) + return false; - foreach (FieldInfo f in fields){ - if (f.IsStatic) - continue; - if (!IsUnmanagedType (f.FieldType)) - return false; + if (t is TypeBuilder){ + TypeContainer tc = LookupTypeContainer (t); + if (tc.Fields == null) + return true; + foreach (Field f in tc.Fields){ + // Avoid using f.FieldBuilder: f.Define () may not yet have been invoked. + if ((f.ModFlags & Modifiers.STATIC) != 0) + continue; + if (f.MemberType == null) + continue; + if (!IsUnmanagedType (f.MemberType)){ + Report.SymbolRelatedToPreviousError (f.Location, CSharpName (t) + "." + f.Name); + return false; } } return true; } + + FieldInfo [] fields = t.GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - return false; + foreach (FieldInfo f in fields){ + if (!IsUnmanagedType (f.FieldType)){ + Report.SymbolRelatedToPreviousError (f); + return false; + } + } + + return true; } public static bool IsValueType (Type t) @@ -1702,174 +1716,79 @@ public class TypeManager { return tc.Kind == Kind.Interface; } - public static bool IsEqualGenericType (Type a, Type b) + public static bool IsSubclassOf (Type type, Type base_type) { - if ((a is TypeBuilder) && a.IsGenericTypeDefinition && b.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. - // - if (a != b.GetGenericTypeDefinition ()) - return false; + TypeParameter tparam = LookupTypeParameter (type); + TypeParameter pparam = LookupTypeParameter (base_type); - Type[] aparams = a.GetGenericArguments (); - Type[] bparams = b.GetGenericArguments (); + if ((tparam != null) && (pparam != null)) { + if (tparam == pparam) + return true; - if (aparams.Length != bparams.Length) - return false; + return tparam.IsSubclassOf (base_type); + } - for (int i = 0; i < aparams.Length; i++) - if (!aparams [i].Equals (bparams [i])) - return false; + do { + if (type.Equals (base_type)) + return true; - return true; - } + type = type.BaseType; + } while (type != null); return false; } - public static bool IsEqual (Type a, Type b) + public static bool IsPrivateAccessible (Type type, Type parent) { - if (a.Equals (b)) + if (type.Equals (parent)) return true; - else - return IsEqualGenericType (a, b); - } - public static bool MayBecomeEqualGenericTypes (Type a, Type b) - { - if (a.IsGenericParameter) { + if ((type is TypeBuilder) && type.IsGenericTypeDefinition && parent.IsGenericInstance) { // - // If a is an array of a's type, they may never - // become equal. - // - while (b.IsArray) { - b = b.GetElementType (); - if (a.Equals (b)) - return false; - } - + // `a' is a generic type definition's TypeBuilder and `b' is a + // generic instance of the same type. // - // If b is a generic parameter or an actual type, - // they may become equal: + // Example: // - // class X : I, I - // class X : I, I - // - if (b.IsGenericParameter || !b.IsGenericInstance) - return true; - + // class Stack + // { + // void Test (Stack stack) { } + // } // - // We're now comparing a type parameter with a - // generic instance. They may become equal unless - // the type parameter appears anywhere in the - // generic instance: + // The first argument of `Test' will be the generic instance + // "Stack" - which is the same type than the "Stack" TypeBuilder. // - // class X : I, I> - // -> error because you could instanciate it as - // X,int> // - // class X : I, I> -> ok + // We hit this via Closure.Filter() for gen-82.cs. // - - Type[] bargs = GetTypeArguments (b); - for (int i = 0; i < bargs.Length; i++) { - if (a.Equals (bargs [i])) - return false; - } + if (type != parent.GetGenericTypeDefinition ()) + return false; return true; } - if (b.IsGenericParameter) - return MayBecomeEqualGenericTypes (b, a); - - // - // At this point, neither a nor b are a type parameter. - // - // If one of them is a generic instance, let - // MayBecomeEqualGenericInstances() compare them (if the - // other one is not a generic instance, they can never - // become equal). - // - - if (a.IsGenericInstance || b.IsGenericInstance) - return MayBecomeEqualGenericInstances (a, b); - - // - // If both of them are arrays. - // - - if (a.IsArray && b.IsArray) { - if (a.GetArrayRank () != b.GetArrayRank ()) + if (type.IsGenericInstance && parent.IsGenericInstance) { + if (type.GetGenericTypeDefinition () != parent.GetGenericTypeDefinition ()) return false; - - a = a.GetElementType (); - b = b.GetElementType (); - return MayBecomeEqualGenericTypes (a, b); - } - - // - // Ok, two ordinary types. - // - - return a.Equals (b); - } - - // - // Checks whether two generic instances may become equal for some - // particular instantiation (26.3.1). - // - public static bool MayBecomeEqualGenericInstances (Type a, Type b) - { - if (!a.IsGenericInstance || !b.IsGenericInstance) - return false; - if (a.GetGenericTypeDefinition () != b.GetGenericTypeDefinition ()) - return false; - - Type[] aargs = GetTypeArguments (a); - Type[] bargs = GetTypeArguments (b); - - if (aargs.Length != bargs.Length) - return false; - - for (int i = 0; i < aargs.Length; i++) { - if (MayBecomeEqualGenericTypes (aargs [i], bargs [i])) - return true; + return true; } return false; } - public static bool IsEqualGenericInstance (Type type, Type parent) + public static bool IsFamilyAccessible (Type type, Type parent) { - int tcount = GetNumberOfTypeArguments (type); - int pcount = GetNumberOfTypeArguments (parent); - - if (type.IsGenericInstance) - type = type.GetGenericTypeDefinition (); - if (parent.IsGenericInstance) - parent = parent.GetGenericTypeDefinition (); + TypeParameter tparam = LookupTypeParameter (type); + TypeParameter pparam = LookupTypeParameter (parent); - if (tcount != pcount) - return false; + if ((tparam != null) && (pparam != null)) { + if (tparam == pparam) + return true; - return type.Equals (parent); - } + return tparam.IsSubclassOf (parent); + } - public static bool IsSubclassOf (Type type, Type parent) - { do { if (IsEqualGenericInstance (type, parent)) return true; @@ -1881,12 +1800,12 @@ public class TypeManager { } // - // Checks whether `type' is a subclass or nested child of `parent'. + // Checks whether `type' is a subclass or nested child of `base_type'. // - public static bool IsSubclassOrNestedChildOf (Type type, Type parent) + public static bool IsNestedFamilyAccessible (Type type, Type base_type) { do { - if (IsSubclassOf (type, parent)) + if (IsFamilyAccessible (type, base_type)) return true; // Handle nested types. @@ -1927,6 +1846,14 @@ public class TypeManager { return TypeToCoreType (t.GetElementType ()); } + /// + /// This method is not implemented by MS runtime for dynamic types + /// + public static bool HasElementType (Type t) + { + return t.IsArray || t.IsPointer || t.IsByRef; + } + /// /// Returns the User Defined Types /// @@ -1972,26 +1899,26 @@ 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; + method_params.Add (mb, ip); } - static public InternalParameters LookupParametersByBuilder (MethodBase mb) + static public ParameterData GetParameterData (MethodBase mb) { - if (! (mb is ConstructorBuilder || mb is MethodBuilder)) - return null; - - if (method_internal_params.Contains (mb)) - return (InternalParameters) method_internal_params [mb]; - else - throw new Exception ("Argument for Method not registered" + mb); + object pd = method_params [mb]; + if (pd == null) { + if (mb is MethodBuilder || mb is ConstructorBuilder) + throw new InternalErrorException ("Argument for Method not registered" + mb); + + method_params [mb] = pd = new ReflectionParameters (mb); + } + + return (ParameterData) pd; } /// @@ -2058,7 +1985,6 @@ public class TypeManager { // This is a workaround the fact that GetValue is not // supported for dynamic types // - static Hashtable fields = new Hashtable (); static public bool RegisterFieldValue (FieldBuilder fb, object value) { if (fields.Contains (fb)) @@ -2074,7 +2000,6 @@ public class TypeManager { return fields [fb]; } - static Hashtable fieldbuilders_to_fields = new Hashtable (); static public bool RegisterFieldBase (FieldBuilder fb, FieldBase f) { if (fieldbuilders_to_fields.Contains (fb)) @@ -2091,22 +2016,22 @@ public class TypeManager { // static public FieldBase GetField (FieldInfo fb) { + if (fb.DeclaringType.IsGenericInstance) + fb = fb.Mono_GetGenericFieldDefinition (); + return (FieldBase) fieldbuilders_to_fields [fb]; } 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 +2040,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 +2050,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; @@ -2200,8 +2125,8 @@ public class TypeManager { if (tc.Fields == null) return true; - foreach (Field field in tc.Fields) { - if (field.FieldBuilder.IsStatic) + foreach (FieldMember field in tc.Fields) { + if (field.FieldBuilder == null || field.FieldBuilder.IsStatic) continue; Type ftype = field.FieldBuilder.FieldType; @@ -2248,17 +2173,19 @@ public class TypeManager { public static Type[] ExpandInterfaces (EmitContext ec, TypeExpr [] base_interfaces) { ArrayList new_ifaces = new ArrayList (); - + foreach (TypeExpr iface in base_interfaces){ - Type itype = iface.ResolveType (ec); - if (itype == null) + TypeExpr texpr = iface.ResolveAsTypeTerminal (ec); + if (texpr == null) return null; - if (!new_ifaces.Contains (itype)) - new_ifaces.Add (itype); - - Type [] implementing = itype.GetInterfaces (); + if (new_ifaces.Contains (texpr.Type)) + continue; + + new_ifaces.Add (texpr.Type); + Type [] implementing = texpr.Type.GetInterfaces (); + foreach (Type imp in implementing){ if (!new_ifaces.Contains (imp)) new_ifaces.Add (imp); @@ -2277,7 +2204,6 @@ public class TypeManager { /// public static Type [] GetInterfaces (Type t) { - Type [] cached = iface_cache [t] as Type []; if (cached != null) return cached; @@ -2295,21 +2221,25 @@ public class TypeManager { if (t.IsArray) t = TypeManager.array_type; - if (t is TypeBuilder){ - Type[] parent_ifaces; + if ((t is TypeBuilder) || t.IsGenericInstance) { + Type [] base_ifaces; if (t.BaseType == null) - parent_ifaces = NoTypes; + base_ifaces = NoTypes; else - parent_ifaces = GetInterfaces (t.BaseType); - Type[] type_ifaces = (Type []) builder_to_ifaces [t]; + base_ifaces = GetInterfaces (t.BaseType); + Type[] type_ifaces; + if (t.IsGenericInstance) + type_ifaces = t.GetInterfaces (); + else + type_ifaces = (Type []) builder_to_ifaces [t]; if (type_ifaces == null) type_ifaces = NoTypes; - int parent_count = parent_ifaces.Length; - Type[] result = new Type [parent_count + type_ifaces.Length]; - parent_ifaces.CopyTo (result, 0); - type_ifaces.CopyTo (result, parent_count); + int base_count = base_ifaces.Length; + Type [] result = new Type [base_count + type_ifaces.Length]; + base_ifaces.CopyTo (result, 0); + type_ifaces.CopyTo (result, base_count); iface_cache [t] = result; return result; @@ -2348,7 +2278,7 @@ public class TypeManager { // as soon as we hit a non-TypeBuiler in the interface // chain, we could return, as the `Type.GetInterfaces' // will return all the interfaces implement by the type - // or its parents. + // or its bases. // do { interfaces = GetInterfaces (t); @@ -2395,7 +2325,7 @@ public class TypeManager { return (object)(convert_value.ToChar (nf_provider)); else if (conversionType.Equals (typeof (DateTime))) return (object)(convert_value.ToDateTime (nf_provider)); - else if (conversionType.Equals (typeof (Decimal))) + else if (conversionType.Equals (TypeManager.decimal_type)) // typeof (Decimal))) return (object)(convert_value.ToDecimal (nf_provider)); else if (conversionType.Equals (typeof (Double))) return (object)(convert_value.ToDouble (nf_provider)); @@ -2515,12 +2445,14 @@ public class TypeManager { return TypeManager.int64_type; case TypeCode.UInt64: return TypeManager.uint64_type; - case TypeCode.Single: - return TypeManager.float_type; - case TypeCode.Double: - return TypeManager.double_type; + case TypeCode.Single: + return TypeManager.float_type; + case TypeCode.Double: + return TypeManager.double_type; case TypeCode.String: return TypeManager.string_type; + case TypeCode.Decimal: + return TypeManager.decimal_type; default: if (t == typeof (void)) return TypeManager.void_type; @@ -2540,18 +2472,7 @@ public class TypeManager { /// public static bool VerifyUnManaged (Type t, Location loc) { - if (t.IsValueType || t.IsPointer){ - // - // FIXME: this is more complex, we actually need to - // make sure that the type does not contain any - // classes itself - // - return true; - } - - if (!RootContext.StdLib && (t == TypeManager.decimal_type)) - // We need this explicit check here to make it work when - // compiling corlib. + if (IsUnmanagedType (t)) return true; Report.Error ( @@ -2566,7 +2487,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 +2497,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 +2508,7 @@ public class TypeManager { return dma.MemberName; } - return "Item"; + return TypeContainer.DefaultIndexerName; } static MethodInfo declare_local_method = null; @@ -2615,7 +2523,7 @@ public class TypeManager { new Type [] { typeof (Type), typeof (bool)}, null); if (declare_local_method == null){ - Report.Warning (-24, new Location (-1), + Report.Warning (-30, new Location (-1), "This version of the runtime does not support making pinned local variables. " + "This code may cause errors on a runtime with a moving GC"); return ig.DeclareLocal (t); @@ -2690,19 +2598,6 @@ public class TypeManager { return target_list; } - static public bool IsGenericMethod (MethodBase mb) - { - if (mb.DeclaringType is TypeBuilder) { - IMethodData method = (IMethodData) builder_to_method [mb]; - if (method == null) - return false; - - return method.GenericMethod != null; - } - - return mb.IsGenericMethodDefinition; - } - #region MemberLookup implementation // @@ -2726,45 +2621,13 @@ public class TypeManager { internal Assembly invocation_assembly; internal IList almost_match; - private bool CheckValidFamilyAccess (bool is_static, MemberInfo m) - { - if (invocation_type == null) - return false; - - if (is_static) - return true; - - // A nested class has access to all the protected members visible - // to its parent. - if (qualifier_type != null - && TypeManager.IsNestedChildOf (invocation_type, qualifier_type)) - return true; - - if (invocation_type == m.DeclaringType - || invocation_type.IsSubclassOf (m.DeclaringType)) { - // Although a derived class can access protected members of - // its base class it cannot do so through an instance of the - // base class (CS1540). - // => Ancestry should be: declaring_type ->* invocation_type - // ->* qualified_type - if (qualifier_type == null - || qualifier_type == invocation_type - || qualifier_type.IsSubclassOf (invocation_type)) - return true; - } - - if (almost_match != null) - almost_match.Add (m); - return false; - } - bool Filter (MethodBase mb, object filter_criteria) { MethodAttributes ma = mb.Attributes & MethodAttributes.MemberAccessMask; if (ma == MethodAttributes.Private) return private_ok || - IsEqual (invocation_type, mb.DeclaringType) || + IsPrivateAccessible (invocation_type, mb.DeclaringType) || IsNestedChildOf (invocation_type, mb.DeclaringType); // @@ -2791,14 +2654,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 +2678,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 +2705,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 +2739,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 +2762,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 @@ -3022,7 +2884,7 @@ public class TypeManager { // works if we already used the cache in the first iteration of this loop. // // If we used the cache in any further iteration, we can still terminate the - // loop since the cache always looks in all parent classes. + // loop since the cache always looks in all base classes. // if (used_cache) @@ -3039,8 +2901,10 @@ public class TypeManager { // This happens with interfaces, they have a null // basetype. Look members up in the Object class. // - if (current_type == null) + if (current_type == null) { current_type = TypeManager.object_type; + searching = true; + } } if (list.Length == 0) @@ -3139,85 +3003,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; } @@ -3229,17 +3038,22 @@ public class TypeManager { /// There is exactly one instance of this class per type. /// public sealed class TypeHandle : IMemberContainer { - public readonly TypeHandle BaseType; + public readonly IMemberContainer BaseType; readonly int id = ++next_id; static int next_id = 0; + static TypeHandle () + { + Reset (); + } + /// /// Lookup a TypeHandle instance for the given type. If the type doesn't have /// a TypeHandle yet, a new instance of it is created. This static method /// ensures that we'll only have one TypeHandle instance per type. /// - public static TypeHandle GetTypeHandle (Type t) + private static TypeHandle GetTypeHandle (Type t) { TypeHandle handle = (TypeHandle) type_hash [t]; if (handle != null) @@ -3249,12 +3063,22 @@ public sealed class TypeHandle : IMemberContainer { type_hash.Add (t, handle); return handle; } + + public static MemberCache GetMemberCache (Type t) + { + return GetTypeHandle (t).MemberCache; + } public static void CleanUp () { type_hash = null; } + public static void Reset () + { + type_hash = new PtrHashtable (); + } + /// /// Returns the TypeHandle for TypeManager.object_type. /// @@ -3283,7 +3107,7 @@ public sealed class TypeHandle : IMemberContainer { } } - private static PtrHashtable type_hash = new PtrHashtable (); + private static PtrHashtable type_hash; private static TypeHandle object_type = null; private static TypeHandle array_type = null; @@ -3292,13 +3116,17 @@ public sealed class TypeHandle : IMemberContainer { private string full_name; private bool is_interface; private MemberCache member_cache; + private MemberCache base_cache; private TypeHandle (Type type) { this.type = type; full_name = type.FullName != null ? type.FullName : type.Name; - if (type.BaseType != null) - BaseType = GetTypeHandle (type.BaseType); + if (type.BaseType != null) { + base_cache = TypeManager.LookupMemberCache (type.BaseType); + BaseType = base_cache.Container; + } else if (type.IsInterface) + base_cache = TypeManager.LookupBaseInterfacesCache (type); this.is_interface = type.IsInterface || type.IsGenericParameter; this.member_cache = new MemberCache (this); } @@ -3317,9 +3145,9 @@ public sealed class TypeHandle : IMemberContainer { } } - public IMemberContainer Parent { + public MemberCache BaseCache { get { - return BaseType; + return base_cache; } }