mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-05-06 05:10:22 +07:00
EqualityCheck extracted and used in various inspections, other fixes
EqualsCalledOnEnumValueFix replaced with EqualsToEqualityFix which does the same
This commit is contained in:
@@ -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())) {
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"; }
|
||||
}
|
||||
@@ -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"; }
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 }
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {}" +
|
||||
"}");
|
||||
|
||||
@@ -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) {" +
|
||||
|
||||
@@ -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(); }
|
||||
}
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user