diff --git a/java/java-analysis-impl/src/messages/QuickFixBundle.properties b/java/java-analysis-impl/src/messages/QuickFixBundle.properties index a0666fc51848..41ee3c90bd63 100644 --- a/java/java-analysis-impl/src/messages/QuickFixBundle.properties +++ b/java/java-analysis-impl/src/messages/QuickFixBundle.properties @@ -301,6 +301,8 @@ java.8.collection.removeif.inspection.description=The loop can be replaced with java.8.collection.removeif.inspection.fix.name=Replace the loop with 'Collection.removeIf' java.8.list.sort.inspection.description=Collections.sort could be replaced with List.sort java.8.list.sort.inspection.fix.name=Replace with List.sort +java.8.list.replaceall.inspection.description=The loop can be replaced with 'List.replaceAll' +java.8.list.replaceall.inspection.fix.name=Replace the loop with 'List.replaceAll' wrap.with.optional.parameter.text=Wrap {0, choice, 1#1st|2#2nd|3#3rd|4#{0,number}th} argument using ''java.util.Optional'' wrap.with.optional.single.parameter.text=Wrap using 'java.util.Optional' diff --git a/java/java-impl/src/META-INF/JavaPlugin.xml b/java/java-impl/src/META-INF/JavaPlugin.xml index 18e7f31cb603..330cfa1f6783 100644 --- a/java/java-impl/src/META-INF/JavaPlugin.xml +++ b/java/java-impl/src/META-INF/JavaPlugin.xml @@ -1575,6 +1575,11 @@ groupKey="group.names.language.level.specific.issues.and.migration.aids8" enabledByDefault="true" level="WARNING" implementationClass="com.intellij.codeInspection.java18api.Java8CollectionRemoveIfInspection" key="inspection.java.8.collection.remove.if.display.name" bundle="messages.JavaBundle"/> + variableAllowedPredicate = variable -> PsiEquivalenceUtil.areElementsEquivalent(variable, loop.getCounter()); + if (!LambdaGenerationUtil.canBeUncheckedLambda(forStatement.getBody(), variableAllowedPredicate)) return null; + PsiMethodCallExpression listGetCall = getListGetCall(body); + if (listGetCall == null) return null; + Ref counter = new Ref<>(0); + PsiTreeUtil.processElements(body, e -> { + if (ExpressionUtils.isReferenceTo(ObjectUtils.tryCast(e, PsiExpression.class), loop.getCounter())) { + counter.set(counter.get() + 1); + } + return counter.get() <= 2; + }); + if (counter.get() != 2) return null; + return UseBulkOperationInspection.findIterableForIndexedLoop(loop, listGetCall); + } + + @Nullable + private static PsiMethodCallExpression getListGetCall(@NotNull PsiStatement body) { + Ref getElementExpression = new Ref<>(); + boolean isSoleGelElementExpression = PsiTreeUtil.processElements(body, e -> { + PsiMethodCallExpression maybeListGet = ObjectUtils.tryCast(e, PsiMethodCallExpression.class); + return !LIST_GET.test(maybeListGet) || getElementExpression.setIfNull(maybeListGet); + }) && !getElementExpression.isNull(); + if (!isSoleGelElementExpression) return null; + return getElementExpression.get(); + } + + private static class ReplaceWithReplaceAllQuickFix implements LocalQuickFix { + private final SmartPsiElementPointer myCallPointer; + + private ReplaceWithReplaceAllQuickFix(@NotNull PsiMethodCallExpression call) { + SmartPointerManager manager = SmartPointerManager.getInstance(call.getProject()); + myCallPointer = manager.createSmartPsiElementPointer(call); + } + + @Nls + @NotNull + @Override + public String getFamilyName() { + return QuickFixBundle.message("java.8.list.replaceall.inspection.fix.name"); + } + + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + PsiMethodCallExpression call = myCallPointer.getElement(); + if (call == null) return; + PsiExpression qualifier = ExpressionUtils.getEffectiveQualifier(call.getMethodExpression()); + if (qualifier == null) return; + PsiExpression iterable = findIterable(call); + if (iterable == null) return; + PsiElement parent = RefactoringUtil.getParentStatement(iterable, false); + if (parent == null) return; + CommentTracker ct = new CommentTracker(); + String bulkMethodParameterText = calculateReplaceAllLambdaExpressionText(call, ct); + String text = ct.text(qualifier) + ".replaceAll(" + bulkMethodParameterText + ");"; + PsiElement result = ct.replaceAndRestoreComments(parent, text); + LambdaCanBeMethodReferenceInspection.replaceAllLambdasWithMethodReferences(result); + simplifyToExpressionLambda(result); + result = JavaCodeStyleManager.getInstance(project).shortenClassReferences(result); + CodeStyleManager.getInstance(project).reformat(result); + } + + @Nullable + private static String calculateReplaceAllLambdaExpressionText(PsiMethodCallExpression listSetCall, CommentTracker ct) { + PsiForStatement forStatement = PsiTreeUtil.getParentOfType(listSetCall, PsiForStatement.class); + if (forStatement == null) return null; + PsiStatement body = forStatement.getBody(); + if (body == null) return null; + PsiMethodCallExpression listGetCall = getListGetCall(body); + if (listGetCall == null) return null; + PsiDeclarationStatement declarationStatement = PsiTreeUtil.getParentOfType(listGetCall, PsiDeclarationStatement.class); + PsiLocalVariable var = IteratorDeclaration.getDeclaredVariable(declarationStatement); + String paramName; + if (var != null && var.getInitializer() == listGetCall) { + paramName = var.getName(); + new CommentTracker().deleteAndRestoreComments(declarationStatement); + } + else { + paramName = new VariableNameGenerator(body, VariableKind.PARAMETER).byExpression(listGetCall).generate(true); + PsiElement element = new CommentTracker().replaceAndRestoreComments(listGetCall, paramName); + PsiLocalVariable variable = + IteratorDeclaration.getDeclaredVariable(PsiTreeUtil.getParentOfType(element, PsiDeclarationStatement.class)); + inlineVariable(variable); + } + String text = "return " + ct.textWithComments(listSetCall.getArgumentList().getExpressions()[1]) + ";"; + PsiElement result = new CommentTracker().replaceAndRestoreComments(listSetCall.getParent(), text); + String codeBlockText = body instanceof PsiBlockStatement ? ct.text(body) : "{ " + ct.text(result) + " }"; + return paramName + " -> " + codeBlockText; + } + + private static void inlineVariable(@Nullable PsiLocalVariable variable) { + if (variable == null) return; + final Collection references = ReferencesSearch.search(variable).findAll(); + PsiExpression initializer = variable.getInitializer(); + if (initializer == null || references.size() != 1) return; + InlineUtil.inlineVariable(variable, initializer, (PsiJavaCodeReferenceElement)references.iterator().next()); + variable.delete(); + } + + private static void simplifyToExpressionLambda(@NotNull PsiElement element) { + PsiExpressionStatement expressionStatement = ObjectUtils.tryCast(element, PsiExpressionStatement.class); + if (expressionStatement == null) return; + PsiMethodCallExpression call = ObjectUtils.tryCast(expressionStatement.getExpression(), PsiMethodCallExpression.class); + if (call == null) return; + PsiExpression arg = ArrayUtil.getFirstElement(call.getArgumentList().getExpressions()); + PsiLambdaExpression lambdaExpression = ObjectUtils.tryCast(arg, PsiLambdaExpression.class); + if (lambdaExpression == null) return; + LambdaRefactoringUtil.simplifyToExpressionLambda(lambdaExpression); + } + } +} diff --git a/java/java-impl/src/com/intellij/codeInspection/util/IteratorDeclaration.java b/java/java-impl/src/com/intellij/codeInspection/util/IteratorDeclaration.java index 6cf45cf08ae9..98d51a25ffa4 100644 --- a/java/java-impl/src/com/intellij/codeInspection/util/IteratorDeclaration.java +++ b/java/java-impl/src/com/intellij/codeInspection/util/IteratorDeclaration.java @@ -73,7 +73,7 @@ public final class IteratorDeclaration extends IterableTraversal { } @Nullable - private static PsiLocalVariable getDeclaredVariable(PsiStatement statement) { + public static PsiLocalVariable getDeclaredVariable(PsiStatement statement) { if (!(statement instanceof PsiDeclarationStatement)) return null; PsiDeclarationStatement declaration = (PsiDeclarationStatement)statement; PsiElement[] elements = declaration.getDeclaredElements(); diff --git a/java/java-impl/src/inspectionDescriptions/Java8ListReplaceAll.html b/java/java-impl/src/inspectionDescriptions/Java8ListReplaceAll.html new file mode 100644 index 000000000000..5d49d3f5d886 --- /dev/null +++ b/java/java-impl/src/inspectionDescriptions/Java8ListReplaceAll.html @@ -0,0 +1,20 @@ + + +Reports loops which can be collapsed into a single Liar.replaceAll call. +

Example:

+

+  for (int i = 0; i < strings.size(); i++) {
+    String str = strings.get(i).toLowerCase();
+    strings.set(i, str);
+  }
+
+

After the quick-fix is applied:

+

+  strings.replaceAll(String::toLowerCase);
+
+ +

+ This inspection only reports if the language level of the project or module is 8 or higher. +

+ + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/afterChainedMethodCalls.java b/java/java-tests/testData/inspection/java8ListReplaceAll/afterChainedMethodCalls.java new file mode 100644 index 000000000000..c81030cf6107 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/afterChainedMethodCalls.java @@ -0,0 +1,8 @@ +// "Replace the loop with 'List.replaceAll'" "true" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + strings.replaceAll(s -> s.trim().toLowerCase()); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/afterConstructor.java b/java/java-tests/testData/inspection/java8ListReplaceAll/afterConstructor.java new file mode 100644 index 000000000000..100032339ca3 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/afterConstructor.java @@ -0,0 +1,8 @@ +// "Replace the loop with 'List.replaceAll'" "true" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + strings.replaceAll(String::new); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/afterForLoopWithoutBody.java b/java/java-tests/testData/inspection/java8ListReplaceAll/afterForLoopWithoutBody.java new file mode 100644 index 000000000000..bf21e5b9b6c0 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/afterForLoopWithoutBody.java @@ -0,0 +1,12 @@ +// "Replace the loop with 'List.replaceAll'" "true" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + strings.replaceAll(this::modifyString); + } + + String modifyString(String str) { + return str.repeat(2); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/afterInstanceMethod1.java b/java/java-tests/testData/inspection/java8ListReplaceAll/afterInstanceMethod1.java new file mode 100644 index 000000000000..bf21e5b9b6c0 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/afterInstanceMethod1.java @@ -0,0 +1,12 @@ +// "Replace the loop with 'List.replaceAll'" "true" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + strings.replaceAll(this::modifyString); + } + + String modifyString(String str) { + return str.repeat(2); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/afterInstanceMethod2.java b/java/java-tests/testData/inspection/java8ListReplaceAll/afterInstanceMethod2.java new file mode 100644 index 000000000000..58f31857f555 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/afterInstanceMethod2.java @@ -0,0 +1,8 @@ +// "Replace the loop with 'List.replaceAll'" "true" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + strings.replaceAll(String::trim); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/afterIntroducedModifiedVar.java b/java/java-tests/testData/inspection/java8ListReplaceAll/afterIntroducedModifiedVar.java new file mode 100644 index 000000000000..f460d1647d31 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/afterIntroducedModifiedVar.java @@ -0,0 +1,8 @@ +// "Replace the loop with 'List.replaceAll'" "true" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + strings.replaceAll(String::toLowerCase); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/afterIntroducedVar.java b/java/java-tests/testData/inspection/java8ListReplaceAll/afterIntroducedVar.java new file mode 100644 index 000000000000..67ed8c3ca806 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/afterIntroducedVar.java @@ -0,0 +1,12 @@ +// "Replace the loop with 'List.replaceAll'" "true" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + strings.replaceAll(Main::modifyString); + } + + static String modifyString(String str) { + return str.repeat(2); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/afterNoModify1.java b/java/java-tests/testData/inspection/java8ListReplaceAll/afterNoModify1.java new file mode 100644 index 000000000000..5bac8307711a --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/afterNoModify1.java @@ -0,0 +1,8 @@ +// "Replace the loop with 'List.replaceAll'" "true" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + strings.replaceAll(e -> e); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/afterNoModify2.java b/java/java-tests/testData/inspection/java8ListReplaceAll/afterNoModify2.java new file mode 100644 index 000000000000..5bac8307711a --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/afterNoModify2.java @@ -0,0 +1,8 @@ +// "Replace the loop with 'List.replaceAll'" "true" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + strings.replaceAll(e -> e); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/afterStaticMethod.java b/java/java-tests/testData/inspection/java8ListReplaceAll/afterStaticMethod.java new file mode 100644 index 000000000000..67ed8c3ca806 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/afterStaticMethod.java @@ -0,0 +1,12 @@ +// "Replace the loop with 'List.replaceAll'" "true" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + strings.replaceAll(Main::modifyString); + } + + static String modifyString(String str) { + return str.repeat(2); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/afterSuper.java b/java/java-tests/testData/inspection/java8ListReplaceAll/afterSuper.java new file mode 100644 index 000000000000..1ed5707dae06 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/afterSuper.java @@ -0,0 +1,13 @@ +// "Replace the loop with 'List.replaceAll'" "true" +import java.util.ArrayList; +import java.util.List; + +class Main extends ArrayList { + void modifyStrings(List strings) { + super.replaceAll(Main::modifyString); + } + + static String modifyString(String str) { + return str.repeat(2); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/afterThis.java b/java/java-tests/testData/inspection/java8ListReplaceAll/afterThis.java new file mode 100644 index 000000000000..94b02cb04edb --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/afterThis.java @@ -0,0 +1,13 @@ +// "Replace the loop with 'List.replaceAll'" "true" +import java.util.ArrayList; +import java.util.List; + +class Main extends ArrayList { + void modifyStrings(List strings) { + this.replaceAll(Main::modifyString); + } + + static String modifyString(String str) { + return str.repeat(2); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/beforeAllBreak.java b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeAllBreak.java new file mode 100644 index 000000000000..6657092c84c8 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeAllBreak.java @@ -0,0 +1,11 @@ +// "Replace the loop with 'List.replaceAll'" "false" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + for (int i = 0; i < strings.size(); i++) { + if (Math.random() > 0.5) break; + strings.set(i, strings.get(i).toLowerCase()); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/beforeChainedMethodCalls.java b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeChainedMethodCalls.java new file mode 100644 index 000000000000..4a64ece8daf2 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeChainedMethodCalls.java @@ -0,0 +1,10 @@ +// "Replace the loop with 'List.replaceAll'" "true" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + for (int i = 0; i < strings.size(); i++) { + strings.set(i, strings.get(i).trim().toLowerCase()); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/beforeCheckedException.java b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeCheckedException.java new file mode 100644 index 000000000000..2aee0ebf0d74 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeCheckedException.java @@ -0,0 +1,15 @@ +// "Replace the loop with 'List.replaceAll'" "false" +import java.io.IOException; +import java.util.*; + +class Main extends ArrayList { + void modifyStrings(List strings) throws IOException { + for (int i = 0; i < strings.size(); i++) { + strings.set(i, modifyString(strings.get(i))); + } + } + + static String modifyString(String str) throws IOException { + return str.repeat(2); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/beforeConstructor.java b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeConstructor.java new file mode 100644 index 000000000000..86d9bc365a65 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeConstructor.java @@ -0,0 +1,10 @@ +// "Replace the loop with 'List.replaceAll'" "true" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + for (int i = 0; i < strings.size(); i++) { + strings.set(i, new String(strings.get(i))); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/beforeContinue.java b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeContinue.java new file mode 100644 index 000000000000..dc4d44bf182d --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeContinue.java @@ -0,0 +1,11 @@ +// "Replace the loop with 'List.replaceAll'" "false" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + for (int i = 0; i < strings.size(); i++) { + if (Math.random() > 0.5) continue; + strings.set(i, strings.get(i).toLowerCase()); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/beforeDifferentIndices.java b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeDifferentIndices.java new file mode 100644 index 000000000000..ebad3add0f97 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeDifferentIndices.java @@ -0,0 +1,11 @@ +// "Replace the loop with 'List.replaceAll'" "false" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + int j = 0; + for (int i = 0; i < strings.size(); i++) { + strings.set(i, strings.get(j)); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/beforeDifferentIndices2.java b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeDifferentIndices2.java new file mode 100644 index 000000000000..b763f4b834e5 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeDifferentIndices2.java @@ -0,0 +1,11 @@ +// "Replace the loop with 'List.replaceAll'" "false" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + int j = 0; + for (int i = 0; i < strings.size(); i++) { + strings.set(j, strings.get(j)); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/beforeDifferentLists1.java b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeDifferentLists1.java new file mode 100644 index 000000000000..6abbc5de525a --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeDifferentLists1.java @@ -0,0 +1,10 @@ +// "Replace the loop with 'List.replaceAll'" "false" +import java.util.*; + +class Main { + void modifyStrings(List strings1, List strings2) { + for (int i = 0; i < strings1.size(); i++) { + strings2.set(i, strings1.get(i)); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/beforeDifferentLists2.java b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeDifferentLists2.java new file mode 100644 index 000000000000..6d32157fcd86 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeDifferentLists2.java @@ -0,0 +1,10 @@ +// "Replace the loop with 'List.replaceAll'" "false" +import java.util.*; + +class Main { + void modifyStrings(List strings1, List strings2) { + for (int i = 0; i < strings1.size(); i++) { + strings1.set(i, strings2.get(i)); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/beforeForLoopWithoutBody.java b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeForLoopWithoutBody.java new file mode 100644 index 000000000000..f581a82f1872 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeForLoopWithoutBody.java @@ -0,0 +1,13 @@ +// "Replace the loop with 'List.replaceAll'" "true" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + for (int i = 0; i < strings.size(); i++) + strings.set(i, modifyString(strings.get(i))); + } + + String modifyString(String str) { + return str.repeat(2); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/beforeInstanceMethod1.java b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeInstanceMethod1.java new file mode 100644 index 000000000000..7850e8f84356 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeInstanceMethod1.java @@ -0,0 +1,14 @@ +// "Replace the loop with 'List.replaceAll'" "true" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + for (int i = 0; i < strings.size(); i++) { + strings.set(i, modifyString(strings.get(i))); + } + } + + String modifyString(String str) { + return str.repeat(2); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/beforeInstanceMethod2.java b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeInstanceMethod2.java new file mode 100644 index 000000000000..1e8f05d0861c --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeInstanceMethod2.java @@ -0,0 +1,10 @@ +// "Replace the loop with 'List.replaceAll'" "true" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + for (int i = 0; i < strings.size(); i++) { + strings.set(i, strings.get(i).trim()); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/beforeIntroducedModifiedVar.java b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeIntroducedModifiedVar.java new file mode 100644 index 000000000000..a865b650a7b1 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeIntroducedModifiedVar.java @@ -0,0 +1,11 @@ +// "Replace the loop with 'List.replaceAll'" "true" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + for (int i = 0; i < strings.size(); i++) { + String str = strings.get(i).toLowerCase(); + strings.set(i, str); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/beforeIntroducedVar.java b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeIntroducedVar.java new file mode 100644 index 000000000000..559732d23d4a --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeIntroducedVar.java @@ -0,0 +1,15 @@ +// "Replace the loop with 'List.replaceAll'" "true" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + for (int i = 0; i < strings.size(); i++) { + String str = strings.get(i); + strings.set(i, modifyString(str)); + } + } + + static String modifyString(String str) { + return str.repeat(2); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/beforeNoModify1.java b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeNoModify1.java new file mode 100644 index 000000000000..31565444a5d6 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeNoModify1.java @@ -0,0 +1,10 @@ +// "Replace the loop with 'List.replaceAll'" "true" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + for (int i = 0; i < strings.size(); i++) { + strings.set(i, strings.get(i)); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/beforeNoModify2.java b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeNoModify2.java new file mode 100644 index 000000000000..31565444a5d6 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeNoModify2.java @@ -0,0 +1,10 @@ +// "Replace the loop with 'List.replaceAll'" "true" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + for (int i = 0; i < strings.size(); i++) { + strings.set(i, strings.get(i)); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/beforeNotEffectivelyFinal.java b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeNotEffectivelyFinal.java new file mode 100644 index 000000000000..81082fb5d9ec --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeNotEffectivelyFinal.java @@ -0,0 +1,16 @@ +// "Replace the loop with 'List.replaceAll'" "false" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + int j = 0; + for (int i = 0; i < strings.size(); i++) { + j++; + strings.set(i, modifyString(strings.get(i))); + } + } + + static String modifyString(String str) { + return str.repeat(2); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/beforeReturn.java b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeReturn.java new file mode 100644 index 000000000000..a6e4fe9f13a0 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeReturn.java @@ -0,0 +1,11 @@ +// "Replace the loop with 'List.replaceAll'" "false" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + for (int i = 0; i < strings.size(); i++) { + if (Math.random() > 0.5) return; + strings.set(i, strings.get(i).toLowerCase()); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/beforeSetNotLastStatement.java b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeSetNotLastStatement.java new file mode 100644 index 000000000000..ca0175059b55 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeSetNotLastStatement.java @@ -0,0 +1,11 @@ +// "Replace the loop with 'List.replaceAll'" "false" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + for (int i = 0; i < strings.size(); i++) { + strings.set(i, strings.get(i).toLowerCase()); + System.out.println("bar"); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/beforeStaticMethod.java b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeStaticMethod.java new file mode 100644 index 000000000000..c22b52b94824 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeStaticMethod.java @@ -0,0 +1,14 @@ +// "Replace the loop with 'List.replaceAll'" "true" +import java.util.*; + +class Main { + void modifyStrings(List strings) { + for (int i = 0; i < strings.size(); i++) { + strings.set(i, modifyString(strings.get(i))); + } + } + + static String modifyString(String str) { + return str.repeat(2); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/beforeSuper.java b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeSuper.java new file mode 100644 index 000000000000..1d0f8d99c893 --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeSuper.java @@ -0,0 +1,15 @@ +// "Replace the loop with 'List.replaceAll'" "true" +import java.util.ArrayList; +import java.util.List; + +class Main extends ArrayList { + void modifyStrings(List strings) { + for (int i = 0; i < super.size(); i++) { + super.set(i, modifyString(super.get(i))); + } + } + + static String modifyString(String str) { + return str.repeat(2); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/java8ListReplaceAll/beforeThis.java b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeThis.java new file mode 100644 index 000000000000..cef3d5559e6f --- /dev/null +++ b/java/java-tests/testData/inspection/java8ListReplaceAll/beforeThis.java @@ -0,0 +1,15 @@ +// "Replace the loop with 'List.replaceAll'" "true" +import java.util.ArrayList; +import java.util.List; + +class Main extends ArrayList { + void modifyStrings(List strings) { + for (int i = 0; i < this.size(); i++) { + this.set(i, modifyString(this.get(i))); + } + } + + static String modifyString(String str) { + return str.repeat(2); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/Java8ListReplaceAllInspectionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/Java8ListReplaceAllInspectionTest.java new file mode 100644 index 000000000000..3f95f3ef097e --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/Java8ListReplaceAllInspectionTest.java @@ -0,0 +1,19 @@ +// Copyright 2000-2021 JetBrains s.r.o. and contributors. 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.codeInspection; + +import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase; +import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.codeInspection.java18api.Java8ListReplaceAllInspection; +import org.jetbrains.annotations.NotNull; + +public class Java8ListReplaceAllInspectionTest extends LightQuickFixParameterizedTestCase { + @Override + protected LocalInspectionTool @NotNull [] configureLocalInspectionTools() { + return new LocalInspectionTool[]{new Java8ListReplaceAllInspection()}; + } + + @Override + protected String getBasePath() { + return "/inspection/java8ListReplaceAll"; + } +}