From c76cb9248de8966b25bc08b098b88d6734b96d09 Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Wed, 24 Jul 2019 16:21:19 -0700 Subject: [PATCH] Add support for increment/decrement [Parameter] usage detection. - Didn't realize there was an increment or decrement operation kind. - Added tests to cover this scenario #12543 --- .../src/ComponentParameterUsageAnalyzer.cs | 16 ++++- .../ComponentParameterUsageAnalyzerTest.cs | 63 +++++++++++++++++++ 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/src/Components/Analyzers/src/ComponentParameterUsageAnalyzer.cs b/src/Components/Analyzers/src/ComponentParameterUsageAnalyzer.cs index 0d45edcabc..8df3167b83 100644 --- a/src/Components/Analyzers/src/ComponentParameterUsageAnalyzer.cs +++ b/src/Components/Analyzers/src/ComponentParameterUsageAnalyzer.cs @@ -38,8 +38,18 @@ namespace Microsoft.AspNetCore.Components.Analyzers { startBlockContext.RegisterOperationAction(context => { - var assignmentOperation = (IAssignmentOperation)context.Operation; - var leftHandSide = assignmentOperation.Target; + IOperation leftHandSide; + + if (context.Operation is IAssignmentOperation assignmentOperation) + { + leftHandSide = assignmentOperation.Target; + } + else + { + var incrementOrDecrementOperation = (IIncrementOrDecrementOperation)context.Operation; + leftHandSide = incrementOrDecrementOperation.Target; + } + if (leftHandSide == null) { // Malformed assignment, no left hand side. @@ -96,7 +106,7 @@ namespace Microsoft.AspNetCore.Components.Analyzers DiagnosticDescriptors.ComponentParametersShouldNotBeSetOutsideOfTheirDeclaredComponent, propertyReference.Syntax.GetLocation(), propertyReference.Member.Name)); - }, OperationKind.SimpleAssignment, OperationKind.CompoundAssignment, OperationKind.CoalesceAssignment); + }, OperationKind.SimpleAssignment, OperationKind.CompoundAssignment, OperationKind.CoalesceAssignment, OperationKind.Increment, OperationKind.Decrement); }); }); } diff --git a/src/Components/Analyzers/test/ComponentParameterUsageAnalyzerTest.cs b/src/Components/Analyzers/test/ComponentParameterUsageAnalyzerTest.cs index db664a2e76..d1c2d2bede 100644 --- a/src/Components/Analyzers/test/ComponentParameterUsageAnalyzerTest.cs +++ b/src/Components/Analyzers/test/ComponentParameterUsageAnalyzerTest.cs @@ -19,6 +19,7 @@ namespace Microsoft.AspNetCore.Components.Analyzers class TestComponent : IComponent {{ [Parameter] public string TestProperty {{ get; set; }} + [Parameter] public int TestInt {{ get; set; }} public string NonParameter {{ get; set; }} }} }}" + ComponentsTestDeclarations.Source; @@ -119,6 +120,68 @@ namespace Microsoft.AspNetCore.Components.Analyzers }); } + [Fact] + public void ComponentPropertyIncrement_Warns() + { + var test = $@" + namespace ConsoleApplication1 + {{ + using {typeof(ParameterAttribute).Namespace}; + class OtherComponent : IComponent + {{ + private TestComponent _testComponent; + void Render() + {{ + _testComponent = new TestComponent(); + _testComponent.TestInt++; + }} + }} + }}" + ComponentTestSource; + + VerifyCSharpDiagnostic(test, + new DiagnosticResult + { + Id = DiagnosticDescriptors.ComponentParametersShouldNotBeSetOutsideOfTheirDeclaredComponent.Id, + Message = "Component parameter 'TestInt' should not be set outside of its component.", + Severity = DiagnosticSeverity.Warning, + Locations = new[] + { + new DiagnosticResultLocation("Test0.cs", 11, 17) + } + }); + } + + [Fact] + public void ComponentPropertyDecrement_Warns() + { + var test = $@" + namespace ConsoleApplication1 + {{ + using {typeof(ParameterAttribute).Namespace}; + class OtherComponent : IComponent + {{ + private TestComponent _testComponent; + void Render() + {{ + _testComponent = new TestComponent(); + _testComponent.TestInt--; + }} + }} + }}" + ComponentTestSource; + + VerifyCSharpDiagnostic(test, + new DiagnosticResult + { + Id = DiagnosticDescriptors.ComponentParametersShouldNotBeSetOutsideOfTheirDeclaredComponent.Id, + Message = "Component parameter 'TestInt' should not be set outside of its component.", + Severity = DiagnosticSeverity.Warning, + Locations = new[] + { + new DiagnosticResultLocation("Test0.cs", 11, 17) + } + }); + } + [Fact] public void ComponentPropertyExpression_Ignores() {