From b803d850f785462ff4575640baa8d4e0654f2eab Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Mon, 23 Jan 2012 18:54:38 +0100 Subject: [PATCH] Do not report invalid conversion from int to void for this code: void Run(Action a) { } int M() { Run(x => $M()$); } --- .../Resolver/ResolveVisitor.cs | 12 +++++--- .../CSharp/Resolver/LambdaTests.cs | 28 +++++++++++++++++++ .../CSharp/Resolver/ResolverTestBase.cs | 26 ++++++++++++++--- 3 files changed, 58 insertions(+), 8 deletions(-) diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs b/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs index 58eb1946ce..58411c567e 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs @@ -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 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(); diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LambdaTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LambdaTests.cs index 6bdab5b599..7e54b8c730 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LambdaTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LambdaTests.cs @@ -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 a) { } + int M() { + Run(x => $M()$); + } +}"; + var c = GetConversion(program); + Assert.IsTrue(c.IsValid); + } + /* TODO write test for this class A { diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs index 7cba4c32a7..d44cc4f161 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs @@ -159,7 +159,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver } } - protected ResolveResult Resolve(string code) + protected Tuple PrepareResolver(string code) { CompilationUnit cu = new CSharpParser().Parse(new StringReader(code.Replace("$", "")), "code.cs"); @@ -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(string code) where T : ResolveResult { ResolveResult rr = Resolve(code);