From 4380297cceaaae42856ab0f198d4923f0b7e8470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20K=C3=A4ll=C3=A9n?= Date: Tue, 26 Feb 2013 23:37:18 +0100 Subject: [PATCH] Add a ConversionResolveResult to lambda body expressions, if required --- .../Resolver/ResolveVisitor.cs | 24 +++++++++++++---- .../CSharp/Resolver/LambdaTests.cs | 26 +++++++++++++++++++ 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs b/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs index 12ccc00fd3..221c2c54d8 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs @@ -2000,6 +2000,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver CSharpResolver storedContext; ResolveVisitor visitor; AstNode body; + ResolveResult bodyRR; IType inferredReturnType; IList returnExpressions; @@ -2024,12 +2025,20 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver public override ResolveResult Body { get { + if (bodyRR != null) + return bodyRR; + if (body is Expression) { Analyze(); - if (returnValues.Count == 1) - return returnValues[0]; + if (returnValues.Count == 1) { + bodyRR = returnValues[0]; + var conv = storedContext.conversions.ImplicitConversion(bodyRR, actualReturnType); + if (!conv.IsIdentityConversion) + bodyRR = new ConversionResolveResult(actualReturnType, bodyRR, conv, storedContext.CheckForOverflow); + return bodyRR; + } } - return visitor.voidResult; + return bodyRR = visitor.voidResult; } } @@ -2282,7 +2291,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver return h; } ResolveVisitor visitor = new ResolveVisitor(storedContext, unresolvedFile); - var newHypothesis = new LambdaTypeHypothesis(this, parameterTypes, visitor, lambda != null ? lambda.Parameters : null); + var newHypothesis = new LambdaTypeHypothesis(this, parameterTypes, visitor, lambda != null ? lambda.Parameters : null, storedContext); hypotheses.Add(newHypothesis); return newHypothesis; } @@ -2360,6 +2369,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver readonly IParameter[] lambdaParameters; internal readonly IType[] parameterTypes; readonly ResolveVisitor visitor; + readonly CSharpResolver storedContext; internal readonly IType inferredReturnType; IList returnExpressions; @@ -2369,13 +2379,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver internal bool success; public LambdaTypeHypothesis(ImplicitlyTypedLambda lambda, IType[] parameterTypes, ResolveVisitor visitor, - ICollection parameterDeclarations) + ICollection parameterDeclarations, CSharpResolver storedContext) { Debug.Assert(parameterTypes.Length == lambda.Parameters.Count); this.lambda = lambda; this.parameterTypes = parameterTypes; this.visitor = visitor; + this.storedContext = storedContext; visitor.SetNavigator(this); Log.WriteLine("Analyzing " + ToString() + "..."); @@ -2454,6 +2465,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver lambda.parameters = lambdaParameters; // replace untyped parameters with typed parameters if (lambda.BodyExpression is Expression && returnValues.Count == 1) { lambda.bodyResult = returnValues[0]; + var conv = storedContext.conversions.ImplicitConversion(lambda.bodyResult, returnType); + if (!conv.IsIdentityConversion) + lambda.bodyResult = new ConversionResolveResult(returnType, lambda.bodyResult, conv, storedContext.CheckForOverflow); } Log.WriteLine("Applying return type {0} to implicitly-typed lambda {1}", returnType, lambda.LambdaExpression); diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LambdaTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LambdaTests.cs index 67766a4c31..0c59016623 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LambdaTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/LambdaTests.cs @@ -668,5 +668,31 @@ class C Assert.IsFalse(mrr.IsError); Assert.AreEqual("System.Threading.Tasks.Task", mrr.Type.ReflectionName); } + + [Test] + public void ConversionInExplicitLambdaResult() { + string program = @"using System; +class Test { + public object M() { + System.Func f = $(int i) => null$; + } +}"; + var rr = Resolve(program); + Assert.IsInstanceOf(rr.Body); + Assert.That(((ConversionResolveResult)rr.Body).Conversion.IsNullLiteralConversion); + } + + [Test] + public void ConversionInImplicitLambdaResult() { + string program = @"using System; +class Test { + public object M() { + System.Func f = $i => null$; + } +}"; + var rr = Resolve(program); + Assert.IsInstanceOf(rr.Body); + Assert.That(((ConversionResolveResult)rr.Body).Conversion.IsNullLiteralConversion); + } } }