Browse Source

[CodeIssues] New issue to convert .Where(p).Any() to .Any(p). (from shani)

newNRvisualizers
Mike Krüger 14 years ago
parent
commit
f43d5df0e2
  1. 1
      ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj
  2. 64
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantWhereWithPredicateIssue.cs
  3. 70
      ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/RedundantWhereWithPredicateIssueTests.cs
  4. 1
      ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj

1
ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj

@ -498,6 +498,7 @@ @@ -498,6 +498,7 @@
<Compile Include="Refactoring\CodeActions\ConvertLambdaToAnonymousDelegateAction.cs" />
<Compile Include="Refactoring\CodeIssues\ParameterCanBeDemotedIssue\IsArrayTypeCriterion.cs" />
<Compile Include="Refactoring\CodeIssues\ParameterCanBeDemotedIssue\SupportsIndexingCriterion.cs" />
<Compile Include="Refactoring\CodeIssues\RedundantWhereWithPredicateIssue.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj">

64
ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantWhereWithPredicateIssue.cs

@ -0,0 +1,64 @@ @@ -0,0 +1,64 @@
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.PatternMatching;
namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
[IssueDescription("Any() should be used with predicate and Where() removed",
Description= "Detects redundant Where() with predicate calls followed by Any().",
Category = IssueCategories.CodeQualityIssues,
Severity = Severity.Hint)]
public class RedundantWhereWithPredicateIssue : ICodeIssueProvider
{
static readonly AstNode pattern =
new InvocationExpression (
new MemberReferenceExpression (
new NamedNode ("whereInvoke",
new InvocationExpression (
new MemberReferenceExpression (new AnyNode ("target"), "Where"),
new AnyNode ())),
"Any"));
public IEnumerable<CodeIssue> GetIssues(BaseRefactoringContext context)
{
return new GatherVisitor(context).GetIssues();
}
class GatherVisitor : GatherVisitorBase
{
public GatherVisitor (BaseRefactoringContext ctx) : base (ctx)
{
}
public override void VisitInvocationExpression (InvocationExpression anyInvoke)
{
base.VisitInvocationExpression (anyInvoke);
var match = pattern.Match (anyInvoke);
if (!match.Success)
return;
var anyResolve = ctx.Resolve (anyInvoke) as InvocationResolveResult;
if (anyResolve == null || anyResolve.Member.FullName != "System.Linq.Enumerable.Any")
return;
var whereInvoke = match.Get<InvocationExpression> ("whereInvoke").Single ();
var whereResolve = ctx.Resolve (whereInvoke) as InvocationResolveResult;
if (whereResolve == null || whereResolve.Member.FullName != "System.Linq.Enumerable.Where")
return;
if (whereResolve.Member.Parameters.Count != 2)
return;
var predResolve = whereResolve.Member.Parameters [1];
if (predResolve.Type.TypeParameterCount != 2)
return;
AddIssue (anyInvoke, "Redundant Where() call with predicate followed by Any()", script => {
var arg = whereInvoke.Arguments.Single ().Clone ();
var target = match.Get<Expression> ("target").Single ().Clone ();
script.Replace (anyInvoke, new InvocationExpression (new MemberReferenceExpression (target, "Any"), arg));
});
}
}
}
}

70
ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/RedundantWhereWithPredicateIssueTests.cs

@ -0,0 +1,70 @@ @@ -0,0 +1,70 @@
using System;
using NUnit.Framework;
using ICSharpCode.NRefactory.CSharp.Refactoring;
using ICSharpCode.NRefactory.CSharp.CodeActions;
namespace ICSharpCode.NRefactory.CSharp.CodeIssues
{
[TestFixture]
public class RedundantWhereWithPredicateIssueTests : InspectionActionTestBase
{
[Test]
public void TestWhereAnyCase1 ()
{
var input = @"using System.Linq;
public class CSharpDemo {
public void Bla () {
int[] arr;
var bla = arr.Where (x => x < 4).Any ();
}
}";
TestRefactoringContext context;
var issues = GetIssues (new RedundantWhereWithPredicateIssue (), input, out context);
Assert.AreEqual (1, issues.Count);
CheckFix (context, issues, @"using System.Linq;
public class CSharpDemo {
public void Bla () {
int[] arr;
var bla = arr.Any (x => x < 4);
}
}");
}
[Test]
public void TestWhereAnyWrongWhere1 ()
{
var input = @"using System.Linq;
public class CSharpDemo {
public void Bla () {
int[] arr;
var bla = arr.Where ((x, i) => x + i < 4).Any ();
}
}";
TestRefactoringContext context;
var issues = GetIssues (new RedundantWhereWithPredicateIssue (), input, out context);
Assert.AreEqual (0, issues.Count);
}
[Test]
public void TestWhereAnyWrongWhere2 ()
{
var input = @"using System;
using System.Linq;
public class X
{
X Where (Func<int,int> f) { return null; }
bool Any () { return false; }
public void Bla () {
X ex = null;
var bla = ex.Where (x => x + 1).Any ();
}
}";
TestRefactoringContext context;
var issues = GetIssues (new RedundantWhereWithPredicateIssue (), input, out context);
Assert.AreEqual (0, issues.Count);
}
}
}

1
ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj

@ -359,6 +359,7 @@ @@ -359,6 +359,7 @@
<Compile Include="CSharp\CodeActions\ConvertLamdaToAnonymousDelegateTests.cs" />
<Compile Include="CSharp\CodeIssues\ParameterCanBeDemotedIssue\SupportsIndexingCriterionTests.cs" />
<Compile Include="CSharp\CodeActions\CreateBackingStoreTests.cs" />
<Compile Include="CSharp\CodeIssues\RedundantWhereWithPredicateIssueTests.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Mono.Cecil\Mono.Cecil.csproj">

Loading…
Cancel
Save