diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/StreamApiMigrationInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/StreamApiMigrationInspection.java index d80ad0a3c919..615c8deb4188 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/StreamApiMigrationInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/StreamApiMigrationInspection.java @@ -145,9 +145,21 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo } if ((isArray || !isRawSubstitution(iteratedValueType, collectionClass)) && isCollectCall(tb, operations)) { boolean addAll = operations.isEmpty() && isAddAllCall(tb); - holder.registerProblem(iteratedValue, "Can be replaced with " + (addAll ? "addAll call" : "collect call"), + String methodName; + if(addAll) { + methodName = "addAll"; + } else { + PsiMethodCallExpression methodCallExpression = tb.getSingleMethodCall(); + if(methodCallExpression != null && extractReplaceableCollectionInitializer( + methodCallExpression.getMethodExpression().getQualifierExpression(), statement) != null) { + methodName = "collect"; + } else { + methodName = "forEach"; + } + } + holder.registerProblem(iteratedValue, "Can be replaced with " + methodName + " call", ProblemHighlightType.GENERIC_ERROR_OR_WARNING, - addAll ? new ReplaceWithAddAllFix() : new ReplaceWithCollectFix()); + new ReplaceWithCollectFix(methodName)); } // do not replace for(T e : arr) {} with Arrays.stream(arr).forEach(e -> {}) even if flag is set else if (!operations.isEmpty() || @@ -628,28 +640,37 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo return consumerClass != null ? psiFacade.getElementFactory().createType(consumerClass, variable.getType()) : null; } - private static class ReplaceWithCollectFix extends ReplaceWithCollectAbstractFix { - @Override - protected String getMethodName() { - return "collect"; + @Contract("null, _ -> null") + static PsiExpression extractReplaceableCollectionInitializer(PsiExpression qualifierExpression, PsiStatement foreachStatement) { + if (qualifierExpression instanceof PsiReferenceExpression) { + final PsiElement resolve = ((PsiReferenceExpression)qualifierExpression).resolve(); + if (resolve instanceof PsiLocalVariable) { + PsiLocalVariable var = (PsiLocalVariable)resolve; + if (isDeclarationJustBefore(var, foreachStatement)) { + final PsiExpression initializer = var.getInitializer(); + if (initializer instanceof PsiNewExpression) { + final PsiExpressionList argumentList = ((PsiNewExpression)initializer).getArgumentList(); + if (argumentList != null && argumentList.getExpressions().length == 0) { + return initializer; + } + } + } + } } + return null; } - private static class ReplaceWithAddAllFix extends ReplaceWithCollectAbstractFix { - @Override - protected String getMethodName() { - return "addAll"; + private static class ReplaceWithCollectFix extends MigrateToStreamFix { + final String myMethodName; + + protected ReplaceWithCollectFix(String methodName) { + myMethodName = methodName; } - } - - private abstract static class ReplaceWithCollectAbstractFix extends MigrateToStreamFix { - - protected abstract String getMethodName(); @NotNull @Override public String getFamilyName() { - return "Replace with " + getMethodName(); + return "Replace with " + myMethodName; } @Override @@ -682,29 +703,19 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo .add(createMapperFunctionalExpressionText(tb.getVariable(), methodCallExpression.getArgumentList().getExpressions()[0])); final StringBuilder builder = generateStream(iteratedValue, intermediateOps); - builder.append(".collect(java.util.stream.Collectors."); final PsiExpression qualifierExpression = methodCallExpression.getMethodExpression().getQualifierExpression(); - if (qualifierExpression instanceof PsiReferenceExpression) { - final PsiElement resolve = ((PsiReferenceExpression)qualifierExpression).resolve(); - if (resolve instanceof PsiLocalVariable) { - PsiLocalVariable var = (PsiLocalVariable)resolve; - if (isDeclarationJustBefore(var, foreachStatement)) { - final PsiExpression initializer = var.getInitializer(); - if (initializer instanceof PsiNewExpression) { - final PsiExpressionList argumentList = ((PsiNewExpression)initializer).getArgumentList(); - if (argumentList != null && argumentList.getExpressions().length == 0) { - final String callText = builder.toString() + createInitializerReplacementText(var.getType(), initializer) + ")"; - PsiElement result = initializer.replace(elementFactory.createExpressionFromText(callText, null)); - simplifyAndFormat(project, result); - foreachStatement.delete(); - return; - } - } - } - } + final PsiExpression initializer = extractReplaceableCollectionInitializer(qualifierExpression, foreachStatement); + if(initializer != null) { + String callText = builder.append(".collect(java.util.stream.Collectors.") + .append(createInitializerReplacementText(qualifierExpression.getType(), initializer)) + .append(")").toString(); + PsiElement result = initializer.replace(elementFactory.createExpressionFromText(callText, null)); + simplifyAndFormat(project, result); + foreachStatement.delete(); + return; } - final String qualifierText = qualifierExpression != null ? qualifierExpression.getText() : ""; - final String callText = StringUtil.getQualifiedName(qualifierText, "addAll(" + builder.toString() + "toList()));"); + final String qualifierText = qualifierExpression != null ? qualifierExpression.getText() : "this"; + final String callText = builder.append(".forEach(").append(qualifierText).append("::add);").toString(); PsiElement result = foreachStatement.replace(elementFactory.createStatementFromText(callText, foreachStatement)); simplifyAndFormat(project, result); } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListCompoundDeclaration.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListCompoundDeclaration.java index 1f86b4e27ac3..4996b5534ecd 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListCompoundDeclaration.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListCompoundDeclaration.java @@ -1,6 +1,5 @@ -// "Replace with collect" "true" +// "Replace with forEach" "true" import java.util.*; -import java.util.stream.Collectors; public class Collect { class Person { @@ -11,6 +10,6 @@ public class Collect { void collectNames(List persons){ List names = new ArrayList<>(), otherNames = new ArrayList<>(names); - names.addAll(persons.stream().map(Person::getName).collect(Collectors.toList())); + persons.stream().map(Person::getName).forEach(names::add); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListNonTrivialInitializer.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListNonTrivialInitializer.java index 641617eb642b..a0c2415f8da4 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListNonTrivialInitializer.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListNonTrivialInitializer.java @@ -1,6 +1,5 @@ -// "Replace with collect" "true" +// "Replace with forEach" "true" import java.util.*; -import java.util.stream.Collectors; public class Collect { class Person { @@ -15,6 +14,6 @@ public class Collect { void collectNames(List persons){ List names = foo(); - names.addAll(persons.stream().map(Person::getName).collect(Collectors.toList())); + persons.stream().map(Person::getName).forEach(names::add); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectHashSetFieldInitializer.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectHashSetFieldInitializer.java index edd903ab1769..5f9199f93a95 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectHashSetFieldInitializer.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectHashSetFieldInitializer.java @@ -1,6 +1,5 @@ -// "Replace with collect" "true" +// "Replace with forEach" "true" import java.util.*; -import java.util.stream.Collectors; public class Collect { class Person { @@ -11,6 +10,6 @@ public class Collect { Set names = new HashSet<>(); void collectNames(List persons){ - names.addAll(persons.stream().map(Person::getName).collect(Collectors.toList())); + persons.stream().map(Person::getName).forEach(names::add); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSelfCollection.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSelfCollection.java index 676c127d4a6f..0d98480e28ee 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSelfCollection.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSelfCollection.java @@ -1,6 +1,5 @@ -// "Replace with collect" "true" +// "Replace with forEach" "true" import java.util.*; -import java.util.stream.Collectors; public abstract class Collect implements Collection{ class Person { @@ -10,6 +9,6 @@ public abstract class Collect implements Collection{ } void collectNames(List persons){ - addAll(persons.stream().map(Person::getName).collect(Collectors.toList())); + persons.stream().map(Person::getName).forEach(this::add); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSetParameter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSetParameter.java index c8201c9b486e..fde0104c5737 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSetParameter.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectSetParameter.java @@ -1,6 +1,5 @@ -// "Replace with collect" "true" +// "Replace with forEach" "true" import java.util.*; -import java.util.stream.Collectors; public class Collect { class Person { @@ -10,6 +9,6 @@ public class Collect { } void collectNames(List persons, Set names){ - names.addAll(persons.stream().map(Person::getName).collect(Collectors.toList())); + persons.stream().map(Person::getName).forEach(names::add); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCompactFilterToMethodReference.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCompactFilterToMethodReference.java index 6f7ce3345cad..17f651523e81 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCompactFilterToMethodReference.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCompactFilterToMethodReference.java @@ -1,10 +1,9 @@ -// "Replace with collect" "true" +// "Replace with forEach" "true" import java.util.List; -import java.util.stream.Collectors; public class A { private void withStream(List stream, final List activeFilters) { - activeFilters.addAll(stream.stream().filter(String::isEmpty).collect(Collectors.toList())); + stream.stream().filter(String::isEmpty).forEach(activeFilters::add); } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterPrimitive.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterPrimitive.java index 00c2e47f78a8..8e464c70390f 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterPrimitive.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterPrimitive.java @@ -1,9 +1,8 @@ -// "Replace with collect" "true" +// "Replace with forEach" "true" import java.util.List; -import java.util.stream.Collectors; class Sample { public void some(List from, List to) { - to.addAll(from.stream().map(String::length).collect(Collectors.toList())); + from.stream().map(String::length).forEach(to::add); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayListCompoundDeclaration.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayListCompoundDeclaration.java index 3f03eab7760f..64f4a59ed0fe 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayListCompoundDeclaration.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayListCompoundDeclaration.java @@ -1,4 +1,4 @@ -// "Replace with collect" "true" +// "Replace with forEach" "true" import java.util.*; public class Collect { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayListNonTrivialInitializer.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayListNonTrivialInitializer.java index 6a276c0033ce..0b03a819f119 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayListNonTrivialInitializer.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectArrayListNonTrivialInitializer.java @@ -1,4 +1,4 @@ -// "Replace with collect" "true" +// "Replace with forEach" "true" import java.util.*; public class Collect { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectHashSetFieldInitializer.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectHashSetFieldInitializer.java index 44f39e19f3dc..99d260c5f082 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectHashSetFieldInitializer.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectHashSetFieldInitializer.java @@ -1,4 +1,4 @@ -// "Replace with collect" "true" +// "Replace with forEach" "true" import java.util.*; public class Collect { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSelfCollection.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSelfCollection.java index 1dbed313c132..247c0bee00b8 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSelfCollection.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSelfCollection.java @@ -1,4 +1,4 @@ -// "Replace with collect" "true" +// "Replace with forEach" "true" import java.util.*; public abstract class Collect implements Collection{ diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSetParameter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSetParameter.java index f7287c4b9a56..20605a54abfd 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSetParameter.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectSetParameter.java @@ -1,4 +1,4 @@ -// "Replace with collect" "true" +// "Replace with forEach" "true" import java.util.*; public class Collect { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCompactFilterToMethodReference.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCompactFilterToMethodReference.java index 82d89f081fed..b8d814ac98d4 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCompactFilterToMethodReference.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCompactFilterToMethodReference.java @@ -1,4 +1,4 @@ -// "Replace with collect" "true" +// "Replace with forEach" "true" import java.util.List; diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforePrimitive.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforePrimitive.java index 317027f27521..b2be39f1234c 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforePrimitive.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforePrimitive.java @@ -1,4 +1,4 @@ -// "Replace with collect" "true" +// "Replace with forEach" "true" import java.util.List; class Sample {