From 4bbcf2dc11e15077ec7c406ebf63ca27af503e8a Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Mon, 10 Oct 2011 22:50:49 +0200 Subject: [PATCH] Add "public ResolveResult Body { get; }" to LambdaResolveResult. --- .../OutputVisitor/CSharpOutputVisitor.cs | 2 +- .../Resolver/LambdaResolveResult.cs | 11 ++++++ .../Resolver/ResolveVisitor.cs | 34 ++++++++++++++++--- .../Resolver/OverloadResolutionTests.cs | 4 +++ .../CSharp/Resolver/TypeInferenceTests.cs | 4 +++ .../PatternMatching/Match.cs | 2 +- 6 files changed, 50 insertions(+), 7 deletions(-) diff --git a/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs b/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs index a7eeedd00d..c5411d49e0 100644 --- a/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs +++ b/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs @@ -2418,7 +2418,7 @@ namespace ICSharpCode.NRefactory.CSharp } else if (childNode is OptionalNode) { VisitOptionalNode((OptionalNode)childNode, data); } else { - throw new InvalidOperationException ("Unknown node type in pattern"); + WritePrimitiveValue(childNode); } } #endregion diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/LambdaResolveResult.cs b/ICSharpCode.NRefactory.CSharp/Resolver/LambdaResolveResult.cs index 5c25cd5c2f..86a5e24c6f 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/LambdaResolveResult.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/LambdaResolveResult.cs @@ -73,5 +73,16 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver /// otherwise returns . /// public abstract Conversion IsValid(IType[] parameterTypes, IType returnType, Conversions conversions); + + /// + /// Gets the resolve result for the lambda body. + /// Returns a resolve result for 'void' for statement lambdas. + /// + public abstract ResolveResult Body { get; } + + public override IEnumerable GetChildResults() + { + return new [] { this.Body }; + } } } diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs b/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs index 079a7a6af7..742dff4144 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs @@ -1700,10 +1700,21 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver get { return body.Parent; } } - internal override AstNode Body { + internal override AstNode BodyExpression { get { return body; } } + public override ResolveResult Body { + get { + if (body is Expression) { + Analyze(); + if (returnValues.Count == 1) + return returnValues[0]; + } + return visitor.voidResult; + } + } + public ExplicitlyTypedLambda(IList parameters, bool isAnonymousMethod, bool isAsync, CSharpResolver storedContext, ResolveVisitor visitor, AstNode body) { this.parameters = parameters; @@ -1833,6 +1844,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver readonly List parameters = new List(); internal LambdaTypeHypothesis winningHypothesis; + internal ResolveResult bodyResult; internal readonly ResolveVisitor parentVisitor; internal override bool IsUndecided { @@ -1848,7 +1860,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver } } - internal override AstNode Body { + internal override AstNode BodyExpression { get { if (selectClause != null) return selectClause.Expression; @@ -1857,11 +1869,16 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver } } + public override ResolveResult Body { + get { return bodyResult; } + } + private ImplicitlyTypedLambda(ResolveVisitor parentVisitor) { this.parentVisitor = parentVisitor; this.storedContext = parentVisitor.resolver.Clone(); this.parsedFile = parentVisitor.parsedFile; + this.bodyResult = parentVisitor.voidResult; } public ImplicitlyTypedLambda(LambdaExpression lambda, ResolveVisitor parentVisitor) @@ -2043,7 +2060,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver } } - visitor.AnalyzeLambda(lambda.Body, lambda.IsAsync, out success, out isValidAsVoidMethod, out inferredReturnType, out returnExpressions, out returnValues); + visitor.AnalyzeLambda(lambda.BodyExpression, lambda.IsAsync, out success, out isValidAsVoidMethod, out inferredReturnType, out returnExpressions, out returnValues); visitor.resolver.PopBlock(); Log.Unindent(); Log.WriteLine("Finished analyzing " + ToString()); @@ -2081,6 +2098,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver throw new InvalidOperationException("Trying to merge conflicting hypotheses"); lambda.winningHypothesis = this; + if (lambda.BodyExpression is Expression && returnValues.Count == 1) { + lambda.bodyResult = returnValues[0]; + } Log.WriteLine("Applying return type {0} to implicitly-typed lambda {1}", returnType, lambda.LambdaExpression); if (lambda.IsAsync) @@ -2111,7 +2131,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver b.Append(lambda.Parameters[i].Name); } b.Append(") => "); - b.Append(lambda.Body.ToString()); + b.Append(lambda.BodyExpression.ToString()); b.Append(']'); return b.ToString(); } @@ -2123,7 +2143,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver { internal abstract bool IsUndecided { get; } internal abstract AstNode LambdaExpression { get; } - internal abstract AstNode Body { get; } + internal abstract AstNode BodyExpression { get; } internal abstract void EnforceMerge(ResolveVisitor parentVisitor); } @@ -2925,6 +2945,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver get { return true; } } + public override ResolveResult Body { + get { return bodyExpression; } + } + public override IType GetInferredReturnType(IType[] parameterTypes) { return bodyExpression.Type; diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/OverloadResolutionTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/OverloadResolutionTests.cs index 75620bf376..d38174d2af 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/OverloadResolutionTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/OverloadResolutionTests.cs @@ -240,6 +240,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver get { return false; } } + public override ResolveResult Body { + get { throw new NotImplementedException(); } + } + public override IType GetInferredReturnType(IType[] parameterTypes) { return inferredReturnType; diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/TypeInferenceTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/TypeInferenceTests.cs index 12bdcdfe2c..5f43d8aae1 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/TypeInferenceTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/TypeInferenceTests.cs @@ -179,6 +179,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver get { return false; } } + public override ResolveResult Body { + get { throw new NotImplementedException(); } + } + public override IType GetInferredReturnType(IType[] parameterTypes) { Assert.AreEqual(expectedParameterTypes, parameterTypes, "Parameters types passed to " + this); diff --git a/ICSharpCode.NRefactory/PatternMatching/Match.cs b/ICSharpCode.NRefactory/PatternMatching/Match.cs index de13c035dd..ea9a871d31 100644 --- a/ICSharpCode.NRefactory/PatternMatching/Match.cs +++ b/ICSharpCode.NRefactory/PatternMatching/Match.cs @@ -83,7 +83,7 @@ namespace ICSharpCode.NRefactory.PatternMatching return false; } - internal void Add(string groupName, INode node) + public void Add(string groupName, INode node) { if (groupName != null && node != null) { results.Add(new KeyValuePair(groupName, node));