From 42921dca18d0553b122c656974c191bc779a104a Mon Sep 17 00:00:00 2001 From: leoowen19 Date: Tue, 9 Apr 2013 03:06:45 +0800 Subject: [PATCH] [CodeIssue] Redundant Constructor issue Do not need an empty constructor --- .../ICSharpCode.NRefactory.CSharp.csproj | 1 + .../RedudantConstructorIssue.cs | 98 +++++++++++++++++++ .../CodeIssues/RedundantConstructorTests.cs | 96 ++++++++++++++++++ .../ICSharpCode.NRefactory.Tests.csproj | 6 +- 4 files changed, 199 insertions(+), 2 deletions(-) create mode 100755 ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ConstructorIssues/RedudantConstructorIssue.cs create mode 100755 ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/RedundantConstructorTests.cs diff --git a/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj b/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj index e1c88cd9d6..7581d1d3bc 100644 --- a/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj +++ b/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj @@ -531,6 +531,7 @@ + diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ConstructorIssues/RedudantConstructorIssue.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ConstructorIssues/RedudantConstructorIssue.cs new file mode 100755 index 0000000000..d84ebd94bc --- /dev/null +++ b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ConstructorIssues/RedudantConstructorIssue.cs @@ -0,0 +1,98 @@ +// +// RedundantConstructorIssue.cs +// +// Author: +// Ji Kun +// +// Copyright (c) 2013 Ji Kun +// +// 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 SaHALL 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 System.Collections.Generic; +using System.Linq; +using ICSharpCode.NRefactory.CSharp.Resolver; +using ICSharpCode.NRefactory.Semantics; +using ICSharpCode.NRefactory.TypeSystem; + +namespace ICSharpCode.NRefactory.CSharp.Refactoring +{ + [IssueDescription("An empty constructor is not necessary", + Description = "An alone empty constructor is not necessary.", + Category = IssueCategories.Redundancies, + Severity = Severity.Suggestion, + ResharperDisableKeyword = "RedundantConstructor", + IssueMarker = IssueMarker.GrayOut)] + public class RedundantConstructorIssue : ICodeIssueProvider + { + public IEnumerable GetIssues(BaseRefactoringContext context) + { + var unit = context.RootNode as SyntaxTree; + if (unit == null) + return Enumerable.Empty(); + return new GatherVisitor(context).GetIssues(); + } + + class GatherVisitor : GatherVisitorBase + { + public GatherVisitor(BaseRefactoringContext ctx) + : base(ctx) + { + } + + public override void VisitTypeDeclaration(TypeDeclaration typedeclaration) + { + var typeResolveResult = ctx.Resolve(typedeclaration) as TypeResolveResult; + var constructors = typeResolveResult.GetType().GetConstructors(); + bool hasEmptyConstructor = false; + bool hasUnemptyConstructor = false; + ConstructorDeclaration emptyContructorNode = new ConstructorDeclaration(); + + foreach (var child in typedeclaration.Children) + { + if (child is ConstructorDeclaration) + { + if ((child as ConstructorDeclaration).HasModifier(Modifiers.Static)) + continue; + if ((child as ConstructorDeclaration).Body.Count() > 0 || + ((child as ConstructorDeclaration).Parameters.Count > 0)) + { + hasUnemptyConstructor = true; + } + else if ((child as ConstructorDeclaration).HasModifier(Modifiers.Public)) + { + hasEmptyConstructor = true; + emptyContructorNode = child as ConstructorDeclaration; + } + } + } + + if (!hasUnemptyConstructor && hasEmptyConstructor) + { + AddIssue(emptyContructorNode, ctx.TranslateString("Remove redundant constructor"), script => + { + script.Remove(emptyContructorNode); + } + ); + } + return; + } + } + } +} diff --git a/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/RedundantConstructorTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/RedundantConstructorTests.cs new file mode 100755 index 0000000000..36ee8beb29 --- /dev/null +++ b/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/RedundantConstructorTests.cs @@ -0,0 +1,96 @@ +// +// RedundantConstructorTest.cs +// +// Author: +// Ji Kun +// +// Copyright (c) 2013 Ji Kun +// +// 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 +{ + [TestFixture] + public class RedundantConstructorTests : InspectionActionTestBase + { + [Test] + public void TestInspectorCase1() + { + var input = @"using System;class Test {private int member; public Test(){}}"; + + TestRefactoringContext context; + var issues = GetIssues(new RedundantConstructorIssue(), input, out context); + Assert.AreEqual(1, issues.Count); + + CheckFix(context, issues, @"using System;class Test {private int member; }"); + } + + [Test] + public void TestInspectorCase2() + { + var input = @"using System;class Test {private int member;public Test(){} static Test(){}}"; + + TestRefactoringContext context; + var issues = GetIssues(new RedundantConstructorIssue(), input, out context); + Assert.AreEqual(1, issues.Count); + + CheckFix(context, issues, @"using System;class Test {private int member; static Test(){}}"); + } + + [Test] + public void TestResharperDisable() + { + var input = @"using System; + //Resharper disable RedundantConstructor +class Test { + public Test(){ + } + //Resharper restore RedundantConstructor + }"; + + TestRefactoringContext context; + var issues = GetIssues(new RedundantConstructorIssue(), input, out context); + Assert.AreEqual(0, issues.Count); + } + + [Test] + public void TestNegateCase1() + { + var input = @"using System;class Test {public Test(){;}}"; + + TestRefactoringContext context; + var issues = GetIssues(new RedundantConstructorIssue(), input, out context); + Assert.AreEqual(0, issues.Count); + } + + [Test] + public void TestNegateCase2() + { + var input = @"using System;class Test {public Test(){;} private Test(){}}"; + + TestRefactoringContext context; + var issues = GetIssues(new RedundantConstructorIssue(), input, out context); + Assert.AreEqual(0, issues.Count); + } + } +} \ No newline at end of file diff --git a/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj b/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj index 0b56890a88..573ad1310f 100644 --- a/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj +++ b/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj @@ -1,4 +1,4 @@ - + {63D3B27A-D966-4902-90B3-30290E1692F1} @@ -403,8 +403,10 @@ - + + +