Browse Source

Add 'allowOptionalParameters' flag to MGRR.PerformOverloadResolution.

newNRvisualizers
Daniel Grunwald 13 years ago
parent
commit
27978f44c7
  1. 2
      ICSharpCode.NRefactory.CSharp/Resolver/CSharpConversions.cs
  2. 8
      ICSharpCode.NRefactory.CSharp/Resolver/MethodGroupResolveResult.cs
  3. 10
      ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs
  4. 10
      ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs
  5. 2
      ICSharpCode.NRefactory.CSharp/Resolver/TypeInference.cs
  6. 49
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/ConversionsTest.cs

2
ICSharpCode.NRefactory.CSharp/Resolver/CSharpConversions.cs

@ -921,7 +921,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
args[i] = new ResolveResult(parameterType); args[i] = new ResolveResult(parameterType);
} }
} }
var or = rr.PerformOverloadResolution(compilation, args, allowExpandingParams: false, conversions: this); var or = rr.PerformOverloadResolution(compilation, args, allowExpandingParams: false, allowOptionalParameters: false, conversions: this);
if (or.FoundApplicableCandidate) { if (or.FoundApplicableCandidate) {
IMethod method = (IMethod)or.GetBestCandidateWithSubstitutedTypeArguments(); IMethod method = (IMethod)or.GetBestCandidateWithSubstitutedTypeArguments();
var thisRR = rr.TargetResult as ThisResolveResult; var thisRR = rr.TargetResult as ThisResolveResult;

8
ICSharpCode.NRefactory.CSharp/Resolver/MethodGroupResolveResult.cs

@ -220,7 +220,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return string.Format("[{0} with {1} method(s)]", GetType().Name, this.Methods.Count()); return string.Format("[{0} with {1} method(s)]", GetType().Name, this.Methods.Count());
} }
public OverloadResolution PerformOverloadResolution(ICompilation compilation, ResolveResult[] arguments, string[] argumentNames = null, bool allowExtensionMethods = true, bool allowExpandingParams = true, bool checkForOverflow = false, CSharpConversions conversions = null) public OverloadResolution PerformOverloadResolution(ICompilation compilation, ResolveResult[] arguments, string[] argumentNames = null,
bool allowExtensionMethods = true,
bool allowExpandingParams = true,
bool allowOptionalParameters = true,
bool checkForOverflow = false, CSharpConversions conversions = null)
{ {
Log.WriteLine("Performing overload resolution for " + this); Log.WriteLine("Performing overload resolution for " + this);
Log.WriteCollection(" Arguments: ", arguments); Log.WriteCollection(" Arguments: ", arguments);
@ -228,6 +232,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
var typeArgumentArray = this.TypeArguments.ToArray(); var typeArgumentArray = this.TypeArguments.ToArray();
OverloadResolution or = new OverloadResolution(compilation, arguments, argumentNames, typeArgumentArray, conversions); OverloadResolution or = new OverloadResolution(compilation, arguments, argumentNames, typeArgumentArray, conversions);
or.AllowExpandingParams = allowExpandingParams; or.AllowExpandingParams = allowExpandingParams;
or.AllowOptionalParameters = allowOptionalParameters;
or.CheckForOverflow = checkForOverflow; or.CheckForOverflow = checkForOverflow;
or.AddMethodLists(methodLists); or.AddMethodLists(methodLists);
@ -249,6 +254,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
var extOr = new OverloadResolution(compilation, extArguments, extArgumentNames, typeArgumentArray, conversions); var extOr = new OverloadResolution(compilation, extArguments, extArgumentNames, typeArgumentArray, conversions);
extOr.AllowExpandingParams = allowExpandingParams; extOr.AllowExpandingParams = allowExpandingParams;
extOr.AllowOptionalParameters = allowOptionalParameters;
extOr.IsExtensionMethodInvocation = true; extOr.IsExtensionMethodInvocation = true;
extOr.CheckForOverflow = checkForOverflow; extOr.CheckForOverflow = checkForOverflow;

10
ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs

@ -155,6 +155,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
this.conversions = conversions ?? CSharpConversions.Get(compilation); this.conversions = conversions ?? CSharpConversions.Get(compilation);
this.AllowExpandingParams = true; this.AllowExpandingParams = true;
this.AllowOptionalParameters = true;
} }
#endregion #endregion
@ -174,6 +175,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// </summary> /// </summary>
public bool AllowExpandingParams { get; set; } public bool AllowExpandingParams { get; set; }
/// <summary>
/// Gets/Sets whether optional parameters may be left at their default value.
/// The default value is true.
/// If this property is set to false, optional parameters will be treated like regular parameters.
/// </summary>
public bool AllowOptionalParameters { get; set; }
/// <summary> /// <summary>
/// Gets/Sets whether ConversionResolveResults created by this OverloadResolution /// Gets/Sets whether ConversionResolveResults created by this OverloadResolution
/// instance apply overflow checking. /// instance apply overflow checking.
@ -543,7 +551,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (candidate.IsExpandedForm && i == argumentCountPerParameter.Length - 1) if (candidate.IsExpandedForm && i == argumentCountPerParameter.Length - 1)
continue; // any number of arguments is fine for the params-array continue; // any number of arguments is fine for the params-array
if (argumentCountPerParameter[i] == 0) { if (argumentCountPerParameter[i] == 0) {
if (candidate.Parameters[i].IsOptional) if (this.AllowOptionalParameters && candidate.Parameters[i].IsOptional)
candidate.HasUnmappedOptionalParameters = true; candidate.HasUnmappedOptionalParameters = true;
else else
candidate.AddError(OverloadResolutionErrors.MissingArgumentForRequiredParameter); candidate.AddError(OverloadResolutionErrors.MissingArgumentForRequiredParameter);

10
ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs

@ -1583,7 +1583,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
var addRR = memberLookup.Lookup(initializedObject, "Add", EmptyList<IType>.Instance, true); var addRR = memberLookup.Lookup(initializedObject, "Add", EmptyList<IType>.Instance, true);
var mgrr = addRR as MethodGroupResolveResult; var mgrr = addRR as MethodGroupResolveResult;
if (mgrr != null) { if (mgrr != null) {
OverloadResolution or = mgrr.PerformOverloadResolution(resolver.Compilation, addArguments, null, false, false, resolver.CheckForOverflow, resolver.conversions); OverloadResolution or = mgrr.PerformOverloadResolution(resolver.Compilation, addArguments, null, false, false, false, resolver.CheckForOverflow, resolver.conversions);
var invocationRR = or.CreateResolveResult(initializedObject); var invocationRR = or.CreateResolveResult(initializedObject);
StoreResult(aie, invocationRR); StoreResult(aie, invocationRR);
ProcessInvocationResult(null, aie.Elements, invocationRR); ProcessInvocationResult(null, aie.Elements, invocationRR);
@ -2745,7 +2745,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} else { } else {
var getEnumeratorMethodGroup = memberLookup.Lookup(expression, "GetEnumerator", EmptyList<IType>.Instance, true) as MethodGroupResolveResult; var getEnumeratorMethodGroup = memberLookup.Lookup(expression, "GetEnumerator", EmptyList<IType>.Instance, true) as MethodGroupResolveResult;
if (getEnumeratorMethodGroup != null) { if (getEnumeratorMethodGroup != null) {
var or = getEnumeratorMethodGroup.PerformOverloadResolution(compilation, new ResolveResult[0]); var or = getEnumeratorMethodGroup.PerformOverloadResolution(
compilation, new ResolveResult[0],
allowExtensionMethods: false, allowExpandingParams: false, allowOptionalParameters: false);
if (or.FoundApplicableCandidate && !or.IsAmbiguous && !or.BestCandidate.IsStatic && or.BestCandidate.IsPublic) { if (or.FoundApplicableCandidate && !or.IsAmbiguous && !or.BestCandidate.IsStatic && or.BestCandidate.IsPublic) {
collectionType = expression.Type; collectionType = expression.Type;
getEnumeratorInvocation = or.CreateResolveResult(expression); getEnumeratorInvocation = or.CreateResolveResult(expression);
@ -2762,7 +2764,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
IMethod moveNextMethod = null; IMethod moveNextMethod = null;
var moveNextMethodGroup = memberLookup.Lookup(new ResolveResult(enumeratorType), "MoveNext", EmptyList<IType>.Instance, false) as MethodGroupResolveResult; var moveNextMethodGroup = memberLookup.Lookup(new ResolveResult(enumeratorType), "MoveNext", EmptyList<IType>.Instance, false) as MethodGroupResolveResult;
if (moveNextMethodGroup != null) { if (moveNextMethodGroup != null) {
var or = moveNextMethodGroup.PerformOverloadResolution(compilation, new ResolveResult[0]); var or = moveNextMethodGroup.PerformOverloadResolution(
compilation, new ResolveResult[0],
allowExtensionMethods: false, allowExpandingParams: false, allowOptionalParameters: false);
moveNextMethod = or.GetBestCandidateWithSubstitutedTypeArguments() as IMethod; moveNextMethod = or.GetBestCandidateWithSubstitutedTypeArguments() as IMethod;
} }

2
ICSharpCode.NRefactory.CSharp/Resolver/TypeInference.cs

@ -510,7 +510,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
var or = mgrr.PerformOverloadResolution(compilation, var or = mgrr.PerformOverloadResolution(compilation,
args, args,
allowExpandingParams: false); allowExpandingParams: false, allowOptionalParameters: false);
if (or.FoundApplicableCandidate && or.BestCandidateAmbiguousWith == null) { if (or.FoundApplicableCandidate && or.BestCandidateAmbiguousWith == null) {
IType returnType = or.GetBestCandidateWithSubstitutedTypeArguments().ReturnType; IType returnType = or.GetBestCandidateWithSubstitutedTypeArguments().ReturnType;
MakeLowerBoundInference(returnType, m.ReturnType); MakeLowerBoundInference(returnType, m.ReturnType);

49
ICSharpCode.NRefactory.Tests/CSharp/Resolver/ConversionsTest.cs

@ -19,6 +19,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.CSharp.TypeSystem; using ICSharpCode.NRefactory.CSharp.TypeSystem;
using ICSharpCode.NRefactory.Semantics; using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
@ -782,5 +783,53 @@ class Test {
//Assert.IsFrue(c.IsValid); //Assert.IsFrue(c.IsValid);
Assert.IsTrue(c.IsMethodGroupConversion); Assert.IsTrue(c.IsMethodGroupConversion);
} }
[Test]
public void MethodGroupConversion_ExactMatchIsBetter()
{
string program = @"using System;
class Test {
delegate void D(string a);
D d = $M$;
static void M(object x) {}
static void M(string x = null) {}
}";
var c = GetConversion(program);
Assert.IsTrue(c.IsValid);
Assert.IsTrue(c.IsMethodGroupConversion);
Assert.AreEqual("System.String", c.Method.Parameters.Single().Type.FullName);
}
[Test]
public void MethodGroupConversion_CannotLeaveOutOptionalParameters()
{
string program = @"using System;
class Test {
delegate void D(string a);
D d = $M$;
static void M(object x) {}
static void M(string x, string y = null) {}
}";
var c = GetConversion(program);
Assert.IsTrue(c.IsValid);
Assert.IsTrue(c.IsMethodGroupConversion);
Assert.AreEqual("System.Object", c.Method.Parameters.Single().Type.FullName);
}
[Test]
public void MethodGroupConversion_CannotUseExpandedParams()
{
string program = @"using System;
class Test {
delegate void D(string a);
D d = $M$;
static void M(object x) {}
static void M(params string[] x) {}
}";
var c = GetConversion(program);
Assert.IsTrue(c.IsValid);
Assert.IsTrue(c.IsMethodGroupConversion);
Assert.AreEqual("System.Object", c.Method.Parameters.Single().Type.FullName);
}
} }
} }

Loading…
Cancel
Save