提交 7d02e6cf 编写于 作者: D Dennis Fischer 提交者: Neal Gafter

Fix that the full bound tree is not cached for ArrowExpressionClauseSyntax

An ArrowExpressionClauseSyntax is special because it has an expression as its direct child. Because of that the binder was not correctly caching all nodes of the bound tree and instead was falling back to binding decendand nodes by themself when asked for them. This fails if in the decendant nodes there is a color color case.

With this change the binder does cache all of the ArrowExpressionClauseSyntax's children including the correctly resolved symbols for a color color situation.
Fixes #5362
Closes #8167
上级 386162ea
......@@ -1192,7 +1192,7 @@ protected void GuardedAddBoundTreeForStandaloneSyntax(CSharpSyntaxNode syntax, B
if (!alreadyInTree)
{
if ((this.IsSpeculativeSemanticModel && syntax == _root) || syntax is StatementSyntax)
if (syntax == _root || syntax is StatementSyntax)
{
// Note: For speculative model we want to always cache the entire bound tree.
// If syntax is a statement, we need to add all its children.
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;
using Xunit;
......@@ -1729,6 +1733,89 @@ class X
CompileAndVerify(comp, expectedOutput: "42");
}
[WorkItem(5362, "https://github.com/dotnet/roslyn/issues/5362")]
[Fact]
public void TestColorColorSymbolInfoInArrowExpressionClauseSyntax()
{
const string source = @"public enum Lifetime
{
Persistent,
Transient,
Scoped
}
public class Example
{
public Lifetime Lifetime => Lifetime.Persistent;
// ^^^^^^^^
}";
var analyzer = new ColorColorSymbolInfoInArrowExpressionClauseSyntaxAnalyzer();
CreateCompilationWithMscorlibAndSystemCore(source, options: TestOptions.ReleaseDll)
.VerifyAnalyzerOccurrenceCount(new[] { analyzer }, 0);
Assert.True(analyzer.ActionFired);
}
class ColorColorSymbolInfoInArrowExpressionClauseSyntaxAnalyzer : DiagnosticAnalyzer
{
public bool ActionFired { get; private set; }
private static readonly DiagnosticDescriptor Descriptor =
new DiagnosticDescriptor("XY0000", "Test", "Test", "Test", DiagnosticSeverity.Warning, true, "Test", "Test");
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
=> ImmutableArray.Create(Descriptor);
public override void Initialize(AnalysisContext context)
{
context.RegisterSyntaxNodeAction(HandleMemberAccessExpression, SyntaxKind.SimpleMemberAccessExpression);
}
private void HandleMemberAccessExpression(SyntaxNodeAnalysisContext context)
{
ActionFired = true;
var memberAccessExpression = context.Node as MemberAccessExpressionSyntax;
var actualSymbol = context.SemanticModel.GetSymbolInfo(memberAccessExpression.Expression);
Assert.Equal("Lifetime", actualSymbol.Symbol.ToTestDisplayString());
Assert.Equal(SymbolKind.NamedType, actualSymbol.Symbol.Kind);
}
}
[WorkItem(5362, "https://github.com/dotnet/roslyn/issues/5362")]
[Fact]
public void TestColorColorSymbolInfoInArrowExpressionClauseSyntax_2()
{
const string source = @"public enum Lifetime
{
Persistent,
Transient,
Scoped
}
public class Example
{
public Lifetime Lifetime => Lifetime.Persistent;
// ^^^^^^^^
}";
var comp = CreateCompilationWithMscorlibAndSystemCore(source, options: TestOptions.ReleaseDll);
comp.VerifyDiagnostics();
var syntaxTree = comp.SyntaxTrees[0];
var syntaxRoot = syntaxTree.GetRoot();
var semanticModel = comp.GetSemanticModel(syntaxTree, false);
var memberAccess = syntaxRoot.DescendantNodes().Single(node => node.IsKind(SyntaxKind.SimpleMemberAccessExpression)) as MemberAccessExpressionSyntax;
Assert.Equal("Lifetime", memberAccess.Expression.ToString());
Assert.Equal("Lifetime.Persistent", memberAccess.ToString());
var actualSymbol = semanticModel.GetSymbolInfo(memberAccess.Expression);
Assert.Equal("Lifetime", actualSymbol.Symbol.ToTestDisplayString());
Assert.Equal(SymbolKind.NamedType, actualSymbol.Symbol.Kind);
}
#endregion Regression cases
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册