public static Expression MemberLookup (IMemberContext rc, bool errorMode, TypeSpec queried_type, string name, int arity, MemberLookupRestrictions restrictions, Location loc)
{
var members = MemberCache.FindMembers (queried_type, name, false);
- if (members == null)
- return null;
- Expression expr;
- do {
- expr = MemberLookupToExpression (rc, members, errorMode, queried_type, name, arity, restrictions, loc);
- if (expr != null)
- return expr;
+ if (members != null) {
+ Expression expr;
+ do {
+ expr = MemberLookupToExpression (rc, members, errorMode, queried_type, name, arity, restrictions, loc);
+ if (expr != null)
+ return expr;
- if (members [0].DeclaringType.BaseType == null)
- members = null;
- else
- members = MemberCache.FindMembers (members [0].DeclaringType.BaseType, name, false);
- } while (members != null);
+ if (members [0].DeclaringType.BaseType == null)
+ members = null;
+ else
+ members = MemberCache.FindMembers (members [0].DeclaringType.BaseType, name, false);
+ } while (members != null);
+ }
- return expr;
+ var tps = queried_type as TypeParameterSpec;
+ if (tps != null) {
+ members = MemberCache.FindInterfaceMembers (tps, name);
+ if (members != null)
+ return MemberLookupToExpression (rc, members, errorMode, queried_type, name, arity, restrictions, loc);
+ }
+
+ return null;
}
public static Expression MemberLookupToExpression (IMemberContext rc, IList<MemberSpec> members, bool errorMode, TypeSpec queried_type, string name, int arity, MemberLookupRestrictions restrictions, Location loc)
if ((restrictions & MemberLookupRestrictions.InvocableOnly) != 0) {
if (member is MethodSpec) {
- //
- // Interface members that are hidden by class members are removed from the set. This
- // step only has an effect if T is a type parameter and T has both an effective base
- // class other than object and a non-empty effective interface set
- //
- var tps = queried_type as TypeParameterSpec;
- if (tps != null && tps.HasTypeConstraint)
- members = RemoveHiddenTypeParameterMethods (members);
-
return new MethodGroupExpr (members, queried_type, loc);
}
return null;
}
- static IList<MemberSpec> RemoveHiddenTypeParameterMethods (IList<MemberSpec> members)
- {
- if (members.Count < 2)
- return members;
-
- //
- // If M is a method, then all non-method members declared in an interface declaration
- // are removed from the set, and all methods with the same signature as M declared in
- // an interface declaration are removed from the set
- //
-
- bool copied = false;
- for (int i = 0; i < members.Count; ++i) {
- var method = members[i] as MethodSpec;
- if (method == null) {
- if (!copied) {
- copied = true;
- members = new List<MemberSpec> (members);
- }
-
- members.RemoveAt (i--);
- continue;
- }
-
- if (!method.DeclaringType.IsInterface)
- continue;
-
- for (int ii = 0; ii < members.Count; ++ii) {
- var candidate = members[ii] as MethodSpec;
- if (candidate == null || !candidate.DeclaringType.IsClass)
- continue;
-
- if (!TypeSpecComparer.Override.IsEqual (candidate.Parameters, method.Parameters))
- continue;
-
- if (!AParametersCollection.HasSameParameterDefaults (candidate.Parameters, method.Parameters))
- continue;
-
- if (!copied) {
- copied = true;
- members = new List<MemberSpec> (members);
- }
-
- members.RemoveAt (i--);
- break;
- }
- }
-
- return members;
- }
-
protected static void Error_NamedArgument (NamedArgument na, Report Report)
{
Report.Error (1742, na.Location, "An element access expression cannot use named argument");
// For extension methodgroup we are not looking for base members but parent
// namespace extension methods
//
- public override IList<MemberSpec> GetBaseMembers (TypeSpec baseType)
+ public override IList<MemberSpec> GetBaseMembers (TypeSpec type)
{
// TODO: candidates are null only when doing error reporting, that's
// incorrect. We have to discover same extension methods in error mode
#region IBaseMembersProvider Members
- public virtual IList<MemberSpec> GetBaseMembers (TypeSpec baseType)
+ public virtual IList<MemberSpec> GetBaseMembers (TypeSpec type)
{
- return baseType == null ? null : MemberCache.FindMembers (baseType, Methods [0].Name, false);
+ var baseType = type.BaseType;
+
+ IList<MemberSpec> members = baseType == null ? null : MemberCache.FindMembers (baseType, Methods [0].Name, false);
+
+ if (members == null && !type.IsInterface) {
+ var tps = queried_type as TypeParameterSpec;
+ if (tps != null)
+ members = MemberCache.FindInterfaceMembers (tps, Methods [0].Name);
+ }
+
+ return members;
}
public IParametersMember GetOverrideMemberParameters (MemberSpec member)
// Restore expanded arguments
candidate_args = args;
}
- } while (best_candidate_rate != 0 && (type_members = base_provider.GetBaseMembers (type_members[0].DeclaringType.BaseType)) != null);
+ } while (best_candidate_rate != 0 && (type_members = base_provider.GetBaseMembers (type_members[0].DeclaringType)) != null);
//
// We've found exact match