From 0d8b154fa267218eb677eff64a541ab6e1028249 Mon Sep 17 00:00:00 2001 From: Gen Lu Date: Tue, 26 Jan 2016 11:11:38 -0800 Subject: [PATCH] Make registering OperationKind.None not to return any operation. --- .../CSharp/Portable/BoundTree/Expression.cs | 2 +- .../Diagnostics/OperationAnalyzerTests.cs | 20 ++++++++++ .../Diagnostics/OperationTestAnalyzer.cs | 37 +++++++++++++++++++ .../Portable/BoundTree/Expression.vb | 2 +- .../Diagnostics/OperationAnalyzerTests.vb | 27 ++++++++++++++ 5 files changed, 86 insertions(+), 2 deletions(-) diff --git a/src/Compilers/CSharp/Portable/BoundTree/Expression.cs b/src/Compilers/CSharp/Portable/BoundTree/Expression.cs index 4ed63ca0710..4f26a977c88 100644 --- a/src/Compilers/CSharp/Portable/BoundTree/Expression.cs +++ b/src/Compilers/CSharp/Portable/BoundTree/Expression.cs @@ -71,7 +71,7 @@ public Collector(List nodes) public override BoundNode Visit(BoundNode node) { IOperation operation = node as IOperation; - if (operation != null) + if (operation != null && operation.Kind != OperationKind.None) { this._nodes.Add(operation); // Certain child-operation of following operation kinds do not occur in bound nodes, diff --git a/src/Compilers/CSharp/Test/Semantic/Diagnostics/OperationAnalyzerTests.cs b/src/Compilers/CSharp/Test/Semantic/Diagnostics/OperationAnalyzerTests.cs index 4bd6d8f4919..9d4a007442a 100644 --- a/src/Compilers/CSharp/Test/Semantic/Diagnostics/OperationAnalyzerTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Diagnostics/OperationAnalyzerTests.cs @@ -1154,5 +1154,25 @@ public void M1() Diagnostic(ParamsArrayTestAnalyzer.LongParamsDescriptor.Id, "new int[] { 2, 3, 4, 5, 6 }").WithLocation(17, 15) ); } + + [Fact] + public void NoneOperationCSharp() + { + // BoundStatementList is OperationKind.None + const string source = @" +class C +{ + public void M0() + { + int x = 0; + int y = x++; + int z = y++; + } +} +"; + CreateCompilationWithMscorlib45(source) + .VerifyDiagnostics() + .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new NoneOperationTestAnalyzer() }, null, null, false); + } } } diff --git a/src/Compilers/Core/CodeAnalysisTest/Diagnostics/OperationTestAnalyzer.cs b/src/Compilers/Core/CodeAnalysisTest/Diagnostics/OperationTestAnalyzer.cs index eab54203bbb..6e2e282e641 100644 --- a/src/Compilers/Core/CodeAnalysisTest/Diagnostics/OperationTestAnalyzer.cs +++ b/src/Compilers/Core/CodeAnalysisTest/Diagnostics/OperationTestAnalyzer.cs @@ -1066,4 +1066,41 @@ private static long IntegralValue(object value) return 0; } } + + + /// Analyzer used to test None IOperations. + public class NoneOperationTestAnalyzer : DiagnosticAnalyzer + { + private const string ReliabilityCategory = "Reliability"; + + // We should not see this warning triggered by any code + public static readonly DiagnosticDescriptor NoneOperationDescriptor = new DiagnosticDescriptor( + "NoneOperation", + "None operation found", + "an IOperation of None kind is found", + ReliabilityCategory, + DiagnosticSeverity.Warning, + isEnabledByDefault: true); + + public sealed override ImmutableArray SupportedDiagnostics + { + get { return ImmutableArray.Create(NoneOperationDescriptor); } + } + + public sealed override void Initialize(AnalysisContext context) + { + context.RegisterOperationAction( + (operationContext) => + { + Report(operationContext, operationContext.Operation.Syntax, NoneOperationDescriptor); + }, + // None kind is only supposed to be used internally and will not actually register actions. + OperationKind.None); + } + + private static void Report(OperationAnalysisContext context, SyntaxNode syntax, DiagnosticDescriptor descriptor) + { + context.ReportDiagnostic(Diagnostic.Create(descriptor, syntax.GetLocation())); + } + } } \ No newline at end of file diff --git a/src/Compilers/VisualBasic/Portable/BoundTree/Expression.vb b/src/Compilers/VisualBasic/Portable/BoundTree/Expression.vb index 5453e02758d..63c55a0235a 100644 --- a/src/Compilers/VisualBasic/Portable/BoundTree/Expression.vb +++ b/src/Compilers/VisualBasic/Portable/BoundTree/Expression.vb @@ -35,7 +35,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Public Overrides Function Visit(node As BoundNode) As BoundNode Dim operation = TryCast(node, IOperation) - If operation IsNot Nothing Then + If operation IsNot Nothing AndAlso operation.Kind <> OperationKind.None Then Me._nodes.Add(operation) ' Certain child-operation of following operation kinds do not occur in bound nodes, ' and those child-operation nodes have to be added explicitly. diff --git a/src/Compilers/VisualBasic/Test/Semantic/Diagnostics/OperationAnalyzerTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Diagnostics/OperationAnalyzerTests.vb index eea9ed09bfa..1d6317cb2e1 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Diagnostics/OperationAnalyzerTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Diagnostics/OperationAnalyzerTests.vb @@ -1210,5 +1210,32 @@ End Class Diagnostic(ParamsArrayTestAnalyzer.LongParamsDescriptor.Id, "New Integer() { 2, 3, 4, 5, 6 }").WithLocation(13, 15), Diagnostic(ParamsArrayTestAnalyzer.LongParamsDescriptor.Id, "New Integer() { 2, 3, 4, 5, 6 }").WithLocation(13, 15)) End Sub + + + Public Sub NoneOperationVisualBasic() + ' BoundCaseStatement is OperationKind.None + Dim source = + + + + + + Dim comp = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime(source) + comp.VerifyDiagnostics() + comp.VerifyAnalyzerDiagnostics({New NoneOperationTestAnalyzer}, Nothing, Nothing, False) + End Sub End Class End Namespace -- GitLab