diff --git a/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj b/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj index b1ea024177..31a81b196c 100644 --- a/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj +++ b/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj @@ -375,6 +375,7 @@ + diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/SetterDoesNotUseValueParameterIssue.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/SetterDoesNotUseValueParameterIssue.cs new file mode 100644 index 0000000000..87ecd2c340 --- /dev/null +++ b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/SetterDoesNotUseValueParameterIssue.cs @@ -0,0 +1,92 @@ +// +// SetterDoesNotUseValueParameterTests.cs +// +// Author: +// Simon Lindgren +// +// Copyright (c) 2012 Simon Lindgren +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System.Collections.Generic; +using ICSharpCode.NRefactory.Semantics; + +namespace ICSharpCode.NRefactory.CSharp.Refactoring +{ + [IssueDescription("Property or indexer setter does not use the value parameter", + Description = "Warns about property or indexer setters that do not use the value parameter.", + Category = IssueCategories.CodeQualityIssues, + Severity = Severity.Warning)] + public class SetterDoesNotUseValueParameterIssue : ICodeIssueProvider + { + public IEnumerable GetIssues(BaseRefactoringContext context) + { + return new GatherVisitor(context, this).GetIssues(); + } + + class GatherVisitor : GatherVisitorBase + { + readonly BaseRefactoringContext context; + + public GatherVisitor(BaseRefactoringContext context, SetterDoesNotUseValueParameterIssue inspector) : base (context) + { + this.context = context; + } + + public override void VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration) + { + FindIssuesInNode(indexerDeclaration.Setter.Body); + } + + public override void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration) + { + FindIssuesInNode(propertyDeclaration.Setter.Body); + } + + void FindIssuesInNode(AstNode node) + { + var setterVisitor = new ReferenceFinderVisitor(context, "value"); + node.AcceptVisitor(setterVisitor); + if (!setterVisitor.FoundReference) + AddIssue(node, context.TranslateString("The setter does not use the 'value' parameter.")); + } + } + + class ReferenceFinderVisitor: DepthFirstAstVisitor + { + readonly BaseRefactoringContext context; + readonly string variableName; + + public ReferenceFinderVisitor(BaseRefactoringContext context, string variableName) + { + this.context = context; + this.variableName = variableName; + } + + public bool FoundReference { get; private set; } + + public override void VisitIdentifierExpression(IdentifierExpression identifierExpression) + { + var resolvedIdentifier = context.Resolve(identifierExpression) as LocalResolveResult; + if (resolvedIdentifier != null) + FoundReference |= resolvedIdentifier.Variable.Name == variableName; + base.VisitIdentifierExpression(identifierExpression); + } + } + } +} diff --git a/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/SetterDoesNotUseValueParameterTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/SetterDoesNotUseValueParameterTests.cs new file mode 100644 index 0000000000..8af25d3d87 --- /dev/null +++ b/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/SetterDoesNotUseValueParameterTests.cs @@ -0,0 +1,91 @@ +// +// SetterDoesNotUseValueParameterTests.cs +// +// Author: +// Simon Lindgren +// +// Copyright (c) 2012 Simon Lindgren +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +using NUnit.Framework; +using ICSharpCode.NRefactory.CSharp.Refactoring; +using ICSharpCode.NRefactory.CSharp.CodeActions; + +namespace ICSharpCode.NRefactory.CSharp.CodeIssues +{ + public class SetterDoesNotUseValueParameterTests : InspectionActionTestBase + { + [Test] + public void TestPropertySetter() + { + var input = @"class A +{ + int Property1 + { + set { + int val = value; + } + } + int Property2 + { + set { + } + } +}"; + TestRefactoringContext context; + var issues = GetIssues(new SetterDoesNotUseValueParameterIssue(), input, out context); + Assert.AreEqual(1, issues.Count); + } + + [Test] + public void TestMatchingIndexerSetter() + { + var input = @"class A +{ + A this[int index] + { + set { + } + } +}"; + TestRefactoringContext context; + var issues = GetIssues(new SetterDoesNotUseValueParameterIssue(), input, out context); + Assert.AreEqual(1, issues.Count); + } + + [Test] + public void TestNonMatchingIndexerSetter() + { + var input = @"class A +{ + A this[int index] + { + set { + A a = value; + } + } +}"; + TestRefactoringContext context; + var issues = GetIssues(new SetterDoesNotUseValueParameterIssue(), input, out context); + Assert.AreEqual(0, issues.Count); + } + } +} + diff --git a/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj b/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj index 236ed2d0d4..47de767cf8 100644 --- a/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj +++ b/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj @@ -271,6 +271,7 @@ +