diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/ConvertEqualsMethodToStaticIntention.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/ConvertEqualsMethodToStaticIntention.java
deleted file mode 100644
index cc3f08e45a64..000000000000
--- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/ConvertEqualsMethodToStaticIntention.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright 2000-2015 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.codeInsight.intention.impl;
-
-import com.intellij.codeInsight.FileModificationService;
-import com.intellij.codeInsight.intention.BaseElementAtCaretIntentionAction;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.project.Project;
-import com.intellij.psi.*;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.util.IncorrectOperationException;
-import org.jetbrains.annotations.Nls;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * @author Dmitry Batkovich
- */
-public class ConvertEqualsMethodToStaticIntention extends BaseElementAtCaretIntentionAction {
- private static final Logger LOG = Logger.getInstance(ConvertEqualsMethodToStaticIntention.class);
- private static final String REPLACE_TEMPLATE = "java.util.Objects.equals(%s, %s)";
- public static final String TEXT = "Convert '.equals()' to 'java.util.Objects.equals()'";
-
- @Override
- public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
- if (!(element instanceof PsiIdentifier)) {
- return false;
- }
- if (!PsiUtil.isLanguageLevel7OrHigher(element)) {
- return false;
- }
- final PsiElement referenceExpression = element.getParent();
- if (!(referenceExpression instanceof PsiReferenceExpression)) {
- return false;
- }
- if (!"equals".equals(((PsiReferenceExpression)referenceExpression).getReferenceName())) {
- return false;
- }
- final PsiElement methodCallExpression = referenceExpression.getParent();
- if (!(methodCallExpression instanceof PsiMethodCallExpression)) {
- return false;
- }
- final int argumentsCount = ((PsiMethodCallExpression)methodCallExpression).getArgumentList().getExpressions().length;
- if (argumentsCount != 1) {
- return false;
- }
- final PsiMethod method = ((PsiMethodCallExpression)methodCallExpression).resolveMethod();
- if (method == null) {
- return false;
- }
- PsiClass javaLangObject = JavaPsiFacade.getInstance(project).findClass(CommonClassNames.JAVA_LANG_OBJECT, element.getResolveScope());
- if (javaLangObject == null) {
- return false;
- }
- if (javaLangObject.isEquivalentTo(method.getContainingClass())) {
- return true;
- }
- final PsiMethod[] superMethods = method.findSuperMethods(javaLangObject);
- return superMethods.length == 1;
- }
-
- @Override
- public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
- if (!FileModificationService.getInstance().preparePsiElementsForWrite(element)) {
- return;
- }
- final PsiElement parent = element.getParent().getParent();
- LOG.assertTrue(parent instanceof PsiMethodCallExpression);
- PsiMethodCallExpression methodCall = (PsiMethodCallExpression) parent;
- final PsiExpression qualifier = methodCall.getMethodExpression().getQualifierExpression();
- final String qualifierText = qualifier == null ? PsiKeyword.THIS : qualifier.getText();
- final PsiExpression parameter = methodCall.getArgumentList().getExpressions()[0];
- final String expressionText = String.format(REPLACE_TEMPLATE, qualifierText, parameter.getText());
- methodCall.replace(JavaPsiFacade.getElementFactory(project).createExpressionFromText(expressionText, null));
- }
-
- @Nls
- @NotNull
- @Override
- public String getFamilyName() {
- return TEXT;
- }
-
- @NotNull
- @Override
- public String getText() {
- return getFamilyName();
- }
-}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/intention/ConvertEqualsMethodToStaticTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/intention/ConvertEqualsMethodToStaticTest.java
deleted file mode 100644
index 5377fe688dc3..000000000000
--- a/java/java-tests/testSrc/com/intellij/codeInsight/intention/ConvertEqualsMethodToStaticTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2000-2015 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.codeInsight.intention;
-
-import com.intellij.JavaTestUtil;
-import com.intellij.codeInsight.intention.impl.ConvertCompareToToEqualsIntention;
-import com.intellij.codeInsight.intention.impl.ConvertEqualsMethodToStaticIntention;
-import com.intellij.openapi.roots.LanguageLevelProjectExtension;
-import com.intellij.pom.java.LanguageLevel;
-import com.intellij.testFramework.fixtures.CodeInsightTestUtil;
-import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
-
-/**
- * @author Dmitry Batkovich
- */
-public class ConvertEqualsMethodToStaticTest extends JavaCodeInsightFixtureTestCase {
- @Override
- protected String getTestDataPath() {
- return JavaTestUtil.getJavaTestDataPath() + "/codeInsight/convertEqualsMethodToStatic/";
- }
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_7);
- }
-
- public void testSimple() {
- doTest();
- }
-
- public void testComplexQualifierAndArgument() {
- doTest();
- }
-
- public void testNotAvailable() {
- doTestNotAvailable();
- }
-
- private void doTest() {
- final String name = getTestName(true);
- CodeInsightTestUtil.doIntentionTest(myFixture, ConvertEqualsMethodToStaticIntention.TEXT, name + ".java", name + "_after.java");
- }
-
- private void doTestNotAvailable() {
- myFixture.configureByFile(getTestName(true) + ".java");
- assertEmpty(myFixture.filterAvailableIntentions(ConvertEqualsMethodToStaticIntention.TEXT));
- }
-}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
index 8beed8aedac4..3c969aec8153 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
@@ -1312,7 +1312,7 @@
implementationClass="com.siyeh.ig.migration.BigDecimalLegacyMethodInspection"/>
#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
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 75b59118fee7..e95e536ceb23 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.ui.SingleCheckboxOptionsPanel;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
@@ -34,10 +35,19 @@ import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import javax.swing.*;
+
/**
* @author Bas Leijdekkers
*/
public class EqualsReplaceableByObjectsCallInspection extends BaseInspection {
+ public boolean checkNotNull;
+
+ @NotNull
+ @Override
+ public JComponent createOptionsPanel() {
+ return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message("equals.replaceable.by.objects.check.not.null.option"), this, "checkNotNull");
+ }
@Nls
@NotNull
@@ -86,10 +96,10 @@ public class EqualsReplaceableByObjectsCallInspection extends BaseInspection {
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement();
- if (!(element instanceof PsiBinaryExpression)) {
+ if (!(element instanceof PsiBinaryExpression || element instanceof PsiMethodCallExpression)) {
return;
}
- final PsiBinaryExpression expression = (PsiBinaryExpression)element;
+ final PsiExpression expression = (PsiExpression)element;
if (myEquals) {
PsiReplacementUtil.replaceExpressionAndShorten(expression, "java.util.Objects.equals(" + myName1 + "," + myName2 + ")");
}
@@ -109,41 +119,62 @@ public class EqualsReplaceableByObjectsCallInspection extends BaseInspection {
return new EqualsReplaceableByObjectsCallVisitor();
}
- private static class EqualsReplaceableByObjectsCallVisitor extends BaseInspectionVisitor {
+ private class EqualsReplaceableByObjectsCallVisitor extends BaseInspectionVisitor {
@Override
- public void visitBinaryExpression(PsiBinaryExpression expression) {
+ public void visitMethodCallExpression(PsiMethodCallExpression expression) {
+ final PsiElement maybeBinary = PsiTreeUtil.skipParentsOfType(expression, PsiParenthesizedExpression.class, PsiPrefixExpression.class);
+ if (maybeBinary instanceof PsiBinaryExpression) {
+ if (processNotNullCheck((PsiBinaryExpression)maybeBinary)) {
+ return;
+ }
+ }
+ if (!checkNotNull) {
+ final PsiVariable variable = ExpressionUtils.getVariable(expression.getMethodExpression().getQualifierExpression());
+ if (variable == null) {
+ return;
+ }
+ final PsiVariable otherVariable = getArgumentFromEqualsCallOn(expression, variable);
+ if (otherVariable == null) {
+ return;
+ }
+ registerError(expression, variable.getName(), otherVariable.getName(), true);
+ }
+ }
+
+ private boolean processNotNullCheck(PsiBinaryExpression expression) {
final IElementType tokenType = expression.getOperationTokenType();
if (JavaTokenType.ANDAND.equals(tokenType)) {
final PsiVariable variable = ExpressionUtils.getVariableFromNullComparison(expression.getLOperand(), false);
if (variable == null) {
- return;
+ return false;
}
final PsiVariable otherVariable = getArgumentFromEqualsCallOn(expression.getROperand(), variable);
if (otherVariable == null) {
- return;
+ return false;
}
checkEqualityBefore(expression, true, variable, otherVariable);
}
else if (JavaTokenType.OROR.equals(tokenType)) {
final PsiVariable variable = ExpressionUtils.getVariableFromNullComparison(expression.getLOperand(), true);
if (variable == null) {
- return;
+ return false;
}
final PsiExpression rhs = ParenthesesUtils.stripParentheses(expression.getROperand());
if (!(rhs instanceof PsiPrefixExpression)) {
- return;
+ return false;
}
final PsiPrefixExpression prefixExpression = (PsiPrefixExpression)rhs;
if (!JavaTokenType.EXCL.equals(prefixExpression.getOperationTokenType())) {
- return;
+ return false;
}
final PsiVariable otherVariable = getArgumentFromEqualsCallOn(prefixExpression.getOperand(), variable);
if (otherVariable == null) {
- return;
+ return false;
}
checkEqualityBefore(expression, false, variable, otherVariable);
}
+ return true;
}
private void checkEqualityBefore(PsiExpression expression, boolean equals, PsiVariable variable1, PsiVariable variable2) {
@@ -161,7 +192,7 @@ public class EqualsReplaceableByObjectsCallInspection extends BaseInspection {
registerError(expression, variable1.getName(), variable2.getName(), Boolean.valueOf(equals));
}
- private static boolean isEquality(PsiExpression expression, boolean equals, PsiVariable variable1, PsiVariable variable2) {
+ private boolean isEquality(PsiExpression expression, boolean equals, PsiVariable variable1, PsiVariable variable2) {
expression = ParenthesesUtils.stripParentheses(expression);
if (!(expression instanceof PsiBinaryExpression)) {
return false;
@@ -183,7 +214,7 @@ public class EqualsReplaceableByObjectsCallInspection extends BaseInspection {
(VariableAccessUtils.evaluatesToVariable(lhs, variable2) && VariableAccessUtils.evaluatesToVariable(rhs, variable1));
}
- private static PsiVariable getArgumentFromEqualsCallOn(PsiExpression expression, @NotNull PsiVariable variable) {
+ private PsiVariable getArgumentFromEqualsCallOn(PsiExpression expression, PsiVariable variable) {
expression = ParenthesesUtils.stripParentheses(expression);
if (!(expression instanceof PsiMethodCallExpression)) {
return null;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpressionUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpressionUtils.java
index 7d234614067f..c72f1991f3b9 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpressionUtils.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpressionUtils.java
@@ -635,7 +635,7 @@ public class ExpressionUtils {
return null;
}
- public static PsiVariable getVariable(PsiExpression expression) {
+ public static PsiVariable getVariable(@Nullable PsiExpression expression) {
expression = ParenthesesUtils.stripParentheses(expression);
if (!(expression instanceof PsiReferenceExpression)) {
return null;
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 fa187d730513..49b9afbef78f 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
@@ -4,4 +4,8 @@ class EqualsReplaceableByObjectsCall {
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);
+ }
}
\ 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
new file mode 100644
index 000000000000..5d4f1fdbe924
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/equals_replaceable_by_objects_call/EqualsReplaceableByObjectsCallCheckNull.java
@@ -0,0 +1,11 @@
+class EqualsReplaceableByObjectsCall {
+ void yyy(Object a, Object 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);
+ }
+}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/EqualsReplaceableByObjectsCallInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/EqualsReplaceableByObjectsCallInspectionTest.java
index 38e5b432ddbc..27d6202dbcab 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/EqualsReplaceableByObjectsCallInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/EqualsReplaceableByObjectsCallInspectionTest.java
@@ -15,23 +15,43 @@
*/
package com.siyeh.ig.migration;
-import com.intellij.codeInspection.InspectionProfileEntry;
+import com.intellij.codeHighlighting.HighlightDisplayLevel;
+import com.intellij.codeInsight.daemon.HighlightDisplayKey;
+import com.intellij.codeInspection.LocalInspectionTool;
+import com.intellij.codeInspection.ex.InspectionProfileImpl;
+import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.siyeh.ig.LightInspectionTestCase;
-import junit.framework.TestCase;
import org.jetbrains.annotations.Nullable;
/**
* @author Bas Leijdekkers
*/
public class EqualsReplaceableByObjectsCallInspectionTest extends LightInspectionTestCase {
+ private EqualsReplaceableByObjectsCallInspection myInspection = new EqualsReplaceableByObjectsCallInspection();
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ final InspectionProfileImpl profile = (InspectionProfileImpl)InspectionProjectProfileManager.getInstance(getProject()).getInspectionProfile();
+ profile.setErrorLevel(HighlightDisplayKey.find("EqualsReplaceableByObjectsCall"), HighlightDisplayLevel.WARNING, getProject());
+ }
public void testEqualsReplaceableByObjectsCall() {
doTest();
}
+ public void testEqualsReplaceableByObjectsCallCheckNull() {
+ try {
+ myInspection.checkNotNull = true;
+ doTest();
+ } finally {
+ myInspection.checkNotNull = false;
+ }
+ }
+
@Nullable
@Override
- protected InspectionProfileEntry getInspection() {
- return new EqualsReplaceableByObjectsCallInspection();
+ protected LocalInspectionTool getInspection() {
+ return myInspection;
}
}
\ No newline at end of file
diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml
index fb6a351caaf8..ad80bf08d27d 100644
--- a/resources/src/META-INF/IdeaPlugin.xml
+++ b/resources/src/META-INF/IdeaPlugin.xml
@@ -882,10 +882,6 @@
com.intellij.codeInsight.intention.impl.ConvertCompareToToEqualsIntention
Java/Control Flow
-
- com.intellij.codeInsight.intention.impl.ConvertEqualsMethodToStaticIntention
- Java/Control Flow
-
com.intellij.codeInsight.intention.impl.CreateFieldFromParameterAction