diff --git a/java/java-tests/testData/inspection/redundantStringOperation/EmptyStringArgument.java b/java/java-tests/testData/inspection/redundantStringOperation/EmptyStringArgument.java new file mode 100644 index 000000000000..12333e4f1e56 --- /dev/null +++ b/java/java-tests/testData/inspection/redundantStringOperation/EmptyStringArgument.java @@ -0,0 +1,13 @@ +class Main { + void foo1() { + System.out.println(""); + } + + void foo2() { + StringBuilder stringBuilder = new StringBuilder(""); + } + + void foo3() { + StringBuffer stringBuffer = new StringBuffer(""); + } +} diff --git a/java/java-tests/testData/inspection/redundantStringOperation/StringLengthArgument.java b/java/java-tests/testData/inspection/redundantStringOperation/StringLengthArgument.java new file mode 100644 index 000000000000..6b5822656f14 --- /dev/null +++ b/java/java-tests/testData/inspection/redundantStringOperation/StringLengthArgument.java @@ -0,0 +1,9 @@ +class Main { + void foo1(String str) { + str.lastIndexOf("42", str.length()); + } + + void foo2(String str) { + str.lastIndexOf("42", str.length() - 1); + } +} diff --git a/java/java-tests/testData/inspection/redundantStringOperation/ZeroArgument.java b/java/java-tests/testData/inspection/redundantStringOperation/ZeroArgument.java new file mode 100644 index 000000000000..8f4b8d261804 --- /dev/null +++ b/java/java-tests/testData/inspection/redundantStringOperation/ZeroArgument.java @@ -0,0 +1,9 @@ +class Main { + void foo1(String str) { + str.indexOf("42", 0); + } + + void foo2(String str) { + str.startsWith("42", 0); + } +} diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/RedundantStringOperationInspectionFixTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/RedundantStringOperationInspectionFixTest.java new file mode 100644 index 000000000000..69c6d57ae13e --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/RedundantStringOperationInspectionFixTest.java @@ -0,0 +1,20 @@ +// Copyright 2000-2017 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.intellij.java.codeInsight.daemon.quickFix; + +import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase; +import com.intellij.codeInspection.LocalInspectionTool; +import com.siyeh.ig.redundancy.RedundantStringOperationInspection; +import org.jetbrains.annotations.NotNull; + + +public class RedundantStringOperationInspectionFixTest extends LightQuickFixParameterizedTestCase { + @Override + protected LocalInspectionTool @NotNull [] configureLocalInspectionTools() { + return new LocalInspectionTool[]{new RedundantStringOperationInspection()}; + } + + @Override + protected String getBasePath() { + return "/codeInsight/daemonCodeAnalyzer/quickFix/redundantStringOperation"; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/RedundantStringOperationInspectionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/RedundantStringOperationInspectionTest.java index 156454a2c682..633c6e5e596f 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/RedundantStringOperationInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/RedundantStringOperationInspectionTest.java @@ -1,20 +1,25 @@ -// Copyright 2000-2017 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. +// Copyright 2000-2020 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.intellij.java.codeInsight.daemon.quickFix; -import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase; -import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.JavaTestUtil; +import com.intellij.codeInspection.InspectionProfileEntry; +import com.siyeh.ig.LightJavaInspectionTestCase; import com.siyeh.ig.redundancy.RedundantStringOperationInspection; -import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; - -public class RedundantStringOperationInspectionTest extends LightQuickFixParameterizedTestCase { +public class RedundantStringOperationInspectionTest extends LightJavaInspectionTestCase { + @Nullable @Override - protected LocalInspectionTool @NotNull [] configureLocalInspectionTools() { - return new LocalInspectionTool[]{new RedundantStringOperationInspection()}; + protected InspectionProfileEntry getInspection() { + return new RedundantStringOperationInspection(); } + public void testEmptyStringArgument() {doTest();} + public void testStringLengthArgument() {doTest();} + public void testZeroArgument() {doTest();} + @Override protected String getBasePath() { - return "/codeInsight/daemonCodeAnalyzer/quickFix/redundantStringOperation"; + return JavaTestUtil.getRelativeJavaTestDataPath() + "/inspection/redundantStringOperation/"; } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/resources/messages/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/resources/messages/InspectionGadgetsBundle.properties index a63337007874..cc07b065b7b8 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/resources/messages/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/resources/messages/InspectionGadgetsBundle.properties @@ -2193,7 +2193,9 @@ inspection.redundant.string.operation.display.name=Redundant String operation inspection.redundant.string.remove.fix.name=Remove redundant ''{0}()'' call inspection.redundant.string.fix.family.name=Remove redundant call inspection.redundant.string.call.message=Call to #ref() is redundant #loc -inspection.redundant.string.argument.message=Redundant argument +inspection.redundant.empty.string.argument.message=Unnecessary empty string argument +inspection.redundant.string.length.argument.message=Unnecessary string length argument +inspection.redundant.zero.argument.message=Unnecessary zero argument inspection.redundant.string.remove.argument.fix.name=Remove argument inspection.redundant.string.intern.on.constant.message=Call to #ref() on compile-time constant is unnecessary #loc inspection.redundant.string.constructor.message=#ref is redundant #loc diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/redundancy/RedundantStringOperationInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/redundancy/RedundantStringOperationInspection.java index 62d647cc50e8..a92232cf20a2 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/redundancy/RedundantStringOperationInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/redundancy/RedundantStringOperationInspection.java @@ -95,7 +95,8 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns .register(STRING_BUILDER_APPEND, this::getAppendProblem) .register(STRING_BUILDER_TO_STRING, this::getRedundantStringBuilderToStringProblem) .register(STRING_INTERN, this::getInternProblem) - .register(PRINTSTREAM_PRINTLN, call -> getRedundantArgumentProblem(getSingleEmptyStringArgument(call))) + .register(PRINTSTREAM_PRINTLN, call -> + getRedundantArgumentProblem(getSingleEmptyStringArgument(call), "inspection.redundant.empty.string.argument.message")) .register(METHOD_WITH_REDUNDANT_ZERO_AS_SECOND_PARAMETER, this::getRedundantZeroAsSecondParameterProblem) .register(STRING_LAST_INDEX_OF, this::getLastIndexOfProblem) .register(STRING_IS_EMPTY, this::getRedundantCaseChangeProblem) @@ -125,7 +126,8 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns PsiJavaCodeReferenceElement classRef = expression.getClassReference(); ProblemDescriptor descriptor = null; if (ConstructionUtils.isReferenceTo(classRef, JAVA_LANG_STRING_BUILDER, JAVA_LANG_STRING_BUFFER)) { - descriptor = getRedundantArgumentProblem(getSingleEmptyStringArgument(expression)); + String key = "inspection.redundant.empty.string.argument.message"; + descriptor = getRedundantArgumentProblem(getSingleEmptyStringArgument(expression), key); } else if (ConstructionUtils.isReferenceTo(classRef, JAVA_LANG_STRING) && !myInspection.ignoreStringConstructor) { descriptor = getStringConstructorProblem(expression); @@ -422,26 +424,28 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns stripped = binOp.getLOperand(); } } - return isLengthOf(stripped, call.getMethodExpression().getQualifierExpression()) ? getRedundantArgumentProblem(secondArg) : null; + PsiExpression qualifier = call.getMethodExpression().getQualifierExpression(); + if (!isLengthOf(stripped, qualifier)) return null; + return getRedundantArgumentProblem(secondArg, "inspection.redundant.string.length.argument.message"); } @Nullable private ProblemDescriptor getRedundantZeroAsSecondParameterProblem(PsiMethodCallExpression call) { PsiExpression secondArg = call.getArgumentList().getExpressions()[1]; if (ExpressionUtils.isLiteral(PsiUtil.skipParenthesizedExprDown(secondArg), 0)) { - return getRedundantArgumentProblem(secondArg); + return getRedundantArgumentProblem(secondArg, "inspection.redundant.zero.argument.message"); } return null; } @Nullable - private ProblemDescriptor getRedundantArgumentProblem(@Nullable PsiExpression argument) { + private ProblemDescriptor getRedundantArgumentProblem(@Nullable PsiExpression argument, + @NotNull @PropertyKey(resourceBundle = BUNDLE) String key) { if (argument == null) return null; LocalQuickFix fix = new DeleteElementFix(argument, InspectionGadgetsBundle.message("inspection.redundant.string.remove.argument.fix.name")); return myManager.createProblemDescriptor(argument, - InspectionGadgetsBundle.message( - "inspection.redundant.string.argument.message"), + InspectionGadgetsBundle.message(key), myIsOnTheFly, new LocalQuickFix[]{fix}, ProblemHighlightType.LIKE_UNUSED_SYMBOL); @@ -470,8 +474,9 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns } DeleteElementFix fix = new DeleteElementFix(args[1], InspectionGadgetsBundle.message("inspection.redundant.string.remove.argument.fix.name")); + final String message = InspectionGadgetsBundle.message("inspection.redundant.string.length.argument.message"); return myManager.createProblemDescriptor(args[1], - InspectionGadgetsBundle.message("inspection.redundant.string.argument.message"), + message, fix, ProblemHighlightType.LIKE_UNUSED_SYMBOL, myIsOnTheFly); }