X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fmembercache.cs;h=de1ef82c7fd610f50f3cce042a8d9897e2bfeac8;hb=28c53a39a4630ecb719a94ee6dd6801633799a89;hp=e59b6d31fe0e0ed5def30b4817185b3d65ed5348;hpb=acdb58d09ff4b41517a9294482eddc1d83a41857;p=mono.git diff --git a/mcs/mcs/membercache.cs b/mcs/mcs/membercache.cs index e59b6d31fe0..de1ef82c7fd 100644 --- a/mcs/mcs/membercache.cs +++ b/mcs/mcs/membercache.cs @@ -73,15 +73,6 @@ namespace Mono.CSharp { public readonly TypeSpec MemberType; public readonly int Arity; // -1 to ignore the check - private MemberFilter (string name, MemberKind kind) - { - Name = name; - Kind = kind; - Parameters = null; - MemberType = null; - Arity = -1; - } - public MemberFilter (MethodSpec m) { Name = m.Name; @@ -249,6 +240,8 @@ namespace Mono.CSharp { // contain all base interface members, so the Lookup code // can use simple inheritance rules. // + // Does not work recursively because of generic interfaces + // public void AddInterface (TypeSpec iface) { var cache = iface.MemberCache; @@ -267,6 +260,13 @@ namespace Mono.CSharp { } foreach (var ce in entry.Value) { + // + // When two or more different base interfaces implemenent common + // interface + // + // I : IA, IFoo + // IA : IFoo + // if (list.Contains (ce)) continue; @@ -274,12 +274,6 @@ namespace Mono.CSharp { member_hash[entry.Key] = list; } } - - // Add also all base interfaces - if (iface.Interfaces != null) { - foreach (var base_iface in iface.Interfaces) - AddInterface (base_iface); - } } public void AddMember (InterfaceMemberBase imb, string exlicitName, MemberSpec ms) @@ -305,13 +299,14 @@ namespace Mono.CSharp { if (member.Kind == MemberKind.Operator) { var dt = member.DeclaringType; + // // Some core types have user operators but they cannot be used like normal // user operators as they are predefined and therefore having different // rules (e.g. binary operators) by not setting the flag we hide them for // user conversions // - if (!BuiltinTypeSpec.IsPrimitiveType (dt)) { + if (!BuiltinTypeSpec.IsPrimitiveType (dt) || dt.BuiltinType == BuiltinTypeSpec.Type.Char) { switch (dt.BuiltinType) { case BuiltinTypeSpec.Type.String: case BuiltinTypeSpec.Type.Delegate: @@ -444,12 +439,15 @@ namespace Mono.CSharp { // A special method to work with member lookup only. It returns a list of all members named @name // starting from @container. It's very performance sensitive // - public static IList FindMembers (TypeSpec container, string name, bool declaredOnly) + // declaredOnlyClass cannot be used interfaces. Manual filtering is required because names are + // compacted + // + public static IList FindMembers (TypeSpec container, string name, bool declaredOnlyClass) { IList applicable; do { - if (container.MemberCache.member_hash.TryGetValue (name, out applicable) || declaredOnly) + if (container.MemberCache.member_hash.TryGetValue (name, out applicable) || declaredOnlyClass) return applicable; container = container.BaseType; @@ -797,7 +795,7 @@ namespace Mono.CSharp { while (true) { foreach (var entry in abstract_type.MemberCache.member_hash) { foreach (var name_entry in entry.Value) { - if ((name_entry.Modifiers & Modifiers.ABSTRACT) == 0) + if ((name_entry.Modifiers & (Modifiers.ABSTRACT | Modifiers.OVERRIDE)) != Modifiers.ABSTRACT) continue; if (name_entry.Kind != MemberKind.Method) @@ -846,6 +844,12 @@ namespace Mono.CSharp { if ((item.Modifiers & (Modifiers.OVERRIDE | Modifiers.VIRTUAL)) == 0) continue; + // + // Abstract override does not override anything + // + if ((item.Modifiers & Modifiers.ABSTRACT) != 0) + continue; + if (filter.Equals (item)) { --not_implemented_count; abstract_methods [i] = null; @@ -894,7 +898,7 @@ namespace Mono.CSharp { return IndexerNameAlias; if (mc is Constructor) - return Constructor.ConstructorName; + return mc.IsStatic ? Constructor.TypeConstructorName : Constructor.ConstructorName; return mc.MemberName.Name; } @@ -905,7 +909,7 @@ namespace Mono.CSharp { public static IList GetUserOperator (TypeSpec container, Operator.OpType op, bool declaredOnly) { IList found = null; - + bool shared_list = true; IList applicable; do { var mc = container.MemberCache; @@ -935,10 +939,13 @@ namespace Mono.CSharp { found = new List (); found.Add (applicable[i]); } else { - var prev = found as List; - if (prev == null) { + List prev; + if (shared_list) { + shared_list = false; prev = new List (found.Count + 1); prev.AddRange (found); + } else { + prev = (List) found; } prev.Add (applicable[i]); @@ -947,12 +954,16 @@ namespace Mono.CSharp { } else { if (found == null) { found = applicable; + shared_list = true; } else { - var merged = found as List; - if (merged == null) { + List merged; + if (shared_list) { + shared_list = false; merged = new List (found.Count + applicable.Count); merged.AddRange (found); found = merged; + } else { + merged = (List) found; } merged.AddRange (applicable); @@ -1163,8 +1174,9 @@ namespace Mono.CSharp { if (container.BaseType == null) { locase_members = new Dictionary (member_hash.Count); // StringComparer.OrdinalIgnoreCase); } else { - container.BaseType.MemberCache.VerifyClsCompliance (container.BaseType, report); - locase_members = new Dictionary (container.BaseType.MemberCache.locase_members); //, StringComparer.OrdinalIgnoreCase); + var btype = container.BaseType.GetDefinition (); + btype.MemberCache.VerifyClsCompliance (btype, report); + locase_members = new Dictionary (btype.MemberCache.locase_members); //, StringComparer.OrdinalIgnoreCase); } var is_imported_type = container.MemberDefinition.IsImported; @@ -1354,8 +1366,10 @@ namespace Mono.CSharp { type_a = parameters.Types [ii]; type_b = p_types [ii]; - if ((pd.FixedParameters [ii].ModFlags & Parameter.Modifier.ISBYREF) != - (parameters.FixedParameters [ii].ModFlags & Parameter.Modifier.ISBYREF)) + var a_byref = (pd.FixedParameters[ii].ModFlags & Parameter.Modifier.RefOutMask) != 0; + var b_byref = (parameters.FixedParameters[ii].ModFlags & Parameter.Modifier.RefOutMask) != 0; + + if (a_byref != b_byref) break; } while (TypeSpecComparer.Override.IsEqual (type_a, type_b) && ii-- != 0); @@ -1374,7 +1388,9 @@ namespace Mono.CSharp { // if (pd != null && member is MethodCore) { ii = method_param_count; - while (ii-- != 0 && parameters.FixedParameters[ii].ModFlags == pd.FixedParameters[ii].ModFlags && + while (ii-- != 0 && + (parameters.FixedParameters[ii].ModFlags & Parameter.Modifier.ModifierMask) == + (pd.FixedParameters[ii].ModFlags & Parameter.Modifier.ModifierMask) && parameters.ExtensionMethodType == pd.ExtensionMethodType) ; if (ii >= 0) { @@ -1429,9 +1445,12 @@ namespace Mono.CSharp { "A partial method declaration and partial method implementation must be both `static' or neither"); } - Report.SymbolRelatedToPreviousError (ce); - Report.Error (764, member.Location, - "A partial method declaration and partial method implementation must be both `unsafe' or neither"); + if ((method_a.ModFlags & Modifiers.UNSAFE) != (method_b.ModFlags & Modifiers.UNSAFE)) { + Report.SymbolRelatedToPreviousError (ce); + Report.Error (764, member.Location, + "A partial method declaration and partial method implementation must be both `unsafe' or neither"); + } + return false; }