IDEA-67522 (array equals inspection misses == operator on two arrays)

Added "Array comparison using '==', instead of 'Arrays.equals()'" inspection
This commit is contained in:
Bas Leijdekkers
2011-04-06 09:54:38 +02:00
parent 057be17c9b
commit 0836d5ff07
5 changed files with 148 additions and 5 deletions
@@ -1867,3 +1867,6 @@ html.tag.can.be.javadoc.tag.quickfix=Replace with '{@code ...}'
try.finally.can.be.try.with.resources.display.name='try finally' replaceable with 'try' with resources
try.finally.can.be.try.with.resources.problem.descriptor=<code>#ref</code> can use automatic resource management
try.finally.can.be.try.with.resources.quickfix=Replace with 'try' with resources
array.comparison.display.name=Array comparison using '==', instead of 'Arrays.equals()'
array.comparison.problem.descriptor=Array objects are compared using <code>#ref</code>, not 'Arrays.equals()' #loc
array.comparison.quickfix=Replace with 'Arrays.equals()'
@@ -516,6 +516,7 @@ public class InspectionGadgetsPlugin implements ApplicationComponent,
private void registerBugInspections() {
m_inspectionClasses.add(ArchaicSystemPropertyAccessInspection.class);
m_inspectionClasses.add(ArrayEqualityInspection.class);
m_inspectionClasses.add(ArrayEqualsInspection.class);
m_inspectionClasses.add(AssertWithSideEffectsInspection.class);
m_inspectionClasses.add(ConstantAssertConditionInspection.class);
@@ -0,0 +1,131 @@
/*
* Copyright 2003-2011 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.siyeh.ig.bugs;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.ComparisonUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
public class ArrayEqualityInspection extends BaseInspection {
@Override
@NotNull
public String getDisplayName() {
return InspectionGadgetsBundle.message(
"array.comparison.display.name");
}
@Override
@NotNull
public String buildErrorString(Object... infos) {
return InspectionGadgetsBundle.message(
"array.comparison.problem.descriptor");
}
@Override
public InspectionGadgetsFix buildFix(Object... infos) {
return new ArrayEqualityFix();
}
private static class ArrayEqualityFix extends InspectionGadgetsFix {
@NotNull
@Override
public String getName() {
return InspectionGadgetsBundle.message("array.comparison.quickfix");
}
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
final PsiElement element = descriptor.getPsiElement();
final PsiElement parent = element.getParent();
if (!(parent instanceof PsiBinaryExpression)) {
return;
}
final PsiBinaryExpression binaryExpression =
(PsiBinaryExpression) parent;
final IElementType tokenType =
binaryExpression.getOperationTokenType();
@NonNls final StringBuilder newExpressionText = new StringBuilder();
if (JavaTokenType.NE.equals(tokenType)) {
newExpressionText.append('!');
} else if (!JavaTokenType.EQEQ.equals(tokenType)) {
return;
}
newExpressionText.append("java.util.Arrays.equals(");
newExpressionText.append(binaryExpression.getLOperand().getText());
newExpressionText.append(',');
final PsiExpression rhs = binaryExpression.getROperand();
if (rhs == null) {
return;
}
newExpressionText.append(rhs.getText());
newExpressionText.append(')');
replaceExpressionAndShorten(binaryExpression,
newExpressionText.toString());
}
}
@Override
public BaseInspectionVisitor buildVisitor() {
return new ArrayEqualityVisitor();
}
private static class ArrayEqualityVisitor extends BaseInspectionVisitor {
@Override public void visitBinaryExpression(
@NotNull PsiBinaryExpression expression) {
super.visitBinaryExpression(expression);
if(!(expression.getROperand() != null)){
return;
}
if (!ComparisonUtils.isEqualityComparison(expression)) {
return;
}
final PsiExpression lhs = expression.getLOperand();
if (!(lhs.getType() instanceof PsiArrayType)) {
return;
}
final PsiExpression rhs = expression.getROperand();
if (rhs == null) {
return;
}
if (!(rhs.getType() instanceof PsiArrayType)) {
return;
}
final String lhsText = lhs.getText();
if (PsiKeyword.NULL.equals(lhsText)) {
return;
}
final String rhsText = rhs.getText();
if (PsiKeyword.NULL.equals(rhsText)) {
return;
}
final PsiJavaToken sign = expression.getOperationSign();
registerError(sign);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2010 Dave Griffith, Bas Leijdekkers
* Copyright 2003-2011 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -48,7 +48,7 @@ public class NumberEqualityInspection extends BaseInspection {
@Override
public BaseInspectionVisitor buildVisitor() {
return new ObjectEqualityVisitor();
return new NumberEqualityVisitor();
}
@Override
@@ -56,7 +56,7 @@ public class NumberEqualityInspection extends BaseInspection {
return new EqualityToEqualsFix();
}
private static class ObjectEqualityVisitor extends BaseInspectionVisitor {
private static class NumberEqualityVisitor extends BaseInspectionVisitor {
@Override public void visitBinaryExpression(
@NotNull PsiBinaryExpression expression) {
@@ -90,8 +90,8 @@ public class NumberEqualityInspection extends BaseInspection {
registerError(sign);
}
private static boolean hasNumberType(PsiExpression lhs) {
return TypeUtils.expressionHasTypeOrSubtype(lhs,
private static boolean hasNumberType(PsiExpression expression) {
return TypeUtils.expressionHasTypeOrSubtype(expression,
CommonClassNames.JAVA_LANG_NUMBER);
}
}
@@ -0,0 +1,8 @@
<html>
<body>
This inspection reports any use of <b>==</b> to test for Array equality,
rather than the <b>"java.util.Arrays.equals()"</b> method.
<p>
<small>New in 10.5, Powered by InspectionGadgets</small>
</body>
</html>