{
public readonly MemberSpec Member;
public readonly bool Expanded;
+ public readonly AParametersCollection Parameters;
- public AmbiguousCandidate (MemberSpec member, bool expanded)
+ public AmbiguousCandidate (MemberSpec member, AParametersCollection parameters, bool expanded)
{
Member = member;
+ Parameters = parameters;
Expanded = expanded;
}
}
/// false if candidate ain't better
/// true if candidate is better than the current best match
/// </remarks>
- static bool BetterFunction (ResolveContext ec, Arguments args, MemberSpec candidate, bool candidate_params,
- MemberSpec best, bool best_params)
+ static bool BetterFunction (ResolveContext ec, Arguments args, MemberSpec candidate, AParametersCollection cparam, bool candidate_params,
+ MemberSpec best, AParametersCollection bparam, bool best_params)
{
AParametersCollection candidate_pd = ((IParametersMember) candidate).Parameters;
AParametersCollection best_pd = ((IParametersMember) best).Parameters;
bool same = true;
int args_count = args == null ? 0 : args.Count;
int j = 0;
+ TypeSpec ct, bt;
for (int c_idx = 0, b_idx = 0; j < args_count; ++j, ++c_idx, ++b_idx) {
Argument a = args[j];
if (a.IsDefaultArgument)
break;
- TypeSpec ct = candidate_pd.Types[c_idx];
- TypeSpec bt = best_pd.Types[b_idx];
+ //
+ // When comparing named argument the parameter type index has to be looked up
+ // in original parameter set (override version for virtual members)
+ //
+ NamedArgument na = a as NamedArgument;
+ if (na != null) {
+ int idx = cparam.GetParameterIndexByName (na.Name);
+ ct = candidate_pd.Types[idx];
+ if (candidate_params && candidate_pd.FixedParameters[idx].ModFlags == Parameter.Modifier.PARAMS)
+ ct = TypeManager.GetElementType (ct);
+
+ idx = bparam.GetParameterIndexByName (na.Name);
+ bt = best_pd.Types[idx];
+ if (best_params && best_pd.FixedParameters[idx].ModFlags == Parameter.Modifier.PARAMS)
+ bt = TypeManager.GetElementType (bt);
+ } else {
+ ct = candidate_pd.Types[c_idx];
+ bt = best_pd.Types[b_idx];
- if (candidate_params && candidate_pd.FixedParameters[c_idx].ModFlags == Parameter.Modifier.PARAMS) {
- ct = TypeManager.GetElementType (ct);
- --c_idx;
- }
+ if (candidate_params && candidate_pd.FixedParameters[c_idx].ModFlags == Parameter.Modifier.PARAMS) {
+ ct = TypeManager.GetElementType (ct);
+ --c_idx;
+ }
- if (best_params && best_pd.FixedParameters[b_idx].ModFlags == Parameter.Modifier.PARAMS) {
- bt = TypeManager.GetElementType (bt);
- --b_idx;
+ if (best_params && best_pd.FixedParameters[b_idx].ModFlags == Parameter.Modifier.PARAMS) {
+ bt = TypeManager.GetElementType (bt);
+ --b_idx;
+ }
}
if (ct == bt)
// Prefer non-optional version
//
// LAMESPEC: Specification claims this should be done at last but the opposite is true
+ //
if (candidate_params == best_params && candidate_pd.Count != best_pd.Count) {
if (candidate_pd.Count >= best_pd.Count)
return false;
bool specific_at_least_once = false;
for (j = 0; j < candidate_param_count; ++j) {
- var ct = candidate_def_pd.Types[j];
- var bt = best_def_pd.Types[j];
+ NamedArgument na = args_count == 0 ? null : args [j] as NamedArgument;
+ if (na != null) {
+ ct = candidate_def_pd.Types[cparam.GetParameterIndexByName (na.Name)];
+ bt = best_def_pd.Types[bparam.GetParameterIndexByName (na.Name)];
+ } else {
+ ct = candidate_def_pd.Types[j];
+ bt = best_def_pd.Types[j];
+ }
+
if (ct == bt)
continue;
TypeSpec specific = MoreSpecific (ct, bt);
//
// LAMESPEC: No idea what the exact rules are for System.Reflection.Missing.Value instead of null
//
- if (e == EmptyExpression.MissingValue && ptypes [i] == TypeManager.object_type) {
+ if (e == EmptyExpression.MissingValue && ptypes[i] == TypeManager.object_type || ptypes[i] == InternalType.Dynamic) {
e = new MemberAccess (new MemberAccess (new MemberAccess (
new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Reflection", loc), "Missing", loc), "Value", loc);
} else {
}
// Is the new candidate better
- if (BetterFunction (rc, candidate_args, member, params_expanded_form, best_candidate, best_candidate_params)) {
+ if (BetterFunction (rc, candidate_args, member, pm.Parameters, params_expanded_form, best_candidate, best_parameter_member.Parameters, best_candidate_params)) {
best_candidate = member;
best_candidate_args = candidate_args;
best_candidate_params = params_expanded_form;
if (ambiguous_candidates == null)
ambiguous_candidates = new List<AmbiguousCandidate> ();
- ambiguous_candidates.Add (new AmbiguousCandidate (member, params_expanded_form));
+ ambiguous_candidates.Add (new AmbiguousCandidate (member, pm.Parameters, params_expanded_form));
}
}
for (int ix = 0; ix < ambiguous_candidates.Count; ix++) {
var candidate = ambiguous_candidates [ix];
- if (!BetterFunction (rc, candidate_args, best_candidate, best_candidate_params, candidate.Member, candidate.Expanded)) {
+ if (!BetterFunction (rc, candidate_args, best_candidate, best_parameter_member.Parameters, best_candidate_params, candidate.Member, candidate.Parameters, candidate.Expanded)) {
var ambiguous = candidate.Member;
if (custom_errors == null || !custom_errors.AmbiguousCandidates (rc, best_candidate, ambiguous)) {
rc.Report.SymbolRelatedToPreviousError (best_candidate);
public override SLE.Expression MakeExpression (BuilderContext ctx)
{
- return SLE.Expression.Field (InstanceExpression.MakeExpression (ctx), spec.GetMetaInfo ());
+ return SLE.Expression.Field (
+ IsStatic ? null : InstanceExpression.MakeExpression (ctx),
+ spec.GetMetaInfo ());
}
public override void SetTypeArguments (ResolveContext ec, TypeArguments ta)