EqualityCheck extracted and used in various inspections, other fixes

EqualsCalledOnEnumValueFix replaced with EqualsToEqualityFix which does the same
This commit is contained in:
Tagir Valeev
2018-03-27 14:53:12 +07:00
parent 3d0dc4ebf4
commit f61a13bfcd
20 changed files with 305 additions and 202 deletions

View File

@@ -38,13 +38,11 @@ import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.rename.inplace.MemberInplaceRenamer;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.ThrowableRunnable;
import com.siyeh.ig.callMatcher.CallMatcher;
import com.siyeh.ig.psiutils.ClassUtils;
import com.siyeh.ig.psiutils.EqualityCheck;
import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ig.psiutils.MethodCallUtils;
import one.util.streamex.IntStreamEx;
import one.util.streamex.MoreCollectors;
import one.util.streamex.StreamEx;
@@ -61,10 +59,6 @@ import static com.intellij.util.ObjectUtils.tryCast;
* @author Tagir Valeev
*/
public class ExtractSetFromComparisonChainAction extends PsiElementBaseIntentionAction {
private static final CallMatcher OBJECT_EQUALS = CallMatcher.anyOf(
CallMatcher.staticCall("java.util.Objects", "equals").parameterCount(2),
CallMatcher.staticCall("com.google.common.base.Objects", "equal").parameterCount(2));
private static final String GUAVA_IMMUTABLE_SET = "com.google.common.collect.ImmutableSet";
private static final String INITIALIZER_FORMAT_GUAVA = GUAVA_IMMUTABLE_SET + ".of({0})";
private static final String INITIALIZER_FORMAT_JAVA2 =
@@ -346,18 +340,9 @@ public class ExtractSetFromComparisonChainAction extends PsiElementBaseIntention
static ExpressionToConstantComparison create(PsiExpression candidate) {
candidate = PsiUtil.skipParenthesizedExprDown(candidate);
PsiMethodCallExpression call = tryCast(candidate, PsiMethodCallExpression.class);
if (call != null) {
if (MethodCallUtils.isEqualsCall(call)) {
PsiExpression qualifier = call.getMethodExpression().getQualifierExpression();
PsiExpression argument = ArrayUtil.getFirstElement(call.getArgumentList().getExpressions());
return fromComparison(candidate, qualifier, argument);
}
if (OBJECT_EQUALS.test(call)) {
PsiExpression[] arguments = call.getArgumentList().getExpressions();
return fromComparison(candidate, arguments[0], arguments[1]);
}
return null;
EqualityCheck check = EqualityCheck.from(candidate);
if (check != null) {
return fromComparison(candidate, check.getLeft(), check.getRight());
}
PsiBinaryExpression binOp = tryCast(candidate, PsiBinaryExpression.class);
if (binOp != null && JavaTokenType.EQEQ.equals(binOp.getOperationTokenType())) {

View File

@@ -0,0 +1,22 @@
// "Fix all ''equals()' called on 'java.math.BigDecimal'' problems in file" "true"
import java.math.BigDecimal;
import java.util.Objects;
class BigDecimalEquals {
public void foo(BigDecimal qux)
{
final BigDecimal foo = new BigDecimal(3);
final BigDecimal bar = new BigDecimal(3);
foo.equals(bar);
if(foo.compareTo(bar) == 0)
{
return;
}
if(!(foo.compareTo(bar) == 0)) {
System.out.println("not equals");
}
if(qux != null && qux.compareTo(bar) == 0) {
System.out.println("equals");
}
}
}

View File

@@ -0,0 +1,22 @@
// "Fix all ''equals()' called on 'java.math.BigDecimal'' problems in file" "true"
import java.math.BigDecimal;
import java.util.Objects;
class BigDecimalEquals {
public void foo(BigDecimal qux)
{
final BigDecimal foo = new BigDecimal(3);
final BigDecimal bar = new BigDecimal(3);
foo.equals(bar);
if(foo.eq<caret>uals(bar))
{
return;
}
if(!Objects.equals(foo, bar)) {
System.out.println("not equals");
}
if(Objects.equals(qux, bar)) {
System.out.println("equals");
}
}
}

View File

@@ -3,7 +3,6 @@
*/
package com.siyeh.ig;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
@@ -16,7 +15,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class PsiReplacementUtil {
private static final Logger LOG = Logger.getInstance(PsiReplacementUtil.class);
/**
* Consider to use {@link #replaceExpression(PsiExpression, String, CommentTracker)} to preserve comments
@@ -32,7 +30,7 @@ public class PsiReplacementUtil {
}
/**
* @param commentTracker ensure to {@link CommentTracker#markUnchanged(PsiElement)} expressions used as getText in newExpressionText
* @param tracker ensure to {@link CommentTracker#markUnchanged(PsiElement)} expressions used as getText in newExpressionText
*/
public static void replaceExpression(@NotNull PsiExpression expression, @NotNull @NonNls String newExpressionText, CommentTracker tracker) {
final Project project = expression.getProject();
@@ -62,7 +60,7 @@ public class PsiReplacementUtil {
}
/**
* Consider to use {@link #replaceStatement(PsiExpression, String, CommentTracker)} to preserve comments
* Consider to use {@link #replaceStatement(PsiStatement, String, CommentTracker)} to preserve comments
*/
public static PsiElement replaceStatement(@NotNull PsiStatement statement, @NotNull @NonNls String newStatementText) {
final Project project = statement.getProject();

View File

@@ -8,13 +8,13 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiMethodCallExpression;
import com.intellij.psi.PsiReferenceExpression;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.PsiReplacementUtil;
import com.siyeh.ig.psiutils.BoolUtils;
import com.siyeh.ig.psiutils.CommentTracker;
import com.siyeh.ig.psiutils.EqualityCheck;
import com.siyeh.ig.psiutils.ParenthesesUtils;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
@@ -41,19 +41,11 @@ public class EqualsToEqualityFix extends InspectionGadgetsFix {
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) {
final PsiMethodCallExpression call = (PsiMethodCallExpression)descriptor.getPsiElement().getParent().getParent();
if (call == null) {
return;
}
final PsiReferenceExpression methodExpression = call.getMethodExpression();
final PsiExpression lhs = PsiUtil.deparenthesizeExpression(methodExpression.getQualifierExpression());
if (lhs == null) {
return;
}
final PsiExpression rhs = PsiUtil.deparenthesizeExpression(call.getArgumentList().getExpressions()[0]);
if (rhs == null) {
return;
}
final PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PsiMethodCallExpression.class);
EqualityCheck check = EqualityCheck.from(call);
if (check == null) return;
PsiExpression lhs = check.getLeft();
PsiExpression rhs = check.getRight();
final PsiElement parent = ParenthesesUtils.getParentSkipParentheses(call);
final CommentTracker commentTracker = new CommentTracker();
final String lhsText = commentTracker.text(lhs, ParenthesesUtils.EQUALITY_PRECEDENCE);

View File

@@ -16,16 +16,23 @@
package com.siyeh.ig.numeric;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.dataFlow.Nullness;
import com.intellij.codeInspection.dataFlow.NullnessUtil;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiExpressionStatement;
import com.intellij.psi.PsiMethodCallExpression;
import com.intellij.psi.util.PsiTreeUtil;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.PsiReplacementUtil;
import com.siyeh.ig.psiutils.CommentTracker;
import com.siyeh.ig.psiutils.EqualityCheck;
import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ig.psiutils.MethodCallUtils;
import com.siyeh.ig.psiutils.ParenthesesUtils;
import org.jetbrains.annotations.NotNull;
public class BigDecimalEqualsInspection extends BaseInspection {
@@ -56,21 +63,17 @@ public class BigDecimalEqualsInspection extends BaseInspection {
@Override
public void doFix(Project project, ProblemDescriptor descriptor) {
final PsiIdentifier name = (PsiIdentifier)descriptor.getPsiElement();
final PsiReferenceExpression expression = (PsiReferenceExpression)name.getParent();
assert expression != null;
final PsiMethodCallExpression call = (PsiMethodCallExpression)expression.getParent();
final PsiExpression qualifier = expression.getQualifierExpression();
if (qualifier == null) {
return;
}
PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PsiMethodCallExpression.class);
EqualityCheck check = EqualityCheck.from(call);
if (check == null) return;
CommentTracker commentTracker = new CommentTracker();
final String qualifierText = commentTracker.text(qualifier);
assert call != null;
final PsiExpressionList argumentList = call.getArgumentList();
final PsiExpression[] args = argumentList.getExpressions();
final String argText = commentTracker.text(args[0]);
PsiReplacementUtil.replaceExpression(call, qualifierText + ".compareTo(" + argText + ")==0", commentTracker);
final String qualifierText = commentTracker.text(check.getLeft(), ParenthesesUtils.METHOD_CALL_PRECEDENCE);
final String argText = commentTracker.text(check.getRight());
String replacement = qualifierText + ".compareTo(" + argText + ")==0";
if (!check.isLeftDereferenced() && NullnessUtil.getExpressionNullness(check.getLeft(), true) != Nullness.NOT_NULL) {
replacement = commentTracker.text(check.getLeft(), ParenthesesUtils.EQUALITY_PRECEDENCE) + "!=null && " + replacement;
}
PsiReplacementUtil.replaceExpression(call, replacement, commentTracker);
}
}
@@ -84,23 +87,12 @@ public class BigDecimalEqualsInspection extends BaseInspection {
@Override
public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
super.visitMethodCallExpression(expression);
if (!MethodCallUtils.isEqualsCall(expression)) {
return;
}
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
final PsiExpressionList argumentList = expression.getArgumentList();
final PsiExpression[] arguments = argumentList.getExpressions();
if (arguments.length == 0) {
return;
}
final PsiExpression arg = arguments[0];
if (!ExpressionUtils.hasType(arg, "java.math.BigDecimal")) {
return;
}
final PsiExpression qualifier = methodExpression.getQualifierExpression();
if (!ExpressionUtils.hasType(qualifier, "java.math.BigDecimal")) {
return;
}
EqualityCheck check = EqualityCheck.from(expression);
if (check == null) return;
PsiExpression left = check.getLeft();
PsiExpression right = check.getRight();
if (!ExpressionUtils.hasType(left, "java.math.BigDecimal")) return;
if (!ExpressionUtils.hasType(right, "java.math.BigDecimal")) return;
final PsiElement context = expression.getParent();
if (context instanceof PsiExpressionStatement) {
//cheesy, but necessary, because otherwise the quickfix will

View File

@@ -12,7 +12,7 @@ import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.fixes.EqualsToEqualityFix;
import com.siyeh.ig.psiutils.BoolUtils;
import com.siyeh.ig.psiutils.ClassUtils;
import com.siyeh.ig.psiutils.MethodCallUtils;
import com.siyeh.ig.psiutils.EqualityCheck;
import com.siyeh.ig.psiutils.ParenthesesUtils;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
@@ -55,24 +55,19 @@ public class ObjectEqualsCanBeEqualityInspection extends BaseInspection {
@Override
public void visitMethodCallExpression(PsiMethodCallExpression expression) {
super.visitMethodCallExpression(expression);
if (!MethodCallUtils.isEqualsCall(expression)) {
return;
}
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
final PsiExpression qualifier = methodExpression.getQualifierExpression();
if (qualifier == null) {
return;
}
final PsiExpression[] expressions = expression.getArgumentList().getExpressions();
if (expressions.length != 1) {
return;
}
final PsiExpression argument = expressions[0];
if (!TypeConversionUtil.isBinaryOperatorApplicable(JavaTokenType.EQEQ, qualifier, argument, false)) {
EqualityCheck check = EqualityCheck.from(expression);
if (check == null) return;
PsiExpression left = check.getLeft();
PsiExpression right = check.getRight();
if (!TypeConversionUtil.isBinaryOperatorApplicable(JavaTokenType.EQEQ, left, right, false)) {
// replacing with == or != will generate uncompilable code
return;
}
final PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(qualifier.getType());
final PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(left.getType());
if (aClass != null && aClass.isEnum()) {
// Enums are reported by separate EqualsCalledOnEnumConstantInspection
return;
}
final ProblemHighlightType highlightType;
if (ClassUtils.isFinalClassWithDefaultEquals(aClass)) {
highlightType = ProblemHighlightType.GENERIC_ERROR_OR_WARNING;
@@ -83,9 +78,9 @@ public class ObjectEqualsCanBeEqualityInspection extends BaseInspection {
}
final PsiElement parent = ParenthesesUtils.getParentSkipParentheses(expression);
final boolean negated = parent instanceof PsiExpression && BoolUtils.isNegation((PsiExpression)parent);
final PsiElement nameToken = methodExpression.getReferenceNameElement();
final PsiElement nameToken = expression.getMethodExpression().getReferenceNameElement();
assert nameToken != null;
registerError(nameToken, highlightType, Boolean.valueOf(negated));
registerError(nameToken, highlightType, negated);
}
}
}

View File

@@ -0,0 +1,69 @@
// 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.siyeh.ig.psiutils;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiMethodCallExpression;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ObjectUtils;
import com.siyeh.ig.callMatcher.CallMatcher;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Represents a model of PsiExpression which checks whether two expressions are equal (via Object.equals directly or indirectly).
*/
public class EqualityCheck {
private static final CallMatcher OBJECT_EQUALS = CallMatcher.anyOf(
CallMatcher.staticCall("java.util.Objects", "equals").parameterCount(2),
CallMatcher.staticCall("com.google.common.base.Objects", "equal").parameterCount(2));
private final @NotNull PsiExpression myLeft;
private final @NotNull PsiExpression myRight;
private final boolean myLeftDereferenced;
private EqualityCheck(@NotNull PsiExpression left, @NotNull PsiExpression right, boolean leftDereferenced) {
myLeft = left;
myRight = right;
myLeftDereferenced = leftDereferenced;
}
/**
* @param expression to create an {@link EqualityCheck} from
* @return an {@link EqualityCheck} which represents an equality check performed on given expression; null if equality check
* was not found in given expression.
*/
@Nullable
@Contract("null -> null")
public static EqualityCheck from(PsiExpression expression) {
PsiMethodCallExpression call = ObjectUtils.tryCast(PsiUtil.skipParenthesizedExprDown(expression), PsiMethodCallExpression.class);
if (call == null) {
return null;
}
if (MethodCallUtils.isEqualsCall(call)) {
PsiExpression left = call.getMethodExpression().getQualifierExpression();
PsiExpression right = ArrayUtil.getFirstElement(call.getArgumentList().getExpressions());
if (left == null || right == null) return null;
return new EqualityCheck(left, right, true);
}
if (OBJECT_EQUALS.test(call)) {
PsiExpression[] args = call.getArgumentList().getExpressions();
return new EqualityCheck(args[0], args[1], false);
}
return null;
}
@NotNull
public PsiExpression getLeft() {
return myLeft;
}
@NotNull
public PsiExpression getRight() {
return myRight;
}
public boolean isLeftDereferenced() {
return myLeftDereferenced;
}
}

View File

@@ -15,18 +15,16 @@
*/
package com.siyeh.ig.style;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.TypeConversionUtil;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.PsiReplacementUtil;
import com.siyeh.ig.psiutils.CommentTracker;
import com.siyeh.ig.psiutils.MethodCallUtils;
import com.siyeh.ig.fixes.EqualsToEqualityFix;
import com.siyeh.ig.psiutils.BoolUtils;
import com.siyeh.ig.psiutils.EqualityCheck;
import com.siyeh.ig.psiutils.ParenthesesUtils;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
@@ -49,64 +47,12 @@ public class EqualsCalledOnEnumConstantInspection extends BaseInspection {
@Override
protected InspectionGadgetsFix buildFix(Object... infos) {
final PsiElement element = (PsiElement)infos[0];
final boolean negated = (boolean)infos[1];
final PsiElement parent = element.getParent();
if (parent instanceof PsiExpressionStatement) {
return null;
}
return new EqualsCalledOnEnumValueFix();
}
private static class EqualsCalledOnEnumValueFix extends InspectionGadgetsFix {
@Override
@NotNull
public String getFamilyName() {
return InspectionGadgetsBundle.message("equals.called.on.enum.constant.quickfix");
}
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement();
final PsiElement parent = element.getParent();
if (parent == null) {
return;
}
final PsiElement grandParent = parent.getParent();
if (!(grandParent instanceof PsiMethodCallExpression)) {
return;
}
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)grandParent;
final PsiExpressionList argumentList = methodCallExpression.getArgumentList();
final PsiExpression[] arguments = argumentList.getExpressions();
if (arguments.length > 1) {
return;
}
final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
final PsiExpression qualifier = methodExpression.getQualifierExpression();
if (qualifier == null) {
return;
}
final StringBuilder newExpression = new StringBuilder();
final PsiElement greatGrandParent = grandParent.getParent();
final boolean not;
final PsiPrefixExpression prefixExpression;
if (greatGrandParent instanceof PsiPrefixExpression) {
prefixExpression = (PsiPrefixExpression)greatGrandParent;
final IElementType tokenType = prefixExpression.getOperationTokenType();
not = JavaTokenType.EXCL == tokenType;
}
else {
prefixExpression = null;
not = false;
}
CommentTracker commentTracker = new CommentTracker();
newExpression.append(commentTracker.text(qualifier));
newExpression.append(not ? "!=" : "==");
if (arguments.length == 1) {
newExpression.append(commentTracker.text(arguments[0]));
}
PsiReplacementUtil.replaceExpression(not ? prefixExpression : methodCallExpression, newExpression.toString(), commentTracker);
}
return new EqualsToEqualityFix(negated);
}
@Override
@@ -119,25 +65,21 @@ public class EqualsCalledOnEnumConstantInspection extends BaseInspection {
@Override
public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
super.visitMethodCallExpression(expression);
if (!MethodCallUtils.isEqualsCall(expression)) {
EqualityCheck check = EqualityCheck.from(expression);
if (check == null) return;
final PsiExpression left = check.getLeft();
if (!TypeUtils.expressionHasTypeOrSubtype(left, CommonClassNames.JAVA_LANG_ENUM)) return;
final PsiExpression right = check.getRight();
final PsiType comparedTypeErasure = TypeConversionUtil.erasure(left.getType());
final PsiType comparisonTypeErasure = TypeConversionUtil.erasure(right.getType());
if (comparedTypeErasure == null || comparisonTypeErasure == null ||
!TypeConversionUtil.areTypesConvertible(comparedTypeErasure, comparisonTypeErasure)) {
return;
}
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
final PsiExpression qualifier = methodExpression.getQualifierExpression();
if (!TypeUtils.expressionHasTypeOrSubtype(qualifier, CommonClassNames.JAVA_LANG_ENUM)) {
return;
}
final PsiExpressionList argumentList = expression.getArgumentList();
final PsiExpression[] arguments = argumentList.getExpressions();
if (arguments.length > 0) {
final PsiType comparedTypeErasure = TypeConversionUtil.erasure(qualifier.getType());
final PsiType comparisonTypeErasure = TypeConversionUtil.erasure(arguments[0].getType());
if (comparedTypeErasure == null || comparisonTypeErasure == null ||
!TypeConversionUtil.areTypesConvertible(comparedTypeErasure, comparisonTypeErasure)) {
return;
}
}
registerMethodCallError(expression, expression);
final PsiElement parent = ParenthesesUtils.getParentSkipParentheses(expression);
final boolean negated = parent instanceof PsiExpression && BoolUtils.isNegation((PsiExpression)parent);
registerMethodCallError(expression, expression, negated);
}
}
}

View File

@@ -26,8 +26,8 @@ import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.PsiReplacementUtil;
import com.siyeh.ig.psiutils.ComparisonUtils;
import com.siyeh.ig.psiutils.EqualityCheck;
import com.siyeh.ig.psiutils.ImportUtils;
import com.siyeh.ig.psiutils.MethodCallUtils;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -102,15 +102,7 @@ public abstract class SimplifiableAssertionInspection extends BaseInspection {
final PsiType type = lhs.getType();
return type != null && TypeConversionUtil.isPrimitiveAndNotNullOrWrapper(type);
}
else if (expression instanceof PsiMethodCallExpression) {
final PsiMethodCallExpression call = (PsiMethodCallExpression)expression;
if (!MethodCallUtils.isEqualsCall(call)) {
return false;
}
final PsiReferenceExpression methodExpression = call.getMethodExpression();
return methodExpression.getQualifierExpression() != null;
}
return false;
return EqualityCheck.from(expression) != null;
}
private static boolean isIdentityComparison(PsiExpression expression) {
@@ -235,13 +227,12 @@ public abstract class SimplifiableAssertionInspection extends BaseInspection {
lhs = binaryExpression.getLOperand();
rhs = binaryExpression.getROperand();
}
else if (position instanceof PsiMethodCallExpression) {
final PsiMethodCallExpression call = (PsiMethodCallExpression)position;
final PsiReferenceExpression equalityMethodExpression = call.getMethodExpression();
final PsiExpressionList equalityArgumentList = call.getArgumentList();
final PsiExpression[] equalityArgs = equalityArgumentList.getExpressions();
rhs = equalityArgs[0];
lhs = equalityMethodExpression.getQualifierExpression();
else {
EqualityCheck check = EqualityCheck.from(position);
if (check != null) {
lhs = check.getLeft();
rhs = check.getRight();
}
}
if (!(lhs instanceof PsiLiteralExpression) && rhs instanceof PsiLiteralExpression) {
final PsiExpression temp = lhs;

View File

@@ -0,0 +1,15 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.Objects;
class ObjectEqualsToEquals {
@Test
public void testObjectsEquals() {
assertEquals(getFoo(), getBar());
}
String getFoo() { return "foo"; }
String getBar() { return "foo"; }
}

View File

@@ -0,0 +1,14 @@
import static org.junit.Assert.assertTrue;
import java.util.Objects;
class ObjectEqualsToEquals {
@Test
public void testObjectsEquals() {
<caret>assertTrue(Objects.equals(getFoo(), getBar()));
}
String getFoo() { return "foo"; }
String getBar() { return "foo"; }
}

View File

@@ -1,16 +0,0 @@
package com.siyeh.igtest.bugs;
import java.math.BigDecimal;
public class BigDecimalEqualsInspection {
public void foo()
{
final BigDecimal foo = new BigDecimal(3);
final BigDecimal bar = new BigDecimal(3);
foo.equals(bar);
if(foo.equals(bar))
{
return;
}
}
}

View File

@@ -3,6 +3,7 @@ package com.siyeh.igtest.junit;
import junit.framework.TestCase;
import java.util.Collection;
import java.util.Objects;
public class SimplifiableJUnitAssertion extends TestCase{
public void test()
@@ -15,6 +16,10 @@ public class SimplifiableJUnitAssertion extends TestCase{
<warning descr="'assertTrue()' can be simplified to 'assertEquals()'">assertTrue</warning>(collection.size() == 2);
}
public void testObjectEquals() {
<warning descr="'assertTrue()' can be simplified to 'assertEquals()'">assertTrue</warning>(Objects.equals("foo", "bar"));
}
static class IDEABugTest extends TestCase {
public static enum Input { value1 }

View File

@@ -9,10 +9,16 @@ public class EqualsCalled {
void one() {
E.A.<warning descr="'equals()' called on Enum value">equals</warning>(E.C);
E.B.<warning descr="'equals()' called on Enum value">equals</warning>(new Object());
E.C.<warning descr="'equals()' called on Enum value">equals</warning><error descr="'equals(java.lang.Object)' in 'java.lang.Enum' cannot be applied to '()'">()</error>;
E.C.equals<error descr="'equals(java.lang.Object)' in 'java.lang.Enum' cannot be applied to '()'">()</error>;
final Object A = new Object();
A.equals(1);
}
void objectsEquals(E a, E b) {
if(java.util.Objects.<warning descr="'equals()' called on Enum value">equals</warning>(a, b)) {
System.out.println("equals");
}
}
}
class Main {
enum Suit {

View File

@@ -15,6 +15,8 @@
*/
package com.siyeh.ig.fixes.junit;
import com.intellij.testFramework.IdeaTestUtil;
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.IGQuickFixesTestCase;
import com.siyeh.ig.junit.SimplifiableJUnitAssertionInspection;
@@ -34,6 +36,13 @@ public class SimplifiableJUnitAssertionFixTest extends IGQuickFixesTestCase {
public void testTrueToEqualsJUnit5() { doTest(); }
public void testTrueToEqualsBetweenIncompatibleTypes() { doTest(); }
public void testFalseToNotEqualsJUnit4() { doTest(); }
public void testObjectEqualsToEquals() { doTest(); }
@Override
protected void tuneFixture(JavaModuleFixtureBuilder builder) throws Exception {
super.tuneFixture(builder);
builder.addJdk(IdeaTestUtil.getMockJdk18Path().getPath());
}
@Override
protected void setUp() throws Exception {
@@ -43,7 +52,7 @@ public class SimplifiableJUnitAssertionFixTest extends IGQuickFixesTestCase {
myDefaultHint = InspectionGadgetsBundle.message("simplify.junit.assertion.simplify.quickfix");
myFixture.addClass("package junit.framework;" +
"public abstract class TestCase extends Assert {" +
" /** @noinspection RedundantThrows*/ public abstract class TestCase extends Assert {" +
" protected void setUp() throws Exception {}" +
" protected void tearDown() throws Exception {}" +
"}");

View File

@@ -16,7 +16,9 @@
package com.siyeh.ig.junit;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.intellij.testFramework.LightProjectDescriptor;
import com.siyeh.ig.LightInspectionTestCase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@@ -32,6 +34,12 @@ public class SimplifiableJUnitAssertionInspectionTest extends LightInspectionTes
doTest();
}
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return JAVA_8;
}
@Nullable
@Override
protected InspectionProfileEntry getInspection() {
@@ -42,7 +50,7 @@ public class SimplifiableJUnitAssertionInspectionTest extends LightInspectionTes
protected String[] getEnvironmentClasses() {
return new String[] {
"package junit.framework;" +
"public abstract class TestCase extends Assert {" +
" /** @noinspection ALL*/ public abstract class TestCase extends Assert {" +
" protected void setUp() throws Exception {}" +
" protected void tearDown() throws Exception {}" +
" public static void assertTrue(boolean condition) {" +

View File

@@ -0,0 +1,30 @@
// 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.siyeh.ig.numeric;
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.testFramework.LightProjectDescriptor;
import org.jetbrains.annotations.NotNull;
import static com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase.JAVA_8;
public class BigDecimalEqualsInspectionFixTest extends LightQuickFixParameterizedTestCase {
@NotNull
@Override
protected LocalInspectionTool[] configureLocalInspectionTools() {
return new LocalInspectionTool[]{new BigDecimalEqualsInspection()};
}
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return JAVA_8;
}
@Override
protected String getBasePath() {
return "/codeInsight/daemonCodeAnalyzer/quickFix/bigDecimalEquals";
}
public void test() { doAllTests(); }
}

View File

@@ -16,7 +16,9 @@
package com.siyeh.ig.performance;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.intellij.testFramework.LightProjectDescriptor;
import com.siyeh.ig.LightInspectionTestCase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@@ -32,6 +34,14 @@ public class ObjectEqualsCanBeEqualityInspectionTest extends LightInspectionTest
"}");
}
public void testClassObjects() {
doTest("class X {" +
" boolean m(Class c1, Class c2) {" +
" return java.util.Objects./*'equals()' can be replaced with '=='*/equals/**/(c1, c2);" +
" }" +
"}");
}
public void testObject() {
doTest("class X {" +
" boolean m(Object o1, Object o2) {" +
@@ -72,6 +82,12 @@ public class ObjectEqualsCanBeEqualityInspectionTest extends LightInspectionTest
"}");
}
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return JAVA_8;
}
@Nullable
@Override
protected InspectionProfileEntry getInspection() {

View File

@@ -1,7 +1,9 @@
package com.siyeh.ig.style;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.intellij.testFramework.LightProjectDescriptor;
import com.siyeh.ig.LightInspectionTestCase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class EqualsCalledOnEnumConstantInspectionTest extends LightInspectionTestCase {
@@ -10,6 +12,12 @@ public class EqualsCalledOnEnumConstantInspectionTest extends LightInspectionTes
doTest();
}
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return JAVA_8;
}
@Nullable
@Override
protected InspectionProfileEntry getInspection() {