mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Java inspection: Support qualified variable names and allow expression as argument of equal() in EqualsReplaceableByObjectsCallInspection (IDEA-161076)
This commit is contained in:
+113
-75
@@ -30,7 +30,7 @@ import com.siyeh.ig.InspectionGadgetsFix;
|
||||
import com.siyeh.ig.PsiReplacementUtil;
|
||||
import com.siyeh.ig.psiutils.ExpressionUtils;
|
||||
import com.siyeh.ig.psiutils.ParenthesesUtils;
|
||||
import com.siyeh.ig.psiutils.VariableAccessUtils;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -100,12 +100,8 @@ public class EqualsReplaceableByObjectsCallInspection extends BaseInspection {
|
||||
return;
|
||||
}
|
||||
final PsiExpression expression = (PsiExpression)element;
|
||||
if (myEquals) {
|
||||
PsiReplacementUtil.replaceExpressionAndShorten(expression, "java.util.Objects.equals(" + myName1 + "," + myName2 + ")");
|
||||
}
|
||||
else {
|
||||
PsiReplacementUtil.replaceExpressionAndShorten(expression, "!java.util.Objects.equals(" + myName1 + "," + myName2 + ")");
|
||||
}
|
||||
final String expressionText = "java.util.Objects.equals(" + myName1 + "," + myName2 + ")";
|
||||
PsiReplacementUtil.replaceExpressionAndShorten(expression, myEquals ? expressionText : "!" + expressionText);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,6 +119,10 @@ public class EqualsReplaceableByObjectsCallInspection extends BaseInspection {
|
||||
|
||||
@Override
|
||||
public void visitMethodCallExpression(PsiMethodCallExpression expression) {
|
||||
final String methodName = expression.getMethodExpression().getReferenceName();
|
||||
if (!HardcodedMethodConstants.EQUALS.equals(methodName)) {
|
||||
return;
|
||||
}
|
||||
final PsiElement maybeBinary = PsiTreeUtil.skipParentsOfType(expression, PsiParenthesizedExpression.class, PsiPrefixExpression.class);
|
||||
if (maybeBinary instanceof PsiBinaryExpression) {
|
||||
if (processNotNullCheck((PsiBinaryExpression)maybeBinary)) {
|
||||
@@ -130,69 +130,95 @@ public class EqualsReplaceableByObjectsCallInspection extends BaseInspection {
|
||||
}
|
||||
}
|
||||
if (!checkNotNull) {
|
||||
final PsiVariable variable = ExpressionUtils.getVariable(expression.getMethodExpression().getQualifierExpression());
|
||||
if (variable == null) {
|
||||
final PsiExpression qualifierExpression = getQualifierExpression(expression);
|
||||
if (qualifierExpression == null) {
|
||||
return;
|
||||
}
|
||||
final PsiVariable otherVariable = getArgumentFromEqualsCallOn(expression, variable);
|
||||
if (otherVariable == null) {
|
||||
final PsiExpression argumentExpression = getArgumentExpression(expression);
|
||||
if (argumentExpression == null) {
|
||||
return;
|
||||
}
|
||||
registerError(expression, variable.getName(), otherVariable.getName(), true);
|
||||
registerError(expression, qualifierExpression.getText(), argumentExpression.getText(), true);
|
||||
}
|
||||
}
|
||||
|
||||
private PsiExpression getQualifierExpression(PsiMethodCallExpression expression) {
|
||||
return ParenthesesUtils.stripParentheses(expression.getMethodExpression().getQualifierExpression());
|
||||
}
|
||||
|
||||
private boolean processNotNullCheck(PsiBinaryExpression expression) {
|
||||
final IElementType tokenType = expression.getOperationTokenType();
|
||||
final PsiExpression rightOperand = ParenthesesUtils.stripParentheses(expression.getROperand());
|
||||
if (JavaTokenType.ANDAND.equals(tokenType)) {
|
||||
final PsiVariable variable = ExpressionUtils.getVariableFromNullComparison(expression.getLOperand(), false);
|
||||
if (variable == null) {
|
||||
return false;
|
||||
}
|
||||
final PsiVariable otherVariable = getArgumentFromEqualsCallOn(expression.getROperand(), variable);
|
||||
if (otherVariable == null) {
|
||||
return false;
|
||||
}
|
||||
checkEqualityBefore(expression, true, variable, otherVariable);
|
||||
return registerProblem(expression, rightOperand, true);
|
||||
}
|
||||
else if (JavaTokenType.OROR.equals(tokenType)) {
|
||||
final PsiVariable variable = ExpressionUtils.getVariableFromNullComparison(expression.getLOperand(), true);
|
||||
if (variable == null) {
|
||||
return false;
|
||||
if (rightOperand instanceof PsiPrefixExpression &&
|
||||
JavaTokenType.EXCL.equals(((PsiPrefixExpression)rightOperand).getOperationTokenType())) {
|
||||
final PsiExpression negatedRightOperand = ParenthesesUtils.stripParentheses(((PsiPrefixExpression)rightOperand).getOperand());
|
||||
return registerProblem(expression, negatedRightOperand, false);
|
||||
}
|
||||
final PsiExpression rhs = ParenthesesUtils.stripParentheses(expression.getROperand());
|
||||
if (!(rhs instanceof PsiPrefixExpression)) {
|
||||
return false;
|
||||
}
|
||||
final PsiPrefixExpression prefixExpression = (PsiPrefixExpression)rhs;
|
||||
if (!JavaTokenType.EXCL.equals(prefixExpression.getOperationTokenType())) {
|
||||
return false;
|
||||
}
|
||||
final PsiVariable otherVariable = getArgumentFromEqualsCallOn(prefixExpression.getOperand(), variable);
|
||||
if (otherVariable == null) {
|
||||
return false;
|
||||
}
|
||||
checkEqualityBefore(expression, false, variable, otherVariable);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void checkEqualityBefore(PsiExpression expression, boolean equals, PsiVariable variable1, PsiVariable variable2) {
|
||||
final PsiElement parent = PsiTreeUtil.skipParentsOfType(expression, PsiParenthesizedExpression.class);
|
||||
if (parent instanceof PsiBinaryExpression) {
|
||||
final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)parent;
|
||||
if (PsiTreeUtil.isAncestor(binaryExpression.getROperand(), expression, false)) {
|
||||
final PsiExpression lhs = binaryExpression.getLOperand();
|
||||
if (isEquality(lhs, equals, variable1, variable2)) {
|
||||
registerError(binaryExpression, variable1.getName(), variable2.getName(), Boolean.valueOf(equals));
|
||||
return;
|
||||
/**
|
||||
* Match the patterns, and register the error if a pattern is matched:
|
||||
* <pre>
|
||||
* x==null || !x.equals(y)
|
||||
* x!=null && x.equals(y)</pre>
|
||||
*
|
||||
* @return true if the pattern is matched
|
||||
*/
|
||||
private boolean registerProblem(PsiBinaryExpression expression, PsiExpression rightOperand, boolean equal) {
|
||||
if ((rightOperand instanceof PsiMethodCallExpression)) {
|
||||
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)rightOperand;
|
||||
final PsiReferenceExpression nullCheckedExpression =
|
||||
ExpressionUtils.getReferenceExpressionFromNullComparison(expression.getLOperand(), !equal);
|
||||
final String nullCheckedName = getQualifiedVariableName(nullCheckedExpression);
|
||||
if (nullCheckedName != null) {
|
||||
final PsiExpression qualifierExpression = getQualifierExpression(methodCallExpression);
|
||||
final String qualifierName = getQualifiedVariableName(qualifierExpression);
|
||||
if (qualifierName != null && qualifierName.equals(nullCheckedName)) {
|
||||
final PsiExpression argumentExpression = getArgumentExpression(methodCallExpression);
|
||||
final String argumentName = getQualifiedVariableName(argumentExpression);
|
||||
final PsiExpression expressionToReplace =
|
||||
argumentName != null ? checkEqualityBefore(expression, equal, qualifierName, argumentName) : expression;
|
||||
registerError(expressionToReplace, nullCheckedExpression.getText(), argumentExpression.getText(), Boolean.valueOf(equal));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
registerError(expression, variable1.getName(), variable2.getName(), Boolean.valueOf(equals));
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isEquality(PsiExpression expression, boolean equals, PsiVariable variable1, PsiVariable variable2) {
|
||||
/**
|
||||
* Match the left side of the patterns:
|
||||
* <pre>
|
||||
* x!=y && (x==null || !x.equals(y))
|
||||
* x==y || (x!=null && x.equals(y))</pre>
|
||||
*
|
||||
* @return the expression matching the pattern, or the original expression if there's no match
|
||||
*/
|
||||
@Nullable
|
||||
private PsiExpression checkEqualityBefore(PsiExpression expression, boolean equal, String qualifiedName1, String qualifiedName2) {
|
||||
final PsiElement parent = PsiTreeUtil.skipParentsOfType(expression, PsiParenthesizedExpression.class);
|
||||
if (parent instanceof PsiBinaryExpression) {
|
||||
final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)parent;
|
||||
final IElementType tokenType = binaryExpression.getOperationTokenType();
|
||||
if (equal && JavaTokenType.OROR.equals(tokenType) || !equal && JavaTokenType.ANDAND.equals(tokenType)) {
|
||||
if (PsiTreeUtil.isAncestor(binaryExpression.getROperand(), expression, false)) {
|
||||
final PsiExpression lhs = binaryExpression.getLOperand();
|
||||
if (isEquality(lhs, equal, qualifiedName1, qualifiedName2)) {
|
||||
return binaryExpression;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return expression;
|
||||
}
|
||||
|
||||
private boolean isEquality(PsiExpression expression, boolean equals, String qualifiedName1, String qualifiedName2) {
|
||||
expression = ParenthesesUtils.stripParentheses(expression);
|
||||
if (!(expression instanceof PsiBinaryExpression)) {
|
||||
return false;
|
||||
@@ -208,33 +234,45 @@ public class EqualsReplaceableByObjectsCallInspection extends BaseInspection {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
final PsiExpression lhs = binaryExpression.getLOperand();
|
||||
final PsiExpression rhs = binaryExpression.getROperand();
|
||||
return (VariableAccessUtils.evaluatesToVariable(lhs, variable1) && VariableAccessUtils.evaluatesToVariable(rhs, variable2)) ||
|
||||
(VariableAccessUtils.evaluatesToVariable(lhs, variable2) && VariableAccessUtils.evaluatesToVariable(rhs, variable1));
|
||||
}
|
||||
|
||||
private PsiVariable getArgumentFromEqualsCallOn(PsiExpression expression, PsiVariable variable) {
|
||||
expression = ParenthesesUtils.stripParentheses(expression);
|
||||
if (!(expression instanceof PsiMethodCallExpression)) {
|
||||
return null;
|
||||
}
|
||||
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression;
|
||||
final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
|
||||
final String methodName = methodExpression.getReferenceName();
|
||||
if (!HardcodedMethodConstants.EQUALS.equals(methodName)) {
|
||||
return null;
|
||||
}
|
||||
final PsiExpression qualifier = methodExpression.getQualifierExpression();
|
||||
if (!VariableAccessUtils.evaluatesToVariable(qualifier, variable)) {
|
||||
return null;
|
||||
}
|
||||
final PsiExpressionList argumentList = methodCallExpression.getArgumentList();
|
||||
final PsiExpression[] expressions = argumentList.getExpressions();
|
||||
if (expressions.length != 1) {
|
||||
return null;
|
||||
}
|
||||
return ExpressionUtils.getVariable(expressions[0]);
|
||||
final PsiExpression leftOperand = ParenthesesUtils.stripParentheses(binaryExpression.getLOperand());
|
||||
final PsiExpression rightOperand = ParenthesesUtils.stripParentheses(binaryExpression.getROperand());
|
||||
final String leftName = getQualifiedVariableName(leftOperand);
|
||||
final String rightName = getQualifiedVariableName(rightOperand);
|
||||
return leftName != null && rightName != null &&
|
||||
(leftName.equals(qualifiedName1) && rightName.equals(qualifiedName2) ||
|
||||
leftName.equals(qualifiedName2) && rightName.equals(qualifiedName1));
|
||||
}
|
||||
}
|
||||
|
||||
private PsiExpression getArgumentExpression(PsiMethodCallExpression callExpression) {
|
||||
final PsiExpression[] expressions = callExpression.getArgumentList().getExpressions();
|
||||
return expressions.length == 1 ? ParenthesesUtils.stripParentheses(expressions[0]) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the expression is a variable name chain like "a.b.c" ("this" and "super" are allowed), and convert it into a qualified name
|
||||
*
|
||||
* @return the text representation of the variable chain (with parenthesis stripped), or {@code null} if it's not a variable chain
|
||||
*/
|
||||
@Nullable
|
||||
private static String getQualifiedVariableName(@Nullable PsiExpression expression) {
|
||||
if (expression instanceof PsiReferenceExpression) {
|
||||
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)expression;
|
||||
final String referenceName = referenceExpression.getReferenceName();
|
||||
if (referenceName != null && referenceExpression.resolve() instanceof PsiVariable) {
|
||||
final PsiExpression qualifierExpression = ParenthesesUtils.stripParentheses(referenceExpression.getQualifierExpression());
|
||||
if (qualifierExpression == null) {
|
||||
return referenceName;
|
||||
}
|
||||
final String qualifierName = getQualifiedVariableName(qualifierExpression);
|
||||
return qualifierName != null ? qualifierName + "." + referenceName : null;
|
||||
}
|
||||
}
|
||||
else if (expression instanceof PsiQualifiedExpression) {
|
||||
final PsiJavaCodeReferenceElement qualifier = ((PsiQualifiedExpression)expression).getQualifier();
|
||||
final String name = expression instanceof PsiThisExpression ? "this" : "super";
|
||||
return qualifier != null ? qualifier.getQualifiedName() + "." + name : name;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+12
-15
@@ -600,6 +600,13 @@ public class ExpressionUtils {
|
||||
|
||||
@Nullable
|
||||
public static PsiVariable getVariableFromNullComparison(PsiExpression expression, boolean equals) {
|
||||
final PsiReferenceExpression referenceExpression = getReferenceExpressionFromNullComparison(expression, equals);
|
||||
final PsiElement target = referenceExpression.resolve();
|
||||
return target instanceof PsiVariable ? (PsiVariable)target : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiReferenceExpression getReferenceExpressionFromNullComparison(PsiExpression expression, boolean equals) {
|
||||
expression = ParenthesesUtils.stripParentheses(expression);
|
||||
if (!(expression instanceof PsiPolyadicExpression)) {
|
||||
return null;
|
||||
@@ -620,26 +627,16 @@ public class ExpressionUtils {
|
||||
if (operands.length != 2) {
|
||||
return null;
|
||||
}
|
||||
PsiExpression comparedToNull = null;
|
||||
if (PsiType.NULL.equals(operands[0].getType())) {
|
||||
return getVariable(operands[1]);
|
||||
comparedToNull = operands[1];
|
||||
}
|
||||
else if (PsiType.NULL.equals(operands[1].getType())) {
|
||||
return getVariable(operands[0]);
|
||||
comparedToNull = operands[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
comparedToNull = ParenthesesUtils.stripParentheses(comparedToNull);
|
||||
|
||||
public static PsiVariable getVariable(@Nullable PsiExpression expression) {
|
||||
expression = ParenthesesUtils.stripParentheses(expression);
|
||||
if (!(expression instanceof PsiReferenceExpression)) {
|
||||
return null;
|
||||
}
|
||||
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)expression;
|
||||
final PsiElement target = referenceExpression.resolve();
|
||||
if (!(target instanceof PsiVariable)) {
|
||||
return null;
|
||||
}
|
||||
return (PsiVariable)target;
|
||||
return comparedToNull instanceof PsiReferenceExpression ? (PsiReferenceExpression)comparedToNull : null;
|
||||
}
|
||||
|
||||
public static boolean isConcatenation(PsiElement element) {
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import java.util.Objects;
|
||||
|
||||
class T {
|
||||
static boolean same(String t, String s) {
|
||||
return Objects.equals(s, t + "a");
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class T {
|
||||
static boolean same(String t, String s) {
|
||||
return s.<caret>equals(t + "a");
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import java.util.Objects;
|
||||
|
||||
class T {
|
||||
static boolean same(String t, String s) {
|
||||
return Objects.equals(s, t + "a");
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class T {
|
||||
static boolean same(String t, String s) {
|
||||
return s != null && s.<caret>equals(t + "a");
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import java.util.Objects;
|
||||
|
||||
class T {
|
||||
static boolean same(String t, String s) {
|
||||
return Objects.equals(t + "a", s);
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class T {
|
||||
static boolean same(String t, String s) {
|
||||
return (t + "a").<caret>equals(s);
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import java.util.Objects;
|
||||
|
||||
class T {
|
||||
static class P { String n; }
|
||||
|
||||
static boolean same(P a, P b) {
|
||||
return Objects.equals(a.n, b.n);
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class T {
|
||||
static class P { String n; }
|
||||
|
||||
static boolean same(P a, P b) {
|
||||
return a.n == b.n || a.n != null && a.n.<caret>equals(b.n);
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import java.util.Objects;
|
||||
|
||||
class T {
|
||||
static class P { String n; }
|
||||
|
||||
static boolean notSame(P a, P b) {
|
||||
return !Objects.equals(a.n, b.n);
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class T {
|
||||
static class P { String n; }
|
||||
|
||||
static boolean notSame(P a, P b) {
|
||||
return a.n != b.n && (a.n == null || !a.n.<caret>equals(b.n));
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
import java.util.Objects;
|
||||
|
||||
class T {
|
||||
static class A {
|
||||
String s;
|
||||
}
|
||||
A a;
|
||||
static boolean same(T t, String s) {
|
||||
return Objects.equals(s, t.a.s);
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
class T {
|
||||
static class A {
|
||||
String s;
|
||||
}
|
||||
A a;
|
||||
static boolean same(T t, String s) {
|
||||
return s.<caret>equals(t.a.s);
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
import java.util.Objects;
|
||||
|
||||
class T {
|
||||
static class A {
|
||||
String s;
|
||||
}
|
||||
A a;
|
||||
static boolean same(T t, String s) {
|
||||
return Objects.equals(t.a.s, s);
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
class T {
|
||||
static class A {
|
||||
String s;
|
||||
}
|
||||
A a;
|
||||
static boolean same(T t, String s) {
|
||||
return t.a.s != null && t.a.s.<caret>equals(s);
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
import java.util.Objects;
|
||||
|
||||
class T {
|
||||
String s;
|
||||
|
||||
class A {
|
||||
T t;
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
void check(final String s) {
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
boolean b = Objects.equals(B.super.t.s, s);
|
||||
System.out.println(b);
|
||||
}
|
||||
}.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
class T {
|
||||
String s;
|
||||
|
||||
class A {
|
||||
T t;
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
void check(final String s) {
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
boolean b = (B.super.t.s) == s || (B.super.t.s) != null && (B.super.t).s.<caret>equals(s);
|
||||
System.out.println(b);
|
||||
}
|
||||
}.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import java.util.Objects;
|
||||
|
||||
class T {
|
||||
String s;
|
||||
class A {
|
||||
boolean notSame(String s) {
|
||||
return !Objects.equals(T.this.s, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
class T {
|
||||
String s;
|
||||
class A {
|
||||
boolean notSame(String s) {
|
||||
return T.this.s != s && (T.this.s == null || !T.this.s.<caret>equals(s));
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import java.util.Objects;
|
||||
|
||||
class T {
|
||||
static class P { String n; }
|
||||
|
||||
static boolean same(P a, P b) {
|
||||
return Objects.equals(a.n, b.n);
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class T {
|
||||
static class P { String n; }
|
||||
|
||||
static boolean same(P a, P b) {
|
||||
return a.n != null && a.n.<caret>equals(b.n);
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import java.util.Objects;
|
||||
|
||||
class T {
|
||||
static class P { String n; }
|
||||
|
||||
static boolean notSame(P a, P b) {
|
||||
return !Objects.equals(a.n, b.n);
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class T {
|
||||
static class P { String n; }
|
||||
|
||||
static boolean notSame(P a, P b) {
|
||||
return a.n == null || !a.n.<caret>equals(b.n);
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import java.util.Objects;
|
||||
|
||||
class T {
|
||||
static boolean same(String t, String s) {
|
||||
return Objects.equals(s, t);
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class T {
|
||||
static boolean same(String t, String s) {
|
||||
return s.<caret>equals(t);
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import java.util.Objects;
|
||||
|
||||
class T {
|
||||
static boolean notSame(String t, String s) {
|
||||
return !Objects.equals(s, t);
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class T {
|
||||
static boolean notSame(String t, String s) {
|
||||
return !s.<caret>equals(t);
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import java.util.Objects;
|
||||
|
||||
class T {
|
||||
String s;
|
||||
static class X extends T {
|
||||
boolean same(String s) {
|
||||
return Objects.equals(super.s, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
class T {
|
||||
String s;
|
||||
static class X extends T {
|
||||
boolean same(String s) {
|
||||
return super.s.<caret>equals(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import java.util.Objects;
|
||||
|
||||
class T {
|
||||
String s;
|
||||
boolean same(String s) {
|
||||
return Objects.equals(this.s, s);
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
class T {
|
||||
String s;
|
||||
boolean same(String s) {
|
||||
return this.s.<caret>equals(s);
|
||||
}
|
||||
}
|
||||
+27
@@ -8,4 +8,31 @@ class EqualsReplaceableByObjectsCall {
|
||||
void ignoreNullityCheck(Object a, Object b) {
|
||||
boolean c = <warning descr="'a.equals(b)' replaceable by 'Objects.equals()' expression">a.equals(b)</warning>;
|
||||
}
|
||||
|
||||
void bar(T x, T y, T z) {
|
||||
boolean b = !<warning descr="'x.s.equals(y.s)' replaceable by 'Objects.equals()' expression">x.s.equals(y.s)</warning>;
|
||||
boolean c = <warning descr="'x.s != null && x.s.equals(y.s)' replaceable by 'Objects.equals()' expression">x.s != null && x.s.equals(y.s)</warning>;
|
||||
boolean d = y.s != null && <warning descr="'x.s.equals(y.s)' replaceable by 'Objects.equals()' expression">x.s.equals(y.s)</warning>;
|
||||
boolean e = <warning descr="'x.s == null || !x.s.equals(y.s)' replaceable by 'Objects.equals()' expression">x.s == null || !x.s.equals(y.s)</warning>;
|
||||
boolean f = <warning descr="'x.s != y.s && (x.s == null || !x.s.equals(y.s))' replaceable by 'Objects.equals()' expression">x.s != y.s && (x.s == null || !x.s.equals(y.s))</warning>;
|
||||
boolean g = x.s != y.s || (<warning descr="'x.s == null || !x.s.equals(y.s)' replaceable by 'Objects.equals()' expression">x.s == null || !x.s.equals(y.s)</warning>);
|
||||
boolean h = x.s != y.s && (z.s == null || !<warning descr="'x.s.equals(y.s)' replaceable by 'Objects.equals()' expression">x.s.equals(y.s)</warning>);
|
||||
}
|
||||
|
||||
void baz(T x, T y) {
|
||||
boolean b = <warning descr="'x.copy().equals(y.copy())' replaceable by 'Objects.equals()' expression">x.copy().equals(y.copy())</warning>;
|
||||
boolean c = <warning descr="'x != null && x.equals(y.copy())' replaceable by 'Objects.equals()' expression">x != null && x.equals(y.copy())</warning>;
|
||||
boolean d = <warning descr="'x == null || !x.equals(y.copy())' replaceable by 'Objects.equals()' expression">x == null || !x.equals(y.copy())</warning>;
|
||||
boolean e = x.copy() != null && <warning descr="'x.copy().equals(y)' replaceable by 'Objects.equals()' expression">x.copy().equals(y)</warning>;
|
||||
boolean f = x.copy() == null || !<warning descr="'x.copy().equals(y)' replaceable by 'Objects.equals()' expression">x.copy().equals(y)</warning>;
|
||||
boolean g = x.copy().s != null && <warning descr="'x.copy().s.equals(y.s)' replaceable by 'Objects.equals()' expression">x.copy().s.equals(y.s)</warning>;
|
||||
boolean h = x.copy().s == null || !<warning descr="'x.copy().s.equals(y.s)' replaceable by 'Objects.equals()' expression">x.copy().s.equals(y.s)</warning>;
|
||||
boolean i = x.s == y.copy().s || <warning descr="'(x).s != null && (x.s).equals(y.copy().s)' replaceable by 'Objects.equals()' expression">(x).s != null && (x.s).equals(y.copy().s)</warning>;
|
||||
boolean j = x.s != y.copy().s && (<warning descr="'(x).s == null || !(x.s).equals(y.copy().s)' replaceable by 'Objects.equals()' expression">(x).s == null || !(x.s).equals(y.copy().s)</warning>);
|
||||
}
|
||||
|
||||
static class T {
|
||||
String s;
|
||||
T copy() { T t = new T(); t.s = s; return t; }
|
||||
}
|
||||
}
|
||||
+27
@@ -8,4 +8,31 @@ class EqualsReplaceableByObjectsCall {
|
||||
void ignoreNullityCheck(Object a, Object b) {
|
||||
boolean c = a.equals(b);
|
||||
}
|
||||
|
||||
void bar(T x, T y, T z) {
|
||||
boolean b = !x.s.equals(y.s);
|
||||
boolean c = <warning descr="'x.s != null && x.s.equals(y.s)' replaceable by 'Objects.equals()' expression">x.s != null && x.s.equals(y.s)</warning>;
|
||||
boolean d = y.s != null && x.s.equals(y.s);
|
||||
boolean e = <warning descr="'x.s == null || !x.s.equals(y.s)' replaceable by 'Objects.equals()' expression">x.s == null || !x.s.equals(y.s)</warning>;
|
||||
boolean f = <warning descr="'x.s != y.s && (x.s == null || !x.s.equals(y.s))' replaceable by 'Objects.equals()' expression">x.s != y.s && (x.s == null || !x.s.equals(y.s))</warning>;
|
||||
boolean g = x.s != y.s || (<warning descr="'x.s == null || !x.s.equals(y.s)' replaceable by 'Objects.equals()' expression">x.s == null || !x.s.equals(y.s)</warning>);
|
||||
boolean h = x.s != y.s && (z.s == null || !x.s.equals(y.s));
|
||||
}
|
||||
|
||||
void baz(T x, T y) {
|
||||
boolean b = x.copy().equals(y.copy());
|
||||
boolean c = <warning descr="'x != null && x.equals(y.copy())' replaceable by 'Objects.equals()' expression">x != null && x.equals(y.copy())</warning>;
|
||||
boolean d = <warning descr="'x == null || !x.equals(y.copy())' replaceable by 'Objects.equals()' expression">x == null || !x.equals(y.copy())</warning>;
|
||||
boolean e = x.copy() != null && x.copy().equals(y);
|
||||
boolean f = x.copy() == null || !x.copy().equals(y);
|
||||
boolean g = x.copy().s != null && x.copy().s.equals(y.s);
|
||||
boolean h = x.copy().s == null || !x.copy().s.equals(y.s);
|
||||
boolean i = x.s == y.copy().s || <warning descr="'(x).s != null && (x.s).equals(y.copy().s)' replaceable by 'Objects.equals()' expression">(x).s != null && (x.s).equals(y.copy().s)</warning>;
|
||||
boolean j = x.s != y.copy().s && (<warning descr="'(x).s == null || !(x.s).equals(y.copy().s)' replaceable by 'Objects.equals()' expression">(x).s == null || !(x.s).equals(y.copy().s)</warning>);
|
||||
}
|
||||
|
||||
static class T {
|
||||
String s;
|
||||
T copy() { T t = new T(); t.s = s; return t; }
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.fixes.migration;
|
||||
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.IGQuickFixesTestCase;
|
||||
import com.siyeh.ig.migration.EqualsReplaceableByObjectsCallInspection;
|
||||
|
||||
/**
|
||||
* @author Pavel.Dolgov
|
||||
*/
|
||||
public class EqualsReplaceableByObjectsCallFixTest extends IGQuickFixesTestCase {
|
||||
|
||||
public void testSimpleEquals() { doTest(); }
|
||||
public void testSimpleNotEquals() { doTest(); }
|
||||
|
||||
public void testQualifiedArgument() { doTest(); }
|
||||
public void testQualifiedReciever() { doTest(); }
|
||||
|
||||
public void testExpressionReciever() { doTest(); }
|
||||
public void testExpressionArgument() { doTest(); }
|
||||
public void testExpressionArgument2() { doTest(); }
|
||||
|
||||
public void testLongEquals() { doTest(); }
|
||||
public void testLongNotEquals() { doTest(); }
|
||||
public void testShortEquals() { doTest(); }
|
||||
public void testShortNotEquals() { doTest(); }
|
||||
|
||||
public void testSuperEquals() { doTest(); }
|
||||
public void testThisEquals() { doTest(); }
|
||||
|
||||
public void testQualifiedThisNotEqual() { doTest(); }
|
||||
public void testQualifiedSuperEqual() { doTest(); }
|
||||
|
||||
@Override
|
||||
protected void tuneFixture(JavaModuleFixtureBuilder builder) throws Exception {
|
||||
builder.addJdk(IdeaTestUtil.getMockJdk18Path().getPath())
|
||||
.setLanguageLevel(LanguageLevel.JDK_1_7);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
myFixture.enableInspections(new EqualsReplaceableByObjectsCallInspection());
|
||||
myRelativePath = "migration/equals_replaceable_by_objects_call";
|
||||
myDefaultHint = InspectionGadgetsBundle.message("equals.replaceable.by.objects.call.quickfix");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user