ObjectEqualsNull removed (superseded with DataFlowInspection)

This commit is contained in:
Tagir Valeev
2018-03-27 16:14:06 +07:00
parent 80391a6dea
commit 46f0bf7f3a
13 changed files with 70 additions and 155 deletions

View File

@@ -31,6 +31,7 @@ import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.*;
import com.intellij.util.containers.ContainerUtil;
import com.siyeh.ig.fixes.EqualsToEqualityFix;
import com.siyeh.ig.psiutils.*;
import one.util.streamex.IntStreamEx;
import one.util.streamex.StreamEx;
@@ -682,6 +683,7 @@ public class DataFlowInspectionBase extends AbstractBaseJavaLocalInspectionTool
fixes.add(new SetInspectionOptionFix(this, "DONT_REPORT_TRUE_ASSERT_STATEMENTS",
InspectionsBundle.message("inspection.data.flow.turn.off.true.asserts.quickfix"), true));
}
ContainerUtil.addIfNotNull(fixes, createReplaceWithNullCheckFix(psiAnchor, evaluatesToTrue));
String message = InspectionsBundle.message(isAtRHSOfBooleanAnd(psiAnchor) ?
"dataflow.message.constant.condition.when.reached" :
"dataflow.message.constant.condition", Boolean.toString(evaluatesToTrue));
@@ -689,6 +691,15 @@ public class DataFlowInspectionBase extends AbstractBaseJavaLocalInspectionTool
}
}
private static LocalQuickFix createReplaceWithNullCheckFix(PsiElement psiAnchor, boolean evaluatesToTrue) {
if (evaluatesToTrue) return null;
if (!(psiAnchor instanceof PsiMethodCallExpression) || !MethodCallUtils.isEqualsCall((PsiMethodCallExpression)psiAnchor)) return null;
PsiExpression arg = ArrayUtil.getFirstElement(((PsiMethodCallExpression)psiAnchor).getArgumentList().getExpressions());
if (!ExpressionUtils.isNullLiteral(arg)) return null;
PsiElement parent = PsiUtil.skipParenthesizedExprUp(psiAnchor.getParent());
return new EqualsToEqualityFix(parent instanceof PsiExpression && BoolUtils.isNegation((PsiExpression)parent));
}
protected LocalQuickFix[] createConditionalAssignmentFixes(boolean evaluatesToTrue, PsiAssignmentExpression parent, final boolean onTheFly) {
return LocalQuickFix.EMPTY_ARRAY;
}

View File

@@ -0,0 +1,8 @@
// "Replace 'equals()' with '=='" "true"
class Test {
void foo(Object o) {
if(o == null) {
}
}
}

View File

@@ -0,0 +1,8 @@
// "Replace '!equals()' with '!='" "true"
class Test {
void foo(Object o) {
if(o != null) {
}
}
}

View File

@@ -0,0 +1,8 @@
// "Replace 'equals()' with '=='" "true"
class Test {
void foo(Object o) {
if(o.e<caret>quals(null)) {
}
}
}

View File

@@ -0,0 +1,8 @@
// "Replace '!equals()' with '!='" "true"
class Test {
void foo(Object o) {
if(!o.e<caret>quals(null)) {
}
}
}

View File

@@ -0,0 +1,25 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.java.codeInsight.daemon.quickFix;
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.dataFlow.DataFlowInspection;
import org.jetbrains.annotations.NotNull;
public class ReplaceWithNullCheckFixTest extends LightQuickFixParameterizedTestCase {
@NotNull
@Override
protected LocalInspectionTool[] configureLocalInspectionTools() {
return new LocalInspectionTool[]{new DataFlowInspection()};
}
public void test() {
doAllTests();
}
@Override
protected String getBasePath() {
return "/codeInsight/daemonCodeAnalyzer/quickFix/replaceWithNullCheck";
}
}

View File

@@ -57,6 +57,7 @@ public class DataFlowInspectionTestSuite {
suite.addTestSuite(ReplaceWithTernaryOperatorTest.class);
suite.addTestSuite(ReplaceWithObjectsEqualsTest.class);
suite.addTestSuite(ReplaceWithOfNullableFixTest.class);
suite.addTestSuite(ReplaceWithNullCheckFixTest.class);
suite.addTestSuite(ReplaceFromOfNullableFixTest.class);
suite.addTestSuite(ReplaceWithTrivialLambdaFixTest.class);
suite.addTestSuite(UnwrapIfStatementFixTest.class);

View File

@@ -131,7 +131,6 @@ equality.to.equals.quickfix=Replace '==' with 'equals()'
inequality.to.not.equals.quickfix=Replace '!=' with '!equals()'
equality.to.safe.equals.quickfix=Replace '==' with null-safe 'equals()'
inequality.to.safe.not.equals.quickfix=Replace '!=' with null-safe '!equals()'
object.equals.null.problem.descriptor=<code>.equals(#ref)</code> is always ''false'' #loc
default.tostring.call.display.name=Call to default 'toString()'
default.tostring.call.problem.descriptor=Call to default 'toString()' on <code>#ref</code> #loc
octal.and.decimal.integers.in.same.array.display.name=Octal and decimal integers in same array
@@ -680,7 +679,6 @@ while.loop.spins.on.field.fix.family.name=Fix spin loop
while.loop.spins.on.field.fix.volatile=Make ''{0}'' volatile
while.loop.spins.on.field.fix.spinwait=Add Thread.onSpinWait()
while.loop.spins.on.field.fix.volatile.spinwait=Make ''{0}'' volatile and add Thread.onSpinWait()
object.equals.null.display.name=Object.equals(null)
test.method.is.public.void.no.arg.display.name=Malformed test method
if.statement.with.identical.branches.display.name='if' statement with common parts
multiple.return.points.per.method.display.name=Method with multiple return points

View File

@@ -1,87 +0,0 @@
/*
* Copyright 2003-2017 Dave Griffith, Bas Leijdekkers
*
* 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.siyeh.ig.bugs;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiExpressionStatement;
import com.intellij.psi.PsiMethodCallExpression;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.fixes.EqualsToEqualityFix;
import com.siyeh.ig.psiutils.BoolUtils;
import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ig.psiutils.MethodCallUtils;
import com.siyeh.ig.psiutils.ParenthesesUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ObjectEqualsNullInspection extends BaseInspection {
@Override
@NotNull
public String getDisplayName() {
return InspectionGadgetsBundle.message("object.equals.null.display.name");
}
@Override
@NotNull
public String buildErrorString(Object... infos) {
return InspectionGadgetsBundle.message("object.equals.null.problem.descriptor");
}
@Override
public boolean isEnabledByDefault() {
return true;
}
@Nullable
@Override
protected InspectionGadgetsFix buildFix(Object... infos) {
final Boolean negated = (Boolean)infos[0];
return negated == null ? null : new EqualsToEqualityFix(negated.booleanValue());
}
@Override
public BaseInspectionVisitor buildVisitor() {
return new ObjectEqualsNullVisitor();
}
private static class ObjectEqualsNullVisitor extends BaseInspectionVisitor {
@Override
public void visitMethodCallExpression(@NotNull PsiMethodCallExpression call) {
super.visitMethodCallExpression(call);
if (!MethodCallUtils.isEqualsCall(call)) {
return;
}
PsiExpression[] args = call.getArgumentList().getExpressions();
final PsiExpression argument = args.length > 0 ? args[0] : null;
if (!ExpressionUtils.isNullLiteral(argument)) {
return;
}
PsiElement parent = ParenthesesUtils.getParentSkipParentheses(call);
final boolean negated = parent instanceof PsiExpression && BoolUtils.isNegation((PsiExpression)parent);
if (negated) {
parent = parent.getParent();
}
final boolean quickFix = !(parent instanceof PsiExpressionStatement);
registerError(argument, quickFix ? Boolean.valueOf(negated) : null);
}
}
}

View File

@@ -41,7 +41,7 @@ public class EqualsToEqualityFix extends InspectionGadgetsFix {
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) {
final PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PsiMethodCallExpression.class);
final PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PsiMethodCallExpression.class, false);
EqualityCheck check = EqualityCheck.from(call);
if (check == null) return;
PsiExpression lhs = check.getLeft();

View File

@@ -319,9 +319,6 @@
<localInspection groupPath="Java" language="JAVA" shortName="ObjectEquality" bundle="com.siyeh.InspectionGadgetsBundle" key="object.comparison.display.name"
groupBundle="messages.InspectionsBundle" groupKey="group.names.probable.bugs" enabledByDefault="true" level="INFORMATION"
implementationClass="com.siyeh.ig.bugs.ObjectEqualityInspection"/>
<localInspection groupPath="Java" language="JAVA" shortName="ObjectEqualsNull" bundle="com.siyeh.InspectionGadgetsBundle" key="object.equals.null.display.name"
groupBundle="messages.InspectionsBundle" groupKey="group.names.probable.bugs" enabledByDefault="true" level="WARNING"
implementationClass="com.siyeh.ig.bugs.ObjectEqualsNullInspection"/>
<localInspection groupPath="Java" language="JAVA" shortName="ObjectToString" bundle="com.siyeh.InspectionGadgetsBundle" key="default.tostring.call.display.name"
groupBundle="messages.InspectionsBundle" groupKey="group.names.probable.bugs" enabledByDefault="false" level="WARNING"
implementationClass="com.siyeh.ig.bugs.ObjectToStringInspection"/>

View File

@@ -1,9 +0,0 @@
<html>
<body>
Reports <b>equals()</b> calls with a <b>null</b> argument.
Such calls will always return <b>false</b>
<!-- tooltip end -->
<p>
</body>
</html>

View File

@@ -1,53 +0,0 @@
/*
* Copyright 2000-2017 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.siyeh.ig.bugs;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.IGQuickFixesTestCase;
import org.jetbrains.annotations.Nullable;
/**
* @author Bas Leijdekkers
*/
public class ObjectEqualsNullInspectionTest extends IGQuickFixesTestCase {
public void testCastArgument() {
doMemberTest(InspectionGadgetsBundle.message("not.equals.to.equality.quickfix"),
"boolean m(String s) {" +
" return !s.equals((Integer)/**/(null));" +
"}",
"boolean m(String s) {" +
" return s != null;" +
"}");
}
public void testExpressionStatement() {
assertQuickfixNotAvailable(InspectionGadgetsBundle.message("not.equals.to.equality.quickfix"),
"class X {" +
" void m(String s) {" +
" !s.equals(/**/null);" +
" }" +
"}");
}
@Nullable
@Override
protected BaseInspection getInspection() {
return new ObjectEqualsNullInspection();
}
}