From 3db80a01df7e8012065eadb809fdd64542e8e760 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 18 Sep 2017 15:39:38 +0200 Subject: [PATCH] IG: a != b and b != a and other commutative binary operations are equivalent --- .../siyeh/ig/psiutils/EquivalenceChecker.java | 9 ++++++--- .../siyeh/ig/psiutils/ParenthesesUtils.java | 18 ++++++++++++------ .../DuplicateCondition.java | 6 ++++++ 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/EquivalenceChecker.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/EquivalenceChecker.java index 5ceea468a41a..102287ad0aca 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/EquivalenceChecker.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/EquivalenceChecker.java @@ -899,14 +899,17 @@ public class EquivalenceChecker { final PsiExpression right2 = binaryExpression2.getROperand(); if (!tokenType1.equals(tokenType2)) { // process matches like "a < b" and "b > a" - DfaRelationValue.RelationType rel1 = DfaRelationValue.RelationType.fromElementType(tokenType1); - DfaRelationValue.RelationType rel2 = DfaRelationValue.RelationType.fromElementType(tokenType2); + final DfaRelationValue.RelationType rel1 = DfaRelationValue.RelationType.fromElementType(tokenType1); + final DfaRelationValue.RelationType rel2 = DfaRelationValue.RelationType.fromElementType(tokenType2); if(rel1 != null && rel2 != null && rel1.getFlipped() == rel2) { return expressionsAreEquivalent(new PsiExpression[] {left1, right1}, new PsiExpression[] {right2, left2}); } return EXACT_MISMATCH; } - return expressionsAreEquivalent(new PsiExpression[] {left1, right1}, new PsiExpression[] {left2, right2}); + final Match match = expressionsAreEquivalent(new PsiExpression[] {left1, right1}, new PsiExpression[] {left2, right2}); + return match == EXACT_MISMATCH && ParenthesesUtils.isCommutativeOperation(binaryExpression1) + ? expressionsAreEquivalent(new PsiExpression[]{left1, right1}, new PsiExpression[]{right2, left2}) + : match; } protected Match assignmentExpressionsMatch(@NotNull PsiAssignmentExpression assignmentExpression1, @NotNull PsiAssignmentExpression assignmentExpression2) { diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ParenthesesUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ParenthesesUtils.java index 47193e778894..a75163717166 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ParenthesesUtils.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ParenthesesUtils.java @@ -100,12 +100,18 @@ public class ParenthesesUtils { } public static boolean isCommutativeOperator(@NotNull IElementType token) { - return !(token.equals(JavaTokenType.MINUS) || - token.equals(JavaTokenType.DIV) || - token.equals(JavaTokenType.PERC) || - token.equals(JavaTokenType.LTLT) || - token.equals(JavaTokenType.GTGT) || - token.equals(JavaTokenType.GTGTGT)); + return token == JavaTokenType.PLUS || token == JavaTokenType.ASTERISK || + token == JavaTokenType.EQEQ || token == JavaTokenType.NE || + token == JavaTokenType.AND || token == JavaTokenType.OR || token == JavaTokenType.XOR; + } + + public static boolean isCommutativeOperation(PsiPolyadicExpression expression) { + final IElementType tokenType = expression.getOperationTokenType(); + if (!isCommutativeOperator(tokenType)) { + return false; + } + final PsiType type = expression.getType(); + return type != null && !type.equalsToText(CommonClassNames.JAVA_LANG_STRING); } public static boolean isAssociativeOperation(PsiPolyadicExpression expression) { diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/controlflow/duplicate_condition/DuplicateCondition.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/controlflow/duplicate_condition/DuplicateCondition.java index 05e6c05c7b46..4e45dca2b621 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/controlflow/duplicate_condition/DuplicateCondition.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/controlflow/duplicate_condition/DuplicateCondition.java @@ -33,6 +33,12 @@ public class DuplicateCondition { System.out.println("second"); return; } + if (x != y) { + return; + } + if (((y) != x)) { + return; + } } public void foo()