IG: merge 3 inspections into one "Call to suspicious String method" inspection

This commit is contained in:
Bas Leijdekkers
2016-10-29 20:50:06 +02:00
parent 024d0f5894
commit 1eebf487f3
17 changed files with 164 additions and 434 deletions
@@ -402,6 +402,15 @@ public class InspectionProfileTest extends LightIdeaTestCase {
"</profile>");
}
public void testMergedCallToSuspiciousStringMethodInspections() throws Exception {
checkMergedNoChanges("<profile version=\"1.0\">\n" +
" <option name=\"myName\" value=\"" + PROFILE + "\" />\n" +
" <inspection_tool class=\"StringCompareTo\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\" />\n" +
" <inspection_tool class=\"StringEquals\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\" />\n" +
" <inspection_tool class=\"StringEqualsIgnoreCase\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\" />\n" +
"</profile>" );
}
public void testMergedMisspelledInspections() throws Exception {
checkMergedNoChanges("<profile version=\"1.0\">\n" +
" <option name=\"myName\" value=\"" + PROFILE + "\" />\n" +
@@ -7,6 +7,7 @@
<inspectionElementsMerger implementation="com.siyeh.ig.junit.MalformedSetUpTearDownInspectionMerger"/>
<inspectionElementsMerger implementation="com.siyeh.ig.inheritance.MethodDoesntCallSuperMethodInspectionMerger"/>
<inspectionElementsMerger implementation="com.siyeh.ig.threading.WaitNotifyNotInSynchronizedContextInspectionMerger"/>
<inspectionElementsMerger implementation="com.siyeh.ig.internationalization.CallToSuspiciousStringMethodInspectionMerger"/>
<!--group.names.abstraction.issues-->
<localInspection groupPath="Java" language="JAVA" shortName="BooleanParameter" bundle="com.siyeh.InspectionGadgetsBundle" key="boolean.parameter.display.name"
@@ -1129,6 +1130,10 @@
level="WARNING" implementationClass="com.siyeh.ig.initialization.ThisEscapedInConstructorInspection"/>
<!--group.names.internationalization.issues-->
<localInspection groupPath="Java" language="JAVA" shortName="CallToSuspiciousStringMethod" bundle="com.siyeh.InspectionGadgetsBundle"
key="call.to.suspicious.string.method.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.internationalization.issues" enabledByDefault="false" level="WARNING"
implementationClass="com.siyeh.ig.internationalization.CallToSuspiciousStringMethodInspection"/>
<localInspection groupPath="Java" language="JAVA" shortName="CharacterComparison" bundle="com.siyeh.InspectionGadgetsBundle" key="character.comparison.display.name"
groupBundle="messages.InspectionsBundle" groupKey="group.names.internationalization.issues" enabledByDefault="false"
level="WARNING" implementationClass="com.siyeh.ig.internationalization.CharacterComparisonInspection"/>
@@ -1147,21 +1152,9 @@
key="instantiating.simpledateformat.without.locale.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.internationalization.issues" enabledByDefault="false" level="WARNING"
implementationClass="com.siyeh.ig.internationalization.SimpleDateFormatWithoutLocaleInspection"/>
<localInspection groupPath="Java" language="JAVA" suppressId="CallToStringCompareTo" shortName="StringCompareTo" bundle="com.siyeh.InspectionGadgetsBundle"
key="string.compareto.call.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.internationalization.issues" enabledByDefault="false" level="WARNING"
implementationClass="com.siyeh.ig.internationalization.StringCompareToInspection"/>
<localInspection groupPath="Java" language="JAVA" shortName="StringConcatenation" bundle="com.siyeh.InspectionGadgetsBundle" key="string.concatenation.display.name"
groupBundle="messages.InspectionsBundle" groupKey="group.names.internationalization.issues" enabledByDefault="false"
level="WARNING" implementationClass="com.siyeh.ig.internationalization.StringConcatenationInspection"/>
<localInspection groupPath="Java" language="JAVA" suppressId="CallToStringEqualsIgnoreCase" shortName="StringEqualsIgnoreCase" bundle="com.siyeh.InspectionGadgetsBundle"
key="string.equalsignorecase.call.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.internationalization.issues" enabledByDefault="false" level="WARNING"
implementationClass="com.siyeh.ig.internationalization.StringEqualsIgnoreCaseInspection"/>
<localInspection groupPath="Java" language="JAVA" suppressId="CallToStringEquals" shortName="StringEquals" bundle="com.siyeh.InspectionGadgetsBundle"
key="string.equals.call.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.internationalization.issues" enabledByDefault="false" level="WARNING"
implementationClass="com.siyeh.ig.internationalization.StringEqualsInspection"/>
<localInspection groupPath="Java" language="JAVA" suppressId="StringToUpperCaseOrToLowerCaseWithoutLocale" shortName="StringToUpperWithoutLocale"
bundle="com.siyeh.InspectionGadgetsBundle" key="string.touppercase.tolowercase.without.locale.display.name"
groupBundle="messages.InspectionsBundle" groupKey="group.names.internationalization.issues" enabledByDefault="false"
@@ -1182,7 +1175,7 @@
key="unnecessary.unicode.escape.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.internationalization.issues" enabledByDefault="false" level="WARNING"
implementationClass="com.siyeh.ig.internationalization.UnnecessaryUnicodeEscapeInspection"/>
<localInspection groupPath="Java" language="JAVA" shortName="ImplicitDefaultCharsetUsage" bundle="com.siyeh.InspectionGadgetsBundle"
<localInspection groupPath="Java" language="JAVA" shortName="ImplicitDefaultCharsetUsage" bundle="com.siyeh.InspectionGadgetsBundle"
key="implicit.default.charset.usage.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.internationalization.issues" enabledByDefault="false" level="WARNING"
implementationClass="com.siyeh.ig.internationalization.ImplicitDefaultCharsetUsageInspection"/>
@@ -320,8 +320,6 @@ call.to.numeric.tostring.display.name=Call to Numeric 'toString()'
call.to.numeric.tostring.problem.descriptor=Numeric <code>#ref()</code> called in an internationalized context #loc
instantiating.simpledateformat.without.locale.display.name=Instantiating a SimpleDateFormat without a Locale
instantiating.simpledateformat.without.locale.problem.descriptor=Instantiating a <code>#ref</code> without specifying a Locale in an internationalized context #loc
string.compareto.call.display.name=Call to 'String.compareTo()'
string.compareto.call.problem.descriptor=<code>String.#ref()</code> called using internationalized strings #loc
string.concatenation.display.name=String concatenation
string.concatenation.problem.descriptor=String concatenation <code>#ref</code> in an internationalized context #loc
string.concatenation.ignore.system.out.option=Ignore for 'System.out.print' arguments
@@ -332,10 +330,6 @@ string.concatenation.ignore.constant.initializers.option=Ignore for initializers
ignore.in.annotations=Ignore in annotations
ignore.in.tostring=Ignore inside toString() methods
ignore.as.initial.capacity=Ignore initial capacity for StringBuilders and Collections
string.equalsignorecase.call.display.name=Call to 'String.equalsIgnoreCase()'
string.equalsignorecase.call.problem.descriptor=<code>String.#ref()</code> using internationalized strings #loc
string.equals.call.display.name=Call to 'String.equals()'
string.equals.call.problem.descriptor=<code>String.#ref()</code> using internationalized strings #loc
string.touppercase.tolowercase.without.locale.display.name=Call to 'String.toUpperCase()' or 'toLowerCase()' without a Locale
string.touppercase.tolowercase.without.locale.problem.descriptor=<code>String.#ref()</code> called without specifying a Locale using internationalized strings #loc
use.stringtokenizer.display.name=Use of StringTokenizer
@@ -2205,3 +2199,5 @@ wait.notify.while.not.synchronized.on.problem.descriptor=Call to <code>#ref</cod
junit5.assertions.converter.display.name=Obsolete assertions in JUnit 5 tests
junit5.converter.display.name=JUnit4 test can be JUnit5
junit5.converter.fix.name=Migrate to JUnit5
call.to.suspicious.string.method.display.name=Call to suspicious String method
call.to.suspicious.string.method.problem.descriptor=<code>String.#ref()</code> called in internationalized context #loc
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2010 Dave Griffith, Bas Leijdekkers
* 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.
@@ -24,90 +24,70 @@ import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.DelegatingFix;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.MethodCallUtils;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class StringEqualsInspection extends BaseInspection {
/**
* @author Bas Leijdekkers
*/
public class CallToSuspiciousStringMethodInspection extends BaseInspection {
@Override
@Nls
@NotNull
public String getID() {
return "CallToStringEquals";
}
@Override
@NotNull
public String getDisplayName() {
return InspectionGadgetsBundle.message(
"string.equals.call.display.name");
return InspectionGadgetsBundle.message("call.to.suspicious.string.method.display.name");
}
@NotNull
@Override
protected String buildErrorString(Object... infos) {
return InspectionGadgetsBundle.message("call.to.suspicious.string.method.problem.descriptor");
}
@Override
@NotNull
public String buildErrorString(Object... infos) {
return InspectionGadgetsBundle.message(
"string.equals.call.problem.descriptor");
public BaseInspectionVisitor buildVisitor() {
return new CallToSuspiciousStringMethodVisitor();
}
@Override
@NotNull
protected InspectionGadgetsFix[] buildFixes(Object... infos) {
final PsiMethodCallExpression methodCallExpression =
(PsiMethodCallExpression)infos[0];
final List<InspectionGadgetsFix> result = new ArrayList();
final PsiReferenceExpression methodExpression =
methodCallExpression.getMethodExpression();
final PsiModifierListOwner annotatableQualifier =
NonNlsUtils.getAnnotatableQualifier(
methodExpression);
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)infos[0];
final List<InspectionGadgetsFix> result = new ArrayList<>();
final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
final PsiModifierListOwner annotatableQualifier = NonNlsUtils.getAnnotatableQualifier(methodExpression);
if (annotatableQualifier != null) {
final InspectionGadgetsFix fix =
createAddAnnotationFix(annotatableQualifier);
new DelegatingFix(new AddAnnotationPsiFix(AnnotationUtil.NON_NLS, annotatableQualifier, PsiNameValuePair.EMPTY_ARRAY));
result.add(fix);
}
final PsiModifierListOwner annotatableArgument =
NonNlsUtils.getAnnotatableArgument(
methodCallExpression);
final PsiModifierListOwner annotatableArgument = NonNlsUtils.getAnnotatableArgument(methodCallExpression);
if (annotatableArgument != null) {
final InspectionGadgetsFix fix =
createAddAnnotationFix(annotatableArgument);
new DelegatingFix(new AddAnnotationPsiFix(AnnotationUtil.NON_NLS, annotatableArgument, PsiNameValuePair.EMPTY_ARRAY));
result.add(fix);
}
return result.toArray(new InspectionGadgetsFix[result.size()]);
}
private static DelegatingFix createAddAnnotationFix(PsiModifierListOwner annotatableQualifier) {
return new DelegatingFix(new AddAnnotationPsiFix(
AnnotationUtil.NON_NLS, annotatableQualifier,PsiNameValuePair.EMPTY_ARRAY));
}
@Override
public BaseInspectionVisitor buildVisitor() {
return new StringEqualsVisitor();
}
private static class StringEqualsVisitor extends BaseInspectionVisitor {
private static class CallToSuspiciousStringMethodVisitor extends BaseInspectionVisitor {
@Override
public void visitMethodCallExpression(
@NotNull PsiMethodCallExpression expression) {
super.visitMethodCallExpression(expression);
if (!MethodCallUtils.isEqualsCall(expression)) {
public void visitMethodCallExpression(PsiMethodCallExpression expression) {
if (!MethodCallUtils.isEqualsCall(expression) &&
!MethodCallUtils.isEqualsIgnoreCaseCall(expression) &&
!MethodCallUtils.isCompareToCall(expression) &&
!MethodCallUtils.isCompareToIgnoreCaseCall(expression)) {
return;
}
final PsiMethod method = expression.resolveMethod();
if (method == null) {
return;
}
final PsiParameterList paramList = method.getParameterList();
final PsiParameter[] parameters = paramList.getParameters();
final PsiType parameterType = parameters[0].getType();
if (!TypeUtils.isJavaLangObject(parameterType)) {
return;
}
final PsiClass aClass = method.getContainingClass();
if (aClass == null) {
return;
@@ -116,22 +96,18 @@ public class StringEqualsInspection extends BaseInspection {
if (!CommonClassNames.JAVA_LANG_STRING.equals(className)) {
return;
}
final PsiReferenceExpression methodExpression =
expression.getMethodExpression();
final PsiExpression qualifier =
methodExpression.getQualifierExpression();
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
final PsiExpression qualifier = methodExpression.getQualifierExpression();
if (NonNlsUtils.isNonNlsAnnotated(qualifier)) {
return;
}
final PsiExpressionList argumentList = expression.getArgumentList();
final PsiExpression[] arguments = argumentList.getExpressions();
if (arguments.length != 1) {
return;
}
if (NonNlsUtils.isNonNlsAnnotated(arguments[0])) {
if (arguments.length != 1 || NonNlsUtils.isNonNlsAnnotated(arguments[0])) {
return;
}
registerMethodCallError(expression, expression);
}
}
}
}
@@ -0,0 +1,47 @@
/*
* 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.internationalization;
import com.intellij.codeInspection.ex.InspectionElementsMerger;
/**
* @author Bas Leijdekkers
*/
public class CallToSuspiciousStringMethodInspectionMerger extends InspectionElementsMerger {
@Override
public String getMergedToolName() {
return "CallToSuspiciousStringMethod";
}
@Override
public String[] getSourceToolNames() {
return new String[] {
"StringEquals",
"StringEqualsIgnoreCase",
"StringCompareTo"
};
}
@Override
public String[] getSuppressIds() {
return new String[] {
"CallToStringEquals",
"CallToStringEqualsIgnoreCase",
"CallToStringCompareTo"
};
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2007-2015 Bas Leijdekkers
* Copyright 2007-2016 Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,9 +22,9 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.siyeh.ig.psiutils.MethodUtils;
import org.jetbrains.annotations.Nullable;
public class NonNlsUtils {
class NonNlsUtils {
private static final Key<Boolean> KEY = new Key("IG_NON_NLS_ANNOTATED_USE");
private static final Key<Boolean> KEY = new Key<>("IG_NON_NLS_ANNOTATED_USE");
private NonNlsUtils() {
}
@@ -1,146 +0,0 @@
/*
* Copyright 2003-2010 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.internationalization;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
import com.intellij.psi.*;
import com.siyeh.HardcodedMethodConstants;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.DelegatingFix;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.MethodUtils;
import com.siyeh.ig.psiutils.TypeUtils;
import org.intellij.lang.annotations.Pattern;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class StringCompareToInspection extends BaseInspection {
@Pattern(VALID_ID_PATTERN)
@Override
@NotNull
public String getID() {
return "CallToStringCompareTo";
}
@Override
@NotNull
public String getDisplayName() {
return InspectionGadgetsBundle.message(
"string.compareto.call.display.name");
}
@Override
@NotNull
public String buildErrorString(Object... infos) {
return InspectionGadgetsBundle.message(
"string.compareto.call.problem.descriptor");
}
@Override
@NotNull
protected InspectionGadgetsFix[] buildFixes(Object... infos) {
final PsiMethodCallExpression methodCallExpression =
(PsiMethodCallExpression)infos[0];
final List<InspectionGadgetsFix> result = new ArrayList<>();
final PsiReferenceExpression methodExpression =
methodCallExpression.getMethodExpression();
final PsiModifierListOwner annotatableQualifier =
NonNlsUtils.getAnnotatableQualifier(
methodExpression);
if (annotatableQualifier != null) {
final InspectionGadgetsFix fix = new DelegatingFix(
new AddAnnotationPsiFix(AnnotationUtil.NON_NLS,
annotatableQualifier,PsiNameValuePair.EMPTY_ARRAY));
result.add(fix);
}
final PsiModifierListOwner annotatableArgument =
NonNlsUtils.getAnnotatableArgument(
methodCallExpression);
if (annotatableArgument != null) {
final InspectionGadgetsFix fix = new DelegatingFix(
new AddAnnotationPsiFix(AnnotationUtil.NON_NLS,
annotatableArgument,PsiNameValuePair.EMPTY_ARRAY));
result.add(fix);
}
return result.toArray(new InspectionGadgetsFix[result.size()]);
}
@Override
public BaseInspectionVisitor buildVisitor() {
return new StringCompareToVisitor();
}
private static class StringCompareToVisitor extends BaseInspectionVisitor {
@Override
public void visitMethodCallExpression(
@NotNull PsiMethodCallExpression expression) {
super.visitMethodCallExpression(expression);
if (!isStringCompareTo(expression)) {
return;
}
final PsiReferenceExpression methodExpression =
expression.getMethodExpression();
final PsiExpression qualifier =
methodExpression.getQualifierExpression();
if (NonNlsUtils.isNonNlsAnnotated(qualifier)) {
return;
}
final PsiExpressionList argumentList = expression.getArgumentList();
final PsiExpression[] arguments = argumentList.getExpressions();
if (arguments.length != 1) {
return;
}
if (NonNlsUtils.isNonNlsAnnotated(arguments[0])) {
return;
}
registerMethodCallError(expression, expression);
}
private static boolean isStringCompareTo(
PsiMethodCallExpression expression) {
final PsiReferenceExpression methodExpression =
expression.getMethodExpression();
final String name = methodExpression.getReferenceName();
if (!HardcodedMethodConstants.COMPARE_TO.equals(name)) {
return false;
}
final PsiMethod method = expression.resolveMethod();
if (!MethodUtils.isCompareTo(method)) {
return false;
}
final PsiParameterList parameterList = method.getParameterList();
final PsiParameter[] parameters = parameterList.getParameters();
final PsiType parameterType = parameters[0].getType();
if (!TypeUtils.isJavaLangObject(parameterType) &&
!TypeUtils.isJavaLangString(parameterType)) {
return false;
}
final PsiClass aClass = method.getContainingClass();
if (aClass == null) {
return false;
}
final String className = aClass.getQualifiedName();
return CommonClassNames.JAVA_LANG_STRING.equals(className);
}
}
}
@@ -1,142 +0,0 @@
/*
* Copyright 2003-2010 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.internationalization;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
import com.intellij.psi.*;
import com.siyeh.HardcodedMethodConstants;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.DelegatingFix;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class StringEqualsIgnoreCaseInspection extends BaseInspection {
@Override
@NotNull
public String getID() {
return "CallToStringEqualsIgnoreCase";
}
@Override
@NotNull
public String getDisplayName() {
return InspectionGadgetsBundle.message(
"string.equalsignorecase.call.display.name");
}
@Override
@NotNull
public String buildErrorString(Object... infos) {
return InspectionGadgetsBundle.message(
"string.equalsignorecase.call.problem.descriptor");
}
@Override
@NotNull
protected InspectionGadgetsFix[] buildFixes(Object... infos) {
final PsiMethodCallExpression methodCallExpression =
(PsiMethodCallExpression)infos[0];
final List<InspectionGadgetsFix> result = new ArrayList();
final PsiReferenceExpression methodExpression =
methodCallExpression.getMethodExpression();
final PsiModifierListOwner annotatableQualifier =
NonNlsUtils.getAnnotatableQualifier(methodExpression);
if (annotatableQualifier != null) {
final InspectionGadgetsFix fix =
createAddAnnotationFix(annotatableQualifier);
result.add(fix);
}
final PsiModifierListOwner annotatableArgument =
NonNlsUtils.getAnnotatableArgument(
methodCallExpression);
if (annotatableArgument != null) {
final InspectionGadgetsFix fix =
createAddAnnotationFix(annotatableArgument);
result.add(fix);
}
return result.toArray(new InspectionGadgetsFix[result.size()]);
}
private static DelegatingFix createAddAnnotationFix(PsiModifierListOwner annotatableQualifier) {
return new DelegatingFix(new AddAnnotationPsiFix(
AnnotationUtil.NON_NLS, annotatableQualifier,PsiNameValuePair.EMPTY_ARRAY));
}
@Override
public BaseInspectionVisitor buildVisitor() {
return new StringEqualsIgnoreCaseVisitor();
}
private static class StringEqualsIgnoreCaseVisitor
extends BaseInspectionVisitor {
@Override
public void visitMethodCallExpression(
@NotNull PsiMethodCallExpression expression) {
super.visitMethodCallExpression(expression);
final PsiReferenceExpression methodExpression =
expression.getMethodExpression();
final String methodName = methodExpression.getReferenceName();
if (!HardcodedMethodConstants.EQUALS_IGNORE_CASE.equals(
methodName)) {
return;
}
final PsiMethod method = expression.resolveMethod();
if (method == null) {
return;
}
final PsiParameterList parameterList = method.getParameterList();
if (parameterList.getParametersCount() != 1) {
return;
}
final PsiParameter[] parameters = parameterList.getParameters();
final PsiType parameterType = parameters[0].getType();
if (!TypeUtils.isJavaLangString(parameterType)) {
return;
}
final PsiClass aClass = method.getContainingClass();
if (aClass == null) {
return;
}
final String className = aClass.getQualifiedName();
if (!CommonClassNames.JAVA_LANG_STRING.equals(className)) {
return;
}
final PsiExpression qualifier =
methodExpression.getQualifierExpression();
if (NonNlsUtils.isNonNlsAnnotated(qualifier)) {
return;
}
final PsiExpressionList argumentList = expression.getArgumentList();
final PsiExpression[] arguments = argumentList.getExpressions();
if (arguments.length != 1) {
return;
}
if (NonNlsUtils.isNonNlsAnnotated(arguments[0])) {
return;
}
registerMethodCallError(expression, expression);
}
}
}
@@ -0,0 +1,9 @@
<html>
<body>
Reports any call of <b>equals()</b>, <b>equalsIgnoreCase()</b>, <b>compareTo()</b> or <b>compareToIgnoreCase()</b> on <b>String</b> objects.
Such calls are usually incorrect in an internationalized environment.
<!-- tooltip end -->
<p>
</body>
</html>
@@ -1,9 +0,0 @@
<html>
<body>
Reports any call of <b>compareTo()</b> on <b>String</b> objects. Such calls are usually
incorrect in an internationalized environment.
<!-- tooltip end -->
<p>
</body>
</html>
@@ -1,9 +0,0 @@
<html>
<body>
Reports any call of <b>equals()</b> on <b>String</b> objects. Such calls are usually
incorrect in an internationalized environment.
<!-- tooltip end -->
<p>
</body>
</html>
@@ -1,9 +0,0 @@
<html>
<body>
Reports any call of <b>equalsIgnoreCase()</b> on <b>String</b> objects. Such calls are usually
incorrect in an internationalized environment.
<!-- tooltip end -->
<p>
</body>
</html>
@@ -1,13 +0,0 @@
package com.siyeh.igtest.internationalization;
public class StringCompareToInspection
{
public StringCompareToInspection()
{
}
public void foo()
{
"foo".compareTo("bar");
}
}
@@ -1,13 +0,0 @@
package com.siyeh.igtest.internationalization;
public class StringEqualsIgnoreCaseInspection
{
public StringEqualsIgnoreCaseInspection()
{
}
public void foo()
{
"foo".equalsIgnoreCase("bar");
}
}
@@ -1,13 +0,0 @@
package com.siyeh.igtest.internationalization;
public class StringEqualsInspection
{
public StringEqualsInspection()
{
}
public void foo()
{
"foo".equals("bar");
}
}
@@ -0,0 +1,18 @@
class CallToSuspiciousStringMethod {
void m(String a, String b) {
a.<warning descr="'String.equals()' called in internationalized context">equals</warning>(b);
a.<warning descr="'String.equalsIgnoreCase()' called in internationalized context">equalsIgnoreCase</warning>(b);
a.<warning descr="'String.compareTo()' called in internationalized context">compareTo</warning>(b);
a.<warning descr="'String.compareToIgnoreCase()' called in internationalized context">compareToIgnoreCase</warning>(b);
}
@SuppressWarnings({"CallToStringCompareTo", "CallToStringEquals", "CallToStringEqualsIgnoreCase"})
void n(String a, String b) {
a.equals(b);
a.equalsIgnoreCase(b);
a.compareTo(b);
//noinspection CallToSuspiciousStringMethod
a.compareToIgnoreCase(b);
}
}
@@ -0,0 +1,36 @@
/*
* 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.internationalization;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.siyeh.ig.LightInspectionTestCase;
import org.jetbrains.annotations.Nullable;
/**
* @author Bas Leijdekkers
*/
public class CallToSuspiciousStringMethodInspectionTest extends LightInspectionTestCase {
public void testCallToSuspiciousStringMethod() {
doTest();
}
@Nullable
@Override
protected InspectionProfileEntry getInspection() {
return new CallToSuspiciousStringMethodInspection();
}
}