Enum = 1 << 14,
Interface = 1 << 15,
TypeParameter = 1 << 16,
+ ByRef = 1 << 17,
ArrayType = 1 << 19,
PointerType = 1 << 20,
var entry_pm = entry as IParametersMember;
if (entry_pm != null) {
entry_param = entry_pm.Parameters;
- if (!TypeSpecComparer.Override.IsEqual (entry_param, member_param))
- continue;
+ 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;
+ }
}
}
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<MemberSpec> applicable;
+ var top_container = container;
+
do {
- IList<MemberSpec> 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--) {
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;
}
//
public static IList<MemberSpec> FindMembers (TypeSpec container, string name, bool declaredOnlyClass)
{
- IList<MemberSpec> applicable;
-
do {
+ IList<MemberSpec> applicable;
+
if (container.MemberCache.member_hash.TryGetValue (name, out applicable) || declaredOnlyClass)
return applicable;
return null;
}
+ public static IList<MemberSpec> FindInterfaceMembers (TypeParameterSpec typeParameter, string name)
+ {
+ if (typeParameter.InterfaceCache != null) {
+ IList<MemberSpec> 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<MemberSpec> applicable;
TypeSpec best_match = null;
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;
}
}
}
container = container.BaseType;
- } while (container != null);
+ } while (container != null && !declaredOnlyClass);
return best_match;
}
return ambig_candidate;
}
+ public static List<TypeSpec> GetDeclaredNestedTypes (TypeSpec container)
+ {
+ List<TypeSpec> 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<TypeSpec> ();
+
+ found.Add ((TypeSpec)member);
+ }
+ }
+
+ return found;
+ }
+
//
// Returns inflated version of MemberSpec, it works similarly to
// SRE TypeBuilder.GetMethod
shared_list = false;
prev = new List<MemberSpec> (found.Count + 1);
prev.AddRange (found);
+ found = prev;
} else {
prev = (List<MemberSpec>) found;
}
}
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");
+ }
}
}