From 0836d5ff07b0937563ba57ef1140f9877dae5314 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Wed, 6 Apr 2011 09:54:38 +0200 Subject: [PATCH] IDEA-67522 (array equals inspection misses == operator on two arrays) Added "Array comparison using '==', instead of 'Arrays.equals()'" inspection --- .../siyeh/InspectionGadgetsBundle.properties | 3 + .../com/siyeh/ig/InspectionGadgetsPlugin.java | 1 + .../ig/bugs/ArrayEqualityInspection.java | 131 ++++++++++++++++++ .../ig/bugs/NumberEqualityInspection.java | 10 +- .../inspectionDescriptions/ArrayEquality.html | 8 ++ 5 files changed, 148 insertions(+), 5 deletions(-) create mode 100644 plugins/InspectionGadgets/src/com/siyeh/ig/bugs/ArrayEqualityInspection.java create mode 100644 plugins/InspectionGadgets/src/inspectionDescriptions/ArrayEquality.html diff --git a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties index 9b8042e92c18..b958c1a993ee 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties @@ -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=#ref 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 #ref, not 'Arrays.equals()' #loc +array.comparison.quickfix=Replace with 'Arrays.equals()' diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsPlugin.java b/plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsPlugin.java index 4b98f6fa552b..53afc9934869 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsPlugin.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsPlugin.java @@ -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); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/ArrayEqualityInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/ArrayEqualityInspection.java new file mode 100644 index 000000000000..7e13f97ba92b --- /dev/null +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/ArrayEqualityInspection.java @@ -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); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/NumberEqualityInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/NumberEqualityInspection.java index 3d9b4922c0c4..9ef8c6cf0fd0 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/NumberEqualityInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/NumberEqualityInspection.java @@ -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); } } diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayEquality.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayEquality.html new file mode 100644 index 000000000000..515d2d82489e --- /dev/null +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ArrayEquality.html @@ -0,0 +1,8 @@ + + +This inspection reports any use of == to test for Array equality, +rather than the "java.util.Arrays.equals()" method. +

+New in 10.5, Powered by InspectionGadgets + + \ No newline at end of file