X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fmembercache.cs;h=eebf71b844b8e2a51337bf35a1560c7b13d7134f;hb=34866ac4c20c781f10c40fe6f6fe0c39733fd946;hp=042a15b6533c3b23c227e08269ec551e427ae0ef;hpb=6733010353a6024a2b437a6cd5c5c30ae6e99218;p=mono.git diff --git a/mcs/mcs/membercache.cs b/mcs/mcs/membercache.cs index 042a15b6533..eebf71b844b 100644 --- a/mcs/mcs/membercache.cs +++ b/mcs/mcs/membercache.cs @@ -35,6 +35,7 @@ namespace Mono.CSharp { Enum = 1 << 14, Interface = 1 << 15, TypeParameter = 1 << 16, + ByRef = 1 << 17, ArrayType = 1 << 19, PointerType = 1 << 20, @@ -354,7 +355,7 @@ namespace Mono.CSharp { // static bool AddInterfaceMember (MemberSpec member, ref IList existing) { - var member_param = member is IParametersMember ? ((IParametersMember) member).Parameters : ParametersCompiled.EmptyReadOnlyParameters; + var member_param = member is IParametersMember ? ((IParametersMember) member).Parameters : null; // // interface IA : IB { int Prop { set; } } @@ -368,10 +369,19 @@ namespace Mono.CSharp { if (entry.Arity != member.Arity) continue; - if (entry is IParametersMember) { - var entry_param = ((IParametersMember) entry).Parameters; - if (!TypeSpecComparer.Override.IsEqual (entry_param, member_param)) - continue; + AParametersCollection entry_param = null; + if (member_param != null) { + var entry_pm = entry as IParametersMember; + if (entry_pm != null) { + entry_param = entry_pm.Parameters; + if (entry.DeclaringType != member.DeclaringType) { + if (!TypeSpecComparer.Override.IsEqual (entry_param, member_param)) + continue; + } else { + if (!TypeSpecComparer.Equals (entry_param.Types, member_param.Types)) + continue; + } + } } if (member.DeclaringType.ImplementsInterface (entry.DeclaringType, false)) { @@ -384,8 +394,10 @@ namespace Mono.CSharp { continue; } - if ((entry.DeclaringType == member.DeclaringType && entry.IsAccessor == member.IsAccessor) || - entry.DeclaringType.ImplementsInterface (member.DeclaringType, false)) + if ((entry.DeclaringType == member.DeclaringType && entry.IsAccessor == member.IsAccessor)) + return false; + + if (entry.DeclaringType.ImplementsInterface (member.DeclaringType, false) && AParametersCollection.HasSameParameterDefaults (entry_param, member_param)) return false; } @@ -400,8 +412,13 @@ namespace Mono.CSharp { public static MemberSpec FindMember (TypeSpec container, MemberFilter filter, BindingRestriction restrictions) { + if (filter.Kind == MemberKind.Method && container.Kind == MemberKind.TypeParameter && filter.Parameters == null) + throw new NotSupportedException ("type parameters methods cannot be lookup up due to two stage setup"); + + IList applicable; + var top_container = container; + do { - IList applicable; if (container.MemberCache.member_hash.TryGetValue (filter.Name, out applicable)) { // Start from the end because interface members are in reverse order for (int i = applicable.Count - 1; i >= 0; i--) { @@ -432,6 +449,26 @@ namespace Mono.CSharp { container = container.BaseType; } while (container != null); + var tps = top_container as TypeParameterSpec; + if (tps != null && tps.InterfaceCache != null) { + if (tps.InterfaceCache.member_hash.TryGetValue (filter.Name, out applicable)) { + for (int i = applicable.Count - 1; i >= 0; i--) { + var entry = applicable [i]; + + if ((restrictions & BindingRestriction.NoAccessors) != 0 && entry.IsAccessor) + continue; + + if ((restrictions & BindingRestriction.OverrideOnly) != 0 && (entry.Modifiers & Modifiers.OVERRIDE) == 0) + continue; + + if (!filter.Equals (entry)) + continue; + + return entry; + } + } + } + return null; } @@ -444,9 +481,9 @@ namespace Mono.CSharp { // public static IList FindMembers (TypeSpec container, string name, bool declaredOnlyClass) { - IList applicable; - do { + IList applicable; + if (container.MemberCache.member_hash.TryGetValue (name, out applicable) || declaredOnlyClass) return applicable; @@ -456,10 +493,21 @@ namespace Mono.CSharp { return null; } + public static IList FindInterfaceMembers (TypeParameterSpec typeParameter, string name) + { + if (typeParameter.InterfaceCache != null) { + IList applicable; + typeParameter.InterfaceCache.member_hash.TryGetValue (name, out applicable); + return applicable; + } + + return null; + } + // // Finds the nested type in container // - public static TypeSpec FindNestedType (TypeSpec container, string name, int arity) + public static TypeSpec FindNestedType (TypeSpec container, string name, int arity, bool declaredOnlyClass) { IList applicable; TypeSpec best_match = null; @@ -488,7 +536,7 @@ namespace Mono.CSharp { if (arity < 0) { if (best_match == null) { best_match = ts; - } else if (System.Math.Abs (ts.Arity + arity) < System.Math.Abs (ts.Arity + arity)) { + } else if (System.Math.Abs (ts.Arity + arity) < System.Math.Abs (best_match.Arity + arity)) { best_match = ts; } } @@ -496,7 +544,7 @@ namespace Mono.CSharp { } container = container.BaseType; - } while (container != null); + } while (container != null && !declaredOnlyClass); return best_match; } @@ -637,6 +685,24 @@ namespace Mono.CSharp { return ambig_candidate; } + public static List GetDeclaredNestedTypes (TypeSpec container) + { + List found = null; + foreach (var entry in container.MemberCache.member_hash) { + foreach (var member in entry.Value) { + if ((member.Kind & MemberKind.NestedMask) == 0) + continue; + + if (found == null) + found = new List (); + + found.Add ((TypeSpec)member); + } + } + + return found; + } + // // Returns inflated version of MemberSpec, it works similarly to // SRE TypeBuilder.GetMethod @@ -964,6 +1030,7 @@ namespace Mono.CSharp { shared_list = false; prev = new List (found.Count + 1); prev.AddRange (found); + found = prev; } else { prev = (List) found; } @@ -1316,7 +1383,7 @@ namespace Mono.CSharp { if (a.DeclaringType.MemberDefinition != b.DeclaringType.MemberDefinition) return mc_b; - if (mc_a.Location.File != mc_a.Location.File) + if (mc_a.Location.File != mc_b.Location.File) return mc_b; return mc_b.Location.Row > mc_a.Location.Row ? mc_b : mc_a; @@ -1435,6 +1502,12 @@ namespace Mono.CSharp { } return false; } + + var pm_member = (MethodCore)member; + if (!NamedTupleSpec.CheckOverrideName (pm, pm_member) || !NamedTupleSpec.CheckOverrideName (pm.MemberType, pm_member.MemberType)) { + Report.Error (8142, member.Location, + "A partial method declaration and partial method implementation must both use the same tuple element names"); + } } }