Browse Source

Do not report invalid conversion from int to void for this code:

void Run(Action<string> a) { }
int M() {
    Run(x => $M()$);
}
newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
b803d850f7
  1. 12
      ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs
  2. 28
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/LambdaTests.cs
  3. 26
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs

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

@ -1917,8 +1917,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1917,8 +1917,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
Log.WriteLine("Applying return type {0} to explicitly-typed lambda {1}", returnType, this.LambdaExpression);
if (isAsync)
returnType = parentVisitor.UnpackTask(returnType);
for (int i = 0; i < returnExpressions.Count; i++) {
visitor.ProcessConversion(returnExpressions[i], returnValues[i], returnType);
if (returnType.Kind != TypeKind.Void) {
for (int i = 0; i < returnExpressions.Count; i++) {
visitor.ProcessConversion(returnExpressions[i], returnValues[i], returnType);
}
}
}
@ -2203,8 +2205,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2203,8 +2205,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
Log.WriteLine("Applying return type {0} to implicitly-typed lambda {1}", returnType, lambda.LambdaExpression);
if (lambda.IsAsync)
returnType = parentVisitor.UnpackTask(returnType);
for (int i = 0; i < returnExpressions.Count; i++) {
visitor.ProcessConversion(returnExpressions[i], returnValues[i], returnType);
if (returnType.Kind != TypeKind.Void) {
for (int i = 0; i < returnExpressions.Count; i++) {
visitor.ProcessConversion(returnExpressions[i], returnValues[i], returnType);
}
}
visitor.MergeUndecidedLambdas();

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

@ -392,6 +392,34 @@ class TestClass { @@ -392,6 +392,34 @@ class TestClass {
Assert.IsFalse(rr.HasParameterList);
}
[Test]
public void NonVoidMethodInActionLambdaIsValidConversion()
{
string program = @"using System;
class TestClass {
void Run(Action a) { }
int M() {
Run(() => $M()$);
}
}";
var c = GetConversion(program);
Assert.IsTrue(c.IsValid);
}
[Test]
public void NonVoidMethodInImplicitlyTypedActionLambdaIsValidConversion()
{
string program = @"using System;
class TestClass {
void Run(Action<string> a) { }
int M() {
Run(x => $M()$);
}
}";
var c = GetConversion(program);
Assert.IsTrue(c.IsValid);
}
/* TODO write test for this
class A
{

26
ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs

@ -159,7 +159,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -159,7 +159,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
}
protected ResolveResult Resolve(string code)
protected Tuple<CSharpAstResolver, AstNode> PrepareResolver(string code)
{
CompilationUnit cu = new CSharpParser().Parse(new StringReader(code.Replace("$", "")), "code.cs");
@ -176,16 +176,34 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -176,16 +176,34 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
cu.AcceptVisitor(fnv, null);
Assert.IsNotNull(fnv.ResultNode, "Did not find DOM node at the specified location");
CSharpAstResolver resolver = new CSharpAstResolver(compilation, cu, parsedFile);
return Tuple.Create(resolver, fnv.ResultNode);
}
protected ResolveResult Resolve(string code)
{
var prep = PrepareResolver(code);
Debug.WriteLine(new string('=', 70));
Debug.WriteLine("Starting new resolver for " + fnv.ResultNode);
Debug.WriteLine("Starting new resolver for " + prep.Item2);
CSharpAstResolver resolver = new CSharpAstResolver(compilation, cu, parsedFile);
ResolveResult rr = resolver.Resolve(fnv.ResultNode);
ResolveResult rr = prep.Item1.Resolve(prep.Item2);
Assert.IsNotNull(rr, "ResolveResult is null - did something go wrong while navigating to the target node?");
Debug.WriteLine("ResolveResult is " + rr);
return rr;
}
protected Conversion GetConversion(string code)
{
var prep = PrepareResolver(code);
return prep.Item1.GetConversion((Expression)prep.Item2);
}
protected IType GetExpectedType(string code)
{
var prep = PrepareResolver(code);
return prep.Item1.GetExpectedType((Expression)prep.Item2);
}
protected T Resolve<T>(string code) where T : ResolveResult
{
ResolveResult rr = Resolve(code);

Loading…
Cancel
Save