2
// DuplicateExpressionsInConditionsIssue.cs
5
// Ciprian Khlud <ciprian.mustiata@yahoo.com>
7
// Copyright (c) 2013 Ciprian Khlud
9
// Permission is hereby granted, free of charge, to any person obtaining a copy
10
// of this software and associated documentation files (the "Software"), to deal
11
// in the Software without restriction, including without limitation the rights
12
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
// copies of the Software, and to permit persons to whom the Software is
14
// furnished to do so, subject to the following conditions:
16
// The above copyright notice and this permission notice shall be included in
17
// all copies or substantial portions of the Software.
19
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27
using System.Collections.Generic;
28
using ICSharpCode.NRefactory.PatternMatching;
30
namespace ICSharpCode.NRefactory.CSharp.Refactoring
32
[IssueDescription("Expression has some redundant items",
33
Description = "Expression has some redundant items",
34
Category = IssueCategories.CodeQualityIssues,
35
Severity = Severity.Warning,
36
IssueMarker = IssueMarker.GrayOut,
37
ResharperDisableKeyword = "ConditionalTernaryEqualBranch")]
38
public class DuplicateExpressionsInConditionsIssue : ICodeIssueProvider
40
public IEnumerable<CodeIssue> GetIssues (BaseRefactoringContext context)
42
return new GatherVisitor (context).GetIssues ();
45
static readonly List<BinaryOperatorType> SupportedOperators = new List<BinaryOperatorType>();
46
static DuplicateExpressionsInConditionsIssue()
48
SupportedOperators.Add(BinaryOperatorType.BitwiseAnd);
49
SupportedOperators.Add(BinaryOperatorType.BitwiseOr);
50
SupportedOperators.Add(BinaryOperatorType.ConditionalAnd);
51
SupportedOperators.Add(BinaryOperatorType.ConditionalOr);
54
class GatherVisitor : GatherVisitorBase<IdenticalConditionalBranchIssue>
56
public GatherVisitor (BaseRefactoringContext ctx)
61
public override void VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression)
63
var expression = binaryOperatorExpression;
64
base.VisitBinaryOperatorExpression(expression);
65
if(!SupportedOperators.Contains(expression.Operator) )
67
var parentExpression = expression.Parent as BinaryOperatorExpression;
68
if(parentExpression!=null && parentExpression.Operator==expression.Operator)
70
//handle only parent sequence
73
var expressions = GetExpressions(binaryOperatorExpression, expression);
74
for(var i=0;i<expressions.Count-1;i++)
76
for (var j = i+1; j < expressions.Count; j++)
78
var expressionLeft = expressions[i];
79
var expressionRight = expressions[j];
80
if (!expressionLeft.IsMatch(expressionRight))
82
var action = new CodeAction(ctx.TranslateString("Remove redundant expression"),
83
script => RemoveRedundantExpression(script, expressionRight),
86
AddIssue(expressionRight,
87
ctx.TranslateString(string.Format("The expression '{0}' is identical in the left branch",
88
expressionRight)), action);
95
private static void RemoveRedundantExpression(Script script, AstNode expressionRight)
97
var parent = expressionRight.Parent as BinaryOperatorExpression;
98
if(parent==null) //should never happen!
100
script.Replace(parent, parent.Left.Clone());
103
private static List<Expression> GetExpressions(BinaryOperatorExpression binaryOperatorExpression,
104
BinaryOperatorExpression expression)
106
var baseExpression = expression;
107
var leftExpression = baseExpression.FirstChild as BinaryOperatorExpression;
108
var expressions = new List<Expression>();
109
while (leftExpression != null && binaryOperatorExpression.Operator == leftExpression.Operator)
111
expressions.Add(baseExpression.Right);
112
baseExpression = leftExpression;
113
leftExpression = leftExpression.Left as BinaryOperatorExpression;
115
expressions.Add(baseExpression.Right);
116
expressions.Add(baseExpression.Left);
117
expressions.Reverse();