diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
index f5f2b2bd43f3..d4df74581350 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
@@ -2091,7 +2091,7 @@ dangling.javadoc.delete.quickfix=Remove dangling comment
equals.replaceable.by.objects.call.display.name='equals()' expression replaceable by 'Objects.equals()' expression
equals.replaceable.by.objects.call.problem.descriptor=#ref replaceable by 'Objects.equals()' expression #loc
equals.replaceable.by.objects.call.quickfix=Replace with 'Objects.equals()' expression
-equals.replaceable.by.objects.check.not.null.option=Report only null safe 'equals' calls
+equals.replaceable.by.objects.check.not.null.option=Highlight expressions like 'a != null \\&\\& a.equals(b)'
array.objects.equals.display.name='Objects.equals()' called on arrays
array.objects.equals.problem.descriptor=Objects.#ref() on arrays should probably be 'Arrays.equals()' #loc
array.objects.deep.equals.problem.descriptor=Objects.#ref() on arrays should probably be 'Arrays.deepEquals()' #loc
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/EqualsReplaceableByObjectsCallInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/EqualsReplaceableByObjectsCallInspection.java
index 82fb4efc12ab..81f292d1e124 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/EqualsReplaceableByObjectsCallInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/EqualsReplaceableByObjectsCallInspection.java
@@ -16,6 +16,7 @@
package com.siyeh.ig.migration;
import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
@@ -42,7 +43,7 @@ import javax.swing.*;
* @author Bas Leijdekkers
*/
public class EqualsReplaceableByObjectsCallInspection extends BaseInspection {
- public boolean checkNotNull = true;
+ public boolean checkNotNull;
private static final EquivalenceChecker EQUIVALENCE = new NoSideEffectExpressionEquivalenceChecker();
@@ -141,16 +142,14 @@ public class EqualsReplaceableByObjectsCallInspection extends BaseInspection {
return;
}
}
- if (!checkNotNull) {
- if (qualifierExpression == null) {
- return;
- }
- final PsiExpression argumentExpression = getArgumentExpression(expression);
- if (argumentExpression == null) {
- return;
- }
- registerError(expression, qualifierExpression.getText(), argumentExpression.getText(), true);
+ if (qualifierExpression == null) {
+ return;
}
+ final PsiExpression argumentExpression = getArgumentExpression(expression);
+ if (argumentExpression == null) {
+ return;
+ }
+ registerError(expression, ProblemHighlightType.INFORMATION, qualifierExpression.getText(), argumentExpression.getText(), true);
}
private boolean processNotNullCheck(PsiBinaryExpression expression) {
@@ -219,7 +218,10 @@ public class EqualsReplaceableByObjectsCallInspection extends BaseInspection {
final PsiExpression argumentExpression = getArgumentExpression(methodCallExpression);
if (argumentExpression != null) {
final PsiExpression expressionToReplace = checkEqualityBefore(expression, equal, qualifierExpression, argumentExpression);
- registerError(expressionToReplace, nullCheckedExpression.getText(), argumentExpression.getText(), Boolean.valueOf(equal));
+ ProblemHighlightType highlightType = checkNotNull || expression != expressionToReplace ?
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING : ProblemHighlightType.INFORMATION;
+ registerError(expressionToReplace, highlightType,
+ nullCheckedExpression.getText(), argumentExpression.getText(), Boolean.valueOf(equal));
return true;
}
}
diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsReplaceableByObjectsCall.html b/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsReplaceableByObjectsCall.html
index 80c33db1a5d0..7568b89561de 100644
--- a/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsReplaceableByObjectsCall.html
+++ b/plugins/InspectionGadgets/src/inspectionDescriptions/EqualsReplaceableByObjectsCall.html
@@ -2,12 +2,16 @@
Reports expressions that can be replaced with a call to java.util.Objects.equals(), which is available since JDK 1.7.
For example:
-a != null && a.equals(b)
+
+ a == b || a != null && a.equals(b)
+
+ a != null ? a.equals(b) : b == null
+
- If a.equals(b) isn't preceded with a != null, replacing it with Objects.equals(a, b)
- still makes sense, but slightly changes the semantics. For the cases where only equivalent replacement is needed, there's
- the check box Report only null safe 'equals' calls to enforce that.
+ Replacing expressions like a != null && a.equals(b)
with
+ Objects.equals(a, b)
slightly changes the semantics,
+ but if that's what you need there's a check box for that in the inspection settings.
This inspection only applies to projects and modules configured to use a language level of 7 or higher.
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/equals_replaceable_by_objects_call/EqualsReplaceableByObjectsCall.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/equals_replaceable_by_objects_call/EqualsReplaceableByObjectsCall.java
index c333c3672bde..7b7125ecee41 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/equals_replaceable_by_objects_call/EqualsReplaceableByObjectsCall.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/equals_replaceable_by_objects_call/EqualsReplaceableByObjectsCall.java
@@ -1,41 +1,41 @@
class EqualsReplaceableByObjectsCall {
void yyy(Object a, Object b) {
- boolean c = (a != null) && a.equals(b);
+ boolean c = (a != null) && a.equals(b);
boolean d = (a != b) && (a == null || !a.equals(b));
boolean e = ((a) == (b)) || ((a) != (null) && (a).equals((b)));
}
void ignoreNullityCheck(Object a, Object b) {
- boolean c = a.equals(b);
+ boolean c = a.equals(b);
}
void bar(T x, T y, T z) {
- boolean b = !x.s.equals(y.s);
- boolean c = x.s != null && x.s.equals(y.s);
- boolean d = y.s != null && x.s.equals(y.s);
- boolean e = x.s == null || !x.s.equals(y.s);
+ boolean b = !x.s.equals(y.s);
+ boolean c = x.s != null && x.s.equals(y.s);
+ boolean d = y.s != null && x.s.equals(y.s);
+ boolean e = x.s == null || !x.s.equals(y.s);
boolean f = x.s != y.s && (x.s == null || !x.s.equals(y.s));
- boolean g = x.s != y.s || (x.s == null || !x.s.equals(y.s));
- boolean h = x.s != y.s && (z.s == null || !x.s.equals(y.s));
+ boolean g = x.s != y.s || (x.s == null || !x.s.equals(y.s));
+ boolean h = x.s != y.s && (z.s == null || !x.s.equals(y.s));
}
void baz(T x, T y) {
- boolean b = x.copy().equals(y.copy());
- boolean c = x != null && x.equals(y.copy());
- boolean d = x == null || !x.equals(y.copy());
- boolean e = x.copy() != null && x.copy().equals(y);
- boolean f = x.copy() == null || !x.copy().equals(y);
- boolean g = x.copy().s != null && x.copy().s.equals(y.s);
- boolean h = x.copy().s == null || !x.copy().s.equals(y.s);
- boolean i = x.s == y.copy().s || (x).s != null && (x.s).equals(y.copy().s);
- boolean j = x.s != y.copy().s && ((x).s == null || !(x.s).equals(y.copy().s));
+ boolean b = x.copy().equals(y.copy());
+ boolean c = x != null && x.equals(y.copy());
+ boolean d = x == null || !x.equals(y.copy());
+ boolean e = x.copy() != null && x.copy().equals(y);
+ boolean f = x.copy() == null || !x.copy().equals(y);
+ boolean g = x.copy().s != null && x.copy().s.equals(y.s);
+ boolean h = x.copy().s == null || !x.copy().s.equals(y.s);
+ boolean i = x.s == y.copy().s || (x).s != null && (x.s).equals(y.copy().s);
+ boolean j = x.s != y.copy().s && ((x).s == null || !(x.s).equals(y.copy().s));
}
void arr(T[] a, T[] b, int i) {
- boolean c = a[i] != null && a[i].equals(b[i]);
+ boolean c = a[i] != null && a[i].equals(b[i]);
boolean d = a[i] == null ? b[i] == null : a[i].equals(b[i]);
- boolean e = a[i++] != null && a[i++].equals(b[i++]);
- boolean f = a[--i] != null && a[--i].equals(b[--i]);
+ boolean e = a[i++] != null && a[i++].equals(b[i++]);
+ boolean f = a[--i] != null && a[--i].equals(b[--i]);
}
static class T {
@@ -64,10 +64,10 @@ class EqualsReplaceableByObjectsCall {
}
}
static boolean ab1(String s) {
- return A.b.equals(s);
+ return A.b.equals(s);
}
static boolean ab2(String s) {
- return A.b != null && A.b.equals(s);
+ return A.b != null && A.b.equals(s);
}
static boolean ab3(String s) {
return A.b == s || A.b != null && A.b.equals(s);
@@ -101,7 +101,7 @@ class EqualsReplaceableByObjectsCall {
static final String NULL_CONSTANT = null;
boolean nullConstant(Object o) {
- return NULL_CONSTANT.equals(o);
+ return NULL_CONSTANT.equals(o);
}
static final Object NEW_CONSTANT = new Object();
@@ -139,28 +139,28 @@ class EqualsReplaceableByObjectsCall {
return (s != null) ? (!s.equals(t.s)) : !(t.s == null);
}
boolean notMatches1(Ternary t) {
- return s == null ? t.s != null : s.equals(t.s);
+ return s == null ? t.s != null : s.equals(t.s);
}
boolean notMatches2(Ternary t) {
- return s != null ? t.s != null : s.equals(t.s);
+ return s != null ? t.s != null : s.equals(t.s);
}
boolean notMatches3(Ternary t) {
- return ((s != null) ? !(s.equals(t.s)) : (t.s == null));
+ return ((s != null) ? !(s.equals(t.s)) : (t.s == null));
}
boolean notMatches4(Ternary t) {
- return s == null ? t.s == null : !s.equals(t.s);
+ return s == null ? t.s == null : !s.equals(t.s);
}
boolean notMatches5(Ternary t) {
- return s != null ? s.equals(t.s) : t.s != null;
+ return s != null ? s.equals(t.s) : t.s != null;
}
boolean notMatches6(Ternary t) {
- return s == null ? !s.equals(t.s) : t.s != null;
+ return s == null ? !s.equals(t.s) : t.s != null;
}
boolean notMatches7(Ternary t) {
- return s == null ? t.s == null : t.s.equals(s);
+ return s == null ? t.s == null : t.s.equals(s);
}
boolean notMatches8(Ternary t) {
- return (s != null) ? (t.s.equals(s)) : (t.s == null);
+ return (s != null) ? (t.s.equals(s)) : (t.s == null);
}
}
}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/equals_replaceable_by_objects_call/EqualsReplaceableByObjectsCallCheckNull.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/equals_replaceable_by_objects_call/EqualsReplaceableByObjectsCallCheckNull.java
index 9dc195c0fc67..83ed055c8b1e 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/equals_replaceable_by_objects_call/EqualsReplaceableByObjectsCallCheckNull.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/equals_replaceable_by_objects_call/EqualsReplaceableByObjectsCallCheckNull.java
@@ -6,27 +6,27 @@ class EqualsReplaceableByObjectsCall {
}
void ignoreNullityCheck(Object a, Object b) {
- boolean c = a.equals(b);
+ boolean c = a.equals(b);
}
void bar(T x, T y, T z) {
- boolean b = !x.s.equals(y.s);
+ boolean b = !x.s.equals(y.s);
boolean c = x.s != null && x.s.equals(y.s);
- boolean d = y.s != null && x.s.equals(y.s);
+ boolean d = y.s != null && x.s.equals(y.s);
boolean e = x.s == null || !x.s.equals(y.s);
boolean f = x.s != y.s && (x.s == null || !x.s.equals(y.s));
boolean g = x.s != y.s || (x.s == null || !x.s.equals(y.s));
- boolean h = x.s != y.s && (z.s == null || !x.s.equals(y.s));
+ boolean h = x.s != y.s && (z.s == null || !x.s.equals(y.s));
}
void baz(T x, T y) {
- boolean b = x.copy().equals(y.copy());
+ boolean b = x.copy().equals(y.copy());
boolean c = x != null && x.equals(y.copy());
boolean d = x == null || !x.equals(y.copy());
- boolean e = x.copy() != null && x.copy().equals(y);
- boolean f = x.copy() == null || !x.copy().equals(y);
- boolean g = x.copy().s != null && x.copy().s.equals(y.s);
- boolean h = x.copy().s == null || !x.copy().s.equals(y.s);
+ boolean e = x.copy() != null && x.copy().equals(y);
+ boolean f = x.copy() == null || !x.copy().equals(y);
+ boolean g = x.copy().s != null && x.copy().s.equals(y.s);
+ boolean h = x.copy().s == null || !x.copy().s.equals(y.s);
boolean i = x.s == y.copy().s || (x).s != null && (x.s).equals(y.copy().s);
boolean j = x.s != y.copy().s && ((x).s == null || !(x.s).equals(y.copy().s));
}
@@ -34,8 +34,8 @@ class EqualsReplaceableByObjectsCall {
void arr(T[] a, T[] b, int i) {
boolean c = a[i] != null && a[i].equals(b[i]);
boolean d = a[i] == null ? b[i] == null : a[i].equals(b[i]);
- boolean e = a[i++] != null && a[i++].equals(b[i++]);
- boolean f = a[--i] != null && a[--i].equals(b[--i]);
+ boolean e = a[i++] != null && a[i++].equals(b[i++]);
+ boolean f = a[--i] != null && a[--i].equals(b[--i]);
}
static class T {
@@ -64,7 +64,7 @@ class EqualsReplaceableByObjectsCall {
}
}
static boolean ab1(String s) {
- return A.b.equals(s);
+ return A.b.equals(s);
}
static boolean ab2(String s) {
return A.b != null && A.b.equals(s);
@@ -91,28 +91,28 @@ class EqualsReplaceableByObjectsCall {
return (s != null) ? (!s.equals(t.s)) : !(t.s == null);
}
boolean notMatches1(Ternary t) {
- return s == null ? t.s != null : s.equals(t.s);
+ return s == null ? t.s != null : s.equals(t.s);
}
boolean notMatches2(Ternary t) {
- return s != null ? t.s != null : s.equals(t.s);
+ return s != null ? t.s != null : s.equals(t.s);
}
boolean notMatches3(Ternary t) {
- return ((s != null) ? !(s.equals(t.s)) : (t.s == null));
+ return ((s != null) ? !(s.equals(t.s)) : (t.s == null));
}
boolean notMatches4(Ternary t) {
- return s == null ? t.s == null : !s.equals(t.s);
+ return s == null ? t.s == null : !s.equals(t.s);
}
boolean notMatches5(Ternary t) {
- return s != null ? s.equals(t.s) : t.s != null;
+ return s != null ? s.equals(t.s) : t.s != null;
}
boolean notMatches6(Ternary t) {
- return s == null ? !s.equals(t.s) : t.s != null;
+ return s == null ? !s.equals(t.s) : t.s != null;
}
boolean notMatches7(Ternary t) {
- return s == null ? t.s == null : t.s.equals(s);
+ return s == null ? t.s == null : t.s.equals(s);
}
boolean notMatches8(Ternary t) {
- return (s != null) ? (t.s.equals(s)) : (t.s == null);
+ return (s != null) ? (t.s.equals(s)) : (t.s == null);
}
}
}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/migration/EqualsReplaceableByObjectsCallFixTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/migration/EqualsReplaceableByObjectsCallFixTest.java
index 3354a856ff7e..79cc1288fa46 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/migration/EqualsReplaceableByObjectsCallFixTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/migration/EqualsReplaceableByObjectsCallFixTest.java
@@ -27,16 +27,14 @@ import com.siyeh.ig.migration.EqualsReplaceableByObjectsCallInspection;
*/
public class EqualsReplaceableByObjectsCallFixTest extends IGQuickFixesTestCase {
- private EqualsReplaceableByObjectsCallInspection myInspection;
+ public void testSimpleEquals() { doTest(); }
+ public void testSimpleNotEquals() { doTest(); }
- public void testSimpleEquals() { doTestNoNullCheck(); }
- public void testSimpleNotEquals() { doTestNoNullCheck(); }
-
- public void testQualifiedArgument() { doTestNoNullCheck(); }
+ public void testQualifiedArgument() { doTest(); }
public void testQualifiedReciever() { doTest(); }
- public void testExpressionReciever() { doTestNoNullCheck(); }
- public void testExpressionArgument() { doTestNoNullCheck(); }
+ public void testExpressionReciever() { doTest(); }
+ public void testExpressionArgument() { doTest(); }
public void testExpressionArgument2() { doTest(); }
public void testLongEquals() { doTest(); }
@@ -44,8 +42,8 @@ public class EqualsReplaceableByObjectsCallFixTest extends IGQuickFixesTestCase
public void testShortEquals() { doTest(); }
public void testShortNotEquals() { doTest(); }
- public void testSuperEquals() { doTestNoNullCheck(); }
- public void testThisEquals() { doTestNoNullCheck(); }
+ public void testSuperEquals() { doTest(); }
+ public void testThisEquals() { doTest(); }
public void testQualifiedThisNotEqual() { doTest(); }
public void testQualifiedSuperEqual() { doTest(); }
@@ -68,14 +66,8 @@ public class EqualsReplaceableByObjectsCallFixTest extends IGQuickFixesTestCase
@Override
public void setUp() throws Exception {
super.setUp();
- myInspection = new EqualsReplaceableByObjectsCallInspection();
- myFixture.enableInspections(myInspection);
+ myFixture.enableInspections(new EqualsReplaceableByObjectsCallInspection());
myRelativePath = "migration/equals_replaceable_by_objects_call";
myDefaultHint = InspectionGadgetsBundle.message("equals.replaceable.by.objects.call.quickfix");
}
-
- private void doTestNoNullCheck() {
- myInspection.checkNotNull = false;
- doTest();
- }
}
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/EqualsReplaceableByObjectsCallInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/EqualsReplaceableByObjectsCallInspectionTest.java
index b13d9ebc1bae..14d386975fc0 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/EqualsReplaceableByObjectsCallInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/EqualsReplaceableByObjectsCallInspectionTest.java
@@ -54,7 +54,9 @@ public class EqualsReplaceableByObjectsCallInspectionTest extends LightInspectio
boolean oldNotNull = myInspection.checkNotNull;
try {
myInspection.checkNotNull = checkNotNull;
- doTest();
+
+ myFixture.configureByFile(getTestName(false) + ".java");
+ myFixture.testHighlighting(true, true, false);
}
finally {
myInspection.checkNotNull = oldNotNull;