{
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);
}
// 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);
</method>
</type>
</test>
+ <test name="dtest-optional-01.cs">
+ <type name="G`1[T]">
+ <method name="System.Object M1(T)">
+ <size>7</size>
+ </method>
+ <method name="System.Object M2(T)">
+ <size>7</size>
+ </method>
+ <method name="Void .ctor()">
+ <size>7</size>
+ </method>
+ </type>
+ <type name="C">
+ <method name="System.Object Test(System.Object)">
+ <size>2</size>
+ </method>
+ <method name="Void TestS(S)">
+ <size>1</size>
+ </method>
+ <method name="System.Object TestD(System.Object)">
+ <size>2</size>
+ </method>
+ <method name="Int32 Main()">
+ <size>854</size>
+ </method>
+ <method name="Void .ctor()">
+ <size>7</size>
+ </method>
+ </type>
+ </test>
<test name="gtest-001.cs">
<type name="Stack`1[type]">
<method name="Void .ctor()">
<size>2</size>
</method>
<method name="Int32 Main()">
- <size>90</size>
+ <size>211</size>
</method>
<method name="Void .ctor()">
<size>7</size>
</method>
</type>
</test>
+ <test name="test-named-06.cs">
+ <type name="C">
+ <method name="Int32 Main()">
+ <size>25</size>
+ </method>
+ <method name="Int32 Foo(Int32, Int64, System.String)">
+ <size>2</size>
+ </method>
+ <method name="Int32 Foo(Int32, Int64, System.String[])">
+ <size>2</size>
+ </method>
+ <method name="Int32 Foo(Int64, Int32)">
+ <size>2</size>
+ </method>
+ <method name="Void .ctor()">
+ <size>7</size>
+ </method>
+ </type>
+ </test>
<test name="test-partial-01.cs">
<type name="Foo.Hello">
<method name="Void .ctor()">