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
if (mgrr != null) { if (mgrr != null) {
OverloadResolution or = mgrr.PerformOverloadResolution(compilation, arguments, argumentNames, conversions: conversions); OverloadResolution or = mgrr.PerformOverloadResolution(compilation, arguments, argumentNames, conversions: conversions);
if (or.BestCandidate != null) { 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)); return or.CreateResolveResult(new TypeResolveResult(mgrr.TargetResult.Type));
else else
return or.CreateResolveResult(mgrr.TargetResult); return or.CreateResolveResult(mgrr.TargetResult);

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

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

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

@ -493,5 +493,33 @@ class Test : IVisitor<object, object> {
Assert.AreEqual("System.Object", typeArguments[0].ReflectionName); Assert.AreEqual("System.Object", typeArguments[0].ReflectionName);
Assert.AreEqual("System.Object", typeArguments[1].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