Browse Source

Fix icsharpcode/NRefactory#30: Target of extension method invocation

newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
8d0abbe870
  1. 2
      ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs
  2. 19
      ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs
  3. 28
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/InvocationTests.cs

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

@ -1857,7 +1857,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1857,7 +1857,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (mgrr != null) {
OverloadResolution or = mgrr.PerformOverloadResolution(compilation, arguments, argumentNames, conversions: conversions);
if (or.BestCandidate != null) {
if (or.BestCandidate.IsStatic && !(mgrr.TargetResult is TypeResolveResult))
if (or.BestCandidate.IsStatic && !or.IsExtensionMethodInvocation && !(mgrr.TargetResult is TypeResolveResult))
return or.CreateResolveResult(new TypeResolveResult(mgrr.TargetResult.Type));
else
return or.CreateResolveResult(mgrr.TargetResult);

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

@ -778,11 +778,20 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -778,11 +778,20 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
{
if (bestCandidate == null)
return arguments;
else
return GetArgumentsWithConversions(null);
}
IList<ResolveResult> GetArgumentsWithConversions(ResolveResult targetResolveResult)
{
var conversions = this.ArgumentConversions;
ResolveResult[] args = new ResolveResult[arguments.Length];
for (int i = 0; i < args.Length; i++) {
var argument = arguments[i];
if (this.IsExtensionMethodInvocation && i == 0 && targetResolveResult != null)
argument = targetResolveResult;
if (conversions[i] == Conversion.IdentityConversion) {
args[i] = arguments[i];
args[i] = argument;
} else {
int parameterIndex = bestCandidate.ArgumentToParameterMap[i];
IType parameterType;
@ -792,9 +801,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -792,9 +801,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
parameterType = SpecialType.UnknownType;
}
if (arguments[i].IsCompileTimeConstant && conversions[i] != Conversion.None) {
args[i] = new CSharpResolver(compilation).ResolveCast(parameterType, arguments[i]);
args[i] = new CSharpResolver(compilation).ResolveCast(parameterType, argument);
} else {
args[i] = new ConversionResolveResult(parameterType, arguments[i], conversions[i]);
args[i] = new ConversionResolveResult(parameterType, argument, conversions[i]);
}
}
}
@ -839,9 +848,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -839,9 +848,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
throw new InvalidOperationException();
return new CSharpInvocationResolveResult(
targetResolveResult,
this.IsExtensionMethodInvocation ? new TypeResolveResult(member.DeclaringType) : targetResolveResult,
member,
GetArgumentsWithConversions(),
GetArgumentsWithConversions(targetResolveResult),
this.BestCandidateErrors,
this.IsExtensionMethodInvocation,
this.BestCandidateIsExpandedForm,

28
ICSharpCode.NRefactory.Tests/CSharp/Resolver/InvocationTests.cs

@ -493,5 +493,33 @@ class Test : IVisitor<object, object> { @@ -493,5 +493,33 @@ class Test : IVisitor<object, object> {
Assert.AreEqual("System.Object", typeArguments[0].ReflectionName);
Assert.AreEqual("System.Object", typeArguments[1].ReflectionName);
}
[Test]
public void FirstParameterToExtensionMethod()
{
string program = @"
public class X {}
public static class Ex {
public static void F(this X x, int y, int z) {}
}
class C {
public void M() {
X a = null;
int b = 0, c = 0;
$a.F(b, c)$;
}
}";
var rr = Resolve<CSharpInvocationResolveResult>(program);
Assert.IsFalse(rr.IsError);
Assert.That(rr.IsExtensionMethodInvocation, Is.True);
Assert.That(rr.Arguments[0], Is.InstanceOf<LocalResolveResult>());
Assert.That(((LocalResolveResult)rr.Arguments[0]).Variable.Name, Is.EqualTo("a"));
Assert.That(rr.Arguments[1], Is.InstanceOf<LocalResolveResult>());
Assert.That(((LocalResolveResult)rr.Arguments[1]).Variable.Name, Is.EqualTo("b"));
Assert.That(rr.Arguments[2], Is.InstanceOf<LocalResolveResult>());
Assert.That(((LocalResolveResult)rr.Arguments[2]).Variable.Name, Is.EqualTo("c"));
Assert.That(rr.TargetResult, Is.InstanceOf<TypeResolveResult>());
}
}
}

Loading…
Cancel
Save