diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/streamMigration/MigrateToStreamFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/streamMigration/MigrateToStreamFix.java index 4dd254602a3e..c4b333a19542 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/streamMigration/MigrateToStreamFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/streamMigration/MigrateToStreamFix.java @@ -19,6 +19,7 @@ import com.intellij.codeInsight.FileModificationService; import com.intellij.codeInspection.LambdaCanBeMethodReferenceInspection; import com.intellij.codeInspection.LocalQuickFix; import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.InitializerUsageStatus; import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.Operation; import com.intellij.openapi.project.Project; import com.intellij.psi.*; @@ -72,14 +73,13 @@ abstract class MigrateToStreamFix implements LocalQuickFix { PsiType expressionType) { PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project); restoreComments(foreachStatement, foreachStatement.getBody()); - if (StreamApiMigrationInspection.isDeclarationJustBefore(var, foreachStatement)) { + InitializerUsageStatus status = StreamApiMigrationInspection.getInitializerUsageStatus(var, foreachStatement); + if (status != InitializerUsageStatus.UNKNOWN) { PsiExpression initializer = var.getInitializer(); if (ExpressionUtils.isZero(initializer)) { PsiType type = var.getType(); String replacement = (type.equals(expressionType) ? "" : "(" + type.getCanonicalText() + ") ") + builder; - initializer.replace(elementFactory.createExpressionFromText(replacement, foreachStatement)); - removeLoop(foreachStatement); - simplifyAndFormat(project, var); + replaceInitializer(foreachStatement, var, initializer, replacement, status); return; } } @@ -88,6 +88,27 @@ abstract class MigrateToStreamFix implements LocalQuickFix { simplifyAndFormat(project, result); } + static void replaceInitializer(PsiForeachStatement foreachStatement, + PsiVariable var, + PsiExpression initializer, + String replacement, + InitializerUsageStatus status) { + Project project = foreachStatement.getProject(); + PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project); + if(status == InitializerUsageStatus.DECLARED_JUST_BEFORE) { + initializer.replace(elementFactory.createExpressionFromText(replacement, foreachStatement)); + removeLoop(foreachStatement); + simplifyAndFormat(project, var); + } else { + if(status == InitializerUsageStatus.AT_WANTED_PLACE_ONLY) { + initializer.delete(); + } + PsiElement result = + foreachStatement.replace(elementFactory.createStatementFromText(var.getName() + " = " + replacement + ";", foreachStatement)); + simplifyAndFormat(project, result); + } + } + static void simplifyAndFormat(@NotNull Project project, PsiElement result) { if (result == null) return; LambdaCanBeMethodReferenceInspection.replaceAllLambdasWithMethodReferences(result); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/streamMigration/ReplaceWithCollectFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/streamMigration/ReplaceWithCollectFix.java index ba04d8dc5f90..e092bdb21f79 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/streamMigration/ReplaceWithCollectFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/streamMigration/ReplaceWithCollectFix.java @@ -16,7 +16,9 @@ package com.intellij.codeInspection.streamMigration; import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.InitializerUsageStatus; import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.Operation; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; @@ -32,6 +34,8 @@ import java.util.List; * @author Tagir Valeev */ class ReplaceWithCollectFix extends MigrateToStreamFix { + private static final Logger LOG = Logger.getInstance(ReplaceWithCollectFix.class); + final String myMethodName; protected ReplaceWithCollectFix(String methodName) { @@ -87,16 +91,18 @@ class ReplaceWithCollectFix extends MigrateToStreamFix { final StringBuilder builder = generateStream(iteratedValue, operations); final PsiExpression qualifierExpression = methodCallExpression.getMethodExpression().getQualifierExpression(); - final PsiExpression initializer = StreamApiMigrationInspection - .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); - removeLoop(foreachStatement); - return; + final PsiLocalVariable variable = StreamApiMigrationInspection.extractCollectionVariable(qualifierExpression); + if (variable != null) { + InitializerUsageStatus status = StreamApiMigrationInspection.getInitializerUsageStatus(variable, foreachStatement); + if(status != InitializerUsageStatus.UNKNOWN) { + PsiExpression initializer = variable.getInitializer(); + LOG.assertTrue(initializer != null); + String callText = builder.append(".collect(java.util.stream.Collectors.") + .append(createInitializerReplacementText(qualifierExpression.getType(), initializer)) + .append(")").toString(); + replaceInitializer(foreachStatement, variable, initializer, callText, status); + return; + } } final String qualifierText = qualifierExpression != null ? qualifierExpression.getText() + "." : ""; diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/streamMigration/ReplaceWithFindFirstFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/streamMigration/ReplaceWithFindFirstFix.java index 0579ba2557b1..6eb0e9c86301 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/streamMigration/ReplaceWithFindFirstFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/streamMigration/ReplaceWithFindFirstFix.java @@ -16,6 +16,7 @@ package com.intellij.codeInspection.streamMigration; import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.InitializerUsageStatus; import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.Operation; import com.intellij.openapi.project.Project; import com.intellij.psi.*; @@ -76,13 +77,12 @@ class ReplaceWithFindFirstFix extends MigrateToStreamFix { PsiExpression value = assignment.getRExpression(); if (value == null) return; restoreComments(foreachStatement, body); - if (StreamApiMigrationInspection.isDeclarationJustBefore(var, foreachStatement)) { + InitializerUsageStatus status = StreamApiMigrationInspection.getInitializerUsageStatus(var, foreachStatement); + if (status != InitializerUsageStatus.UNKNOWN) { PsiExpression initializer = var.getInitializer(); if (initializer != null) { - PsiElement result = - initializer.replace(elementFactory.createExpressionFromText(generateOptionalUnwrap(stream, tb, value, initializer), initializer)); - removeLoop(foreachStatement); - simplifyAndFormat(project, result); + String replacementText = generateOptionalUnwrap(stream, tb, value, initializer); + replaceInitializer(foreachStatement, var, initializer, replacementText, status); return; } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/streamMigration/ReplaceWithMatchFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/streamMigration/ReplaceWithMatchFix.java index 0488e0e14cfd..5435eee33752 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/streamMigration/ReplaceWithMatchFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/streamMigration/ReplaceWithMatchFix.java @@ -16,6 +16,7 @@ package com.intellij.codeInspection.streamMigration; import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.InitializerUsageStatus; import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.Operation; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; @@ -93,7 +94,8 @@ class ReplaceWithMatchFix extends MigrateToStreamFix { // for(....) if(...) {flag = true; break;} PsiVariable var = (PsiVariable)maybeVar; PsiExpression initializer = var.getInitializer(); - if(initializer != null && StreamApiMigrationInspection.isDeclarationJustBefore(var, foreachStatement)) { + InitializerUsageStatus status = StreamApiMigrationInspection.getInitializerUsageStatus(var, foreachStatement); + if(initializer != null && status != InitializerUsageStatus.UNKNOWN) { String replacement; if(ExpressionUtils.isLiteral(initializer, Boolean.FALSE) && ExpressionUtils.isLiteral(rValue, Boolean.TRUE)) { @@ -104,9 +106,7 @@ class ReplaceWithMatchFix extends MigrateToStreamFix { } else { replacement = streamText + "?" + rValue.getText() + ":" + initializer.getText(); } - PsiElement result = initializer.replace(elementFactory.createExpressionFromText(replacement, initializer)); - removeLoop(foreachStatement); - simplifyAndFormat(project, result); + replaceInitializer(foreachStatement, var, initializer, replacement, status); return; } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/streamMigration/StreamApiMigrationInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/streamMigration/StreamApiMigrationInspection.java index aad571a9b6fa..1e3bb608c47b 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/streamMigration/StreamApiMigrationInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/streamMigration/StreamApiMigrationInspection.java @@ -49,6 +49,8 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.util.*; +import static com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.InitializerUsageStatus.*; + /** * User: anna */ @@ -377,19 +379,17 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo return consumerClass != null ? psiFacade.getElementFactory().createType(consumerClass, variable.getType()) : null; } - @Contract("null, _ -> null") - static PsiExpression extractReplaceableCollectionInitializer(PsiExpression qualifierExpression, PsiStatement foreachStatement) { + @Contract("null -> null") + static PsiLocalVariable extractCollectionVariable(PsiExpression qualifierExpression) { 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; - } + final PsiExpression initializer = var.getInitializer(); + if (initializer instanceof PsiNewExpression) { + final PsiExpressionList argumentList = ((PsiNewExpression)initializer).getArgumentList(); + if (argumentList != null && argumentList.getExpressions().length == 0) { + return var; } } } @@ -397,6 +397,40 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo return null; } + enum InitializerUsageStatus { + // Variable is declared just before the wanted place + DECLARED_JUST_BEFORE, + // All initial value usages go through wanted place and at wanted place the variable value is guaranteed to be the initial value + AT_WANTED_PLACE_ONLY, + // At wanted place the variable value is guaranteed to be the initial value, but this initial value might be used somewhere else + AT_WANTED_PLACE, + // It's not guaranteed that the variable value at wanted place is initial value + UNKNOWN + } + + static InitializerUsageStatus getInitializerUsageStatus(PsiVariable var, PsiStatement nextStatement) { + if(var.getInitializer() == null) return UNKNOWN; + if(isDeclarationJustBefore(var, nextStatement)) return DECLARED_JUST_BEFORE; + PsiElement declaration = var.getParent(); + // Check if variable is not referenced in the same declaration like "int a = 0, b = a;" + if(!PsiTreeUtil.processElements(declaration, e -> !(e instanceof PsiReferenceExpression) || + ((PsiReferenceExpression)e).resolve() != var)) return UNKNOWN; + PsiElement block = PsiUtil.getVariableCodeBlock(var, null); + if(block == null) return UNKNOWN; + final ControlFlow controlFlow; + try { + controlFlow = ControlFlowFactory.getInstance(nextStatement.getProject()) + .getControlFlow(block, LocalsOrMyInstanceFieldsControlFlowPolicy.getInstance()); + } + catch (AnalysisCanceledException ignored) { + return UNKNOWN; + } + int start = controlFlow.getEndOffset(declaration); + int stop = controlFlow.getStartOffset(nextStatement); + if(ControlFlowUtil.isVariableReferencedBetween(controlFlow, start, stop, var)) return UNKNOWN; + return ControlFlowUtil.isValueUsedWithoutVisitingStop(controlFlow, start, stop, var) ? AT_WANTED_PLACE : AT_WANTED_PLACE_ONLY; + } + static boolean isDeclarationJustBefore(PsiVariable var, PsiStatement nextStatement) { PsiElement declaration = var.getParent(); PsiElement nextStatementParent = nextStatement.getParent(); @@ -482,8 +516,7 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo methodName = "addAll"; } else { PsiMethodCallExpression methodCallExpression = tb.getSingleMethodCall(); - if(methodCallExpression != null && extractReplaceableCollectionInitializer( - methodCallExpression.getMethodExpression().getQualifierExpression(), statement) != null) { + if(canCollect(statement, methodCallExpression)) { methodName = "collect"; } else { if (!SUGGEST_FOREACH) return; @@ -535,13 +568,19 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo } } - void handleSingleReturn(PsiForeachStatement statement, - TerminalBlock tb, - List operations) { + boolean canCollect(PsiForeachStatement statement, PsiMethodCallExpression methodCallExpression) { + if(methodCallExpression == null) return false; + PsiLocalVariable variable = extractCollectionVariable(methodCallExpression.getMethodExpression().getQualifierExpression()); + if(variable == null) return false; + return getInitializerUsageStatus(variable, statement) != UNKNOWN; + } + + void handleSingleReturn(PsiForeachStatement statement, TerminalBlock tb, List operations) { PsiReturnStatement returnStatement = (PsiReturnStatement)tb.getSingleStatement(); PsiExpression value = returnStatement.getReturnValue(); PsiReturnStatement nextReturnStatement = getNextReturnStatement(statement); - if(nextReturnStatement != null && (ExpressionUtils.isLiteral(value, Boolean.TRUE) || ExpressionUtils.isLiteral(value, Boolean.FALSE))) { + if (nextReturnStatement != null && + (ExpressionUtils.isLiteral(value, Boolean.TRUE) || ExpressionUtils.isLiteral(value, Boolean.FALSE))) { boolean foundResult = (boolean)((PsiLiteralExpression)value).getValue(); if(ExpressionUtils.isLiteral(nextReturnStatement.getReturnValue(), !foundResult)) { String methodName; diff --git a/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java b/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java index 4b08e3e094a6..ddab945cff0f 100644 --- a/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * 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. @@ -29,6 +29,7 @@ import com.intellij.util.containers.IntArrayList; import com.intellij.util.containers.IntStack; import gnu.trove.THashMap; import gnu.trove.THashSet; +import gnu.trove.TIntArrayList; import gnu.trove.TIntHashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -1284,6 +1285,112 @@ public class ControlFlowUtil { return visitor.getResult().booleanValue(); } + /** + * Returns true if the value the variable has at start is later referenced without going through stop instruction + * + * @param flow ControlFlow to analyze + * @param start the point at which variable value is created + * @param stop the stop-point + * @param variable the variable to examine + * @return true if the value the variable has at start is later referenced without going through stop instruction + */ + public static boolean isValueUsedWithoutVisitingStop(final ControlFlow flow, final int start, final int stop, final PsiVariable variable) { + if(start == stop) return false; + + class MyVisitor extends InstructionClientVisitor { + // true if value the variable has at given offset maybe referenced without going through stop instruction + final boolean[] maybeReferenced = new boolean[flow.getSize() + 1]; + + @Override + public void visitInstruction(Instruction instruction, int offset, int nextOffset) { + if (offset == stop) { + maybeReferenced[offset] = false; + return; + } + if(instruction instanceof WriteVariableInstruction && ((WriteVariableInstruction)instruction).variable == variable) { + maybeReferenced[offset] = false; + return; + } + if (maybeReferenced[offset]) return; + if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); + + boolean nextState = maybeReferenced[nextOffset]; + maybeReferenced[offset] = + nextState || (instruction instanceof ReadVariableInstruction && ((ReadVariableInstruction)instruction).variable == variable); + } + + @Override + public Boolean getResult() { + return maybeReferenced[start]; + } + } + MyVisitor visitor = new MyVisitor(); + depthFirstSearch(flow, visitor, start, flow.getSize()); + return visitor.getResult().booleanValue(); + } + + /** + * Checks whether variable can be referenced between start and stop points. Back-edges are also considered, so the actual place + * where it referenced might be outside of (start, stop) interval. + * + * @param flow ControlFlow to analyze + * @param start start point + * @param stop stop point + * @param variable variable to analyze + * @return true if variable can be referenced between start and stop points + */ + public static boolean isVariableReferencedBetween(final ControlFlow flow, + final int start, + final int stop, + final PsiVariable variable) { + if(start == stop) return false; + + // DFS visits instructions mainly in backward direction while here visiting in forward direction + // greatly reduces number of iterations. So first we just collect edges, then reverse their order. + // contains (from, to) pairs representing control flow arcs + final TIntArrayList list = new TIntArrayList(); + depthFirstSearch(flow, new InstructionClientVisitor() { + @Override + public void visitInstruction(Instruction instruction, int offset, int nextOffset) { + list.add(offset); + list.add(nextOffset); + } + + @Override + public Void getResult() { + return null; + } + }, start, flow.getSize()); + BitSet violated = new BitSet(); + List instructions = flow.getInstructions(); + boolean changed = true; + while(changed) { + changed = false; + for(int i=list.size()-2; i>=0; i-=2) { + int from = list.get(i); + int to = list.get(i+1); + if(from == stop) continue; + if(violated.get(from)) { + if(!violated.get(to)) { + if(to == stop) return true; + violated.set(to); + changed = true; + } + continue; + } + Instruction instruction = instructions.get(from); + if((instruction instanceof ReadVariableInstruction && ((ReadVariableInstruction)instruction).variable == variable) || + (instruction instanceof WriteVariableInstruction && ((WriteVariableInstruction)instruction).variable == variable)) { + violated.set(from); + violated.set(to); + if(to == stop) return true; + changed = true; + } + } + } + return false; + } + /** * @return min offset after sourceOffset which is definitely reachable from all references */ diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignment.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignment.java index cfdbf01b641b..d701eac44dab 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignment.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignment.java @@ -4,6 +4,6 @@ import java.util.List; public class Main { public void testAssignment(List data) { - String found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty()) ? "yes" : "no"; + String found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty()) ? "yes" : "no"; } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignmentBoolean.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignmentBoolean.java index fc0e5b198bc7..17bfaefa2008 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignmentBoolean.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignmentBoolean.java @@ -4,6 +4,6 @@ import java.util.List; public class Main { public void testAssignment(List data) { - boolean found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty()); + boolean found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty()); } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignmentBooleanInverted.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignmentBooleanInverted.java index 24ba822d2458..9c0ba70e710e 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignmentBooleanInverted.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignmentBooleanInverted.java @@ -4,6 +4,6 @@ import java.util.List; public class Main { public void testAssignment(List data) { - boolean found = !data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty()); + boolean found = !data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty()); } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignmentExtraCode.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignmentExtraCode.java new file mode 100644 index 000000000000..9a35e4e44cd3 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignmentExtraCode.java @@ -0,0 +1,14 @@ +// "Replace with anyMatch()" "true" + +import java.util.List; + +public class Main { + public void testAssignment(List data) { + boolean found; + if (data.size() > 10) { + System.out.println("Big data"); + } + found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty()); + System.out.println(found); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignmentNonTrivial.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignmentNonTrivial.java index 5d7e8f1d4dec..c62a206e83ac 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignmentNonTrivial.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignmentNonTrivial.java @@ -4,13 +4,12 @@ import java.util.List; public class Main { public void testAssignment(List data) { - boolean found = false; + boolean found; if(Math.random() > 0.5) { found = true; } else { - if (data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty())) { - found = true; - } + found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty()); } + System.out.println(found); } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignmentNonTrivialUnassigned.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignmentNonTrivialUnassigned.java new file mode 100644 index 000000000000..f947070807b7 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignmentNonTrivialUnassigned.java @@ -0,0 +1,15 @@ +// "Replace with anyMatch()" "true" + +import java.util.List; + +public class Main { + public void testAssignment(List data) { + boolean found = false; + if(Math.random() > 0.5) { + System.out.println("oops"); + } else { + found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty()); + } + System.out.println(found); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignmentTryCatch.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignmentTryCatch.java new file mode 100644 index 000000000000..c49e906a2145 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignmentTryCatch.java @@ -0,0 +1,16 @@ +// "Replace with anyMatch()" "true" + +import java.util.List; + +public class Main { + public void testAssignment(List data) { + boolean found; + try { + found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty()); + System.out.println(found); + } + catch(Exception ex) { + ex.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignmentTryCatch2.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignmentTryCatch2.java new file mode 100644 index 000000000000..3a1d5dc97f86 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterAnyMatchAssignmentTryCatch2.java @@ -0,0 +1,16 @@ +// "Replace with anyMatch()" "true" + +import java.util.List; + +public class Main { + public void testAssignment(List data) { + boolean found = false; + try { + found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty()); + } + catch(Exception ex) { + ex.printStackTrace(); + } + System.out.println(found); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterArrayFilterCollect.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterArrayFilterCollect.java index 883fd7326822..3b3a7b9983a9 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterArrayFilterCollect.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterArrayFilterCollect.java @@ -6,6 +6,6 @@ import java.util.stream.Collectors; public class Main { public void test(Integer[] arr) { - List result = Arrays.stream(arr).filter(x -> x > 5).collect(Collectors.toList()); + List result = Arrays.stream(arr).filter(x -> x > 5).collect(Collectors.toList()); } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterArrayListVariableType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterArrayListVariableType.java index 6d59beba0bfe..3767a91d0618 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterArrayListVariableType.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterArrayListVariableType.java @@ -4,7 +4,7 @@ import java.util.stream.Collectors; class A { public static void main(List args) { - ArrayList uniqNames = args.stream().map(name -> name.substring(1)).collect(Collectors.toCollection(ArrayList::new)); + ArrayList uniqNames = args.stream().map(name -> name.substring(1)).collect(Collectors.toCollection(ArrayList::new)); uniqNames.forEach(System.out::println); } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCastExpected.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCastExpected.java index b0f1807d07fe..cbf887b56104 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCastExpected.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCastExpected.java @@ -5,7 +5,7 @@ import java.util.stream.Collectors; class Test { public static List> fromString(final T src, Function> extractor) { - final List> result = extractor.apply(src).stream().map((Function>) TokenFilter::new).collect(Collectors.toList()); + final List> result = extractor.apply(src).stream().map((Function>) TokenFilter::new).collect(Collectors.toList()); return result; } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayList.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayList.java index aef9e753f716..134b51e18570 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayList.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayList.java @@ -10,6 +10,6 @@ public class Collect { } void collectNames(List persons){ - List names = persons.stream().map(Person::getName).collect(Collectors.toList()); + List names = persons.stream().map(Person::getName).collect(Collectors.toList()); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListAndFilter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListAndFilter.java index 4c736c9e53e0..e19a340cb9a5 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListAndFilter.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListAndFilter.java @@ -10,6 +10,6 @@ public class Collect { } void collectNames(List persons){ - List names = persons.stream().filter(Objects::nonNull).map(Person::getName).collect(Collectors.toList()); + List names = persons.stream().filter(Objects::nonNull).map(Person::getName).collect(Collectors.toList()); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListCollection.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListCollection.java index c526e817b438..d8233354012e 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListCollection.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListCollection.java @@ -10,6 +10,6 @@ public class Collect { } void collectNames(List persons){ - Collection names = persons.stream().map(Person::getName).collect(Collectors.toList()); + Collection names = persons.stream().map(Person::getName).collect(Collectors.toList()); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListComment.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListComment.java index a9b24a5a2005..cfec0c75d869 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListComment.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListComment.java @@ -10,7 +10,7 @@ public class Collect { } void collectNames(List persons){ - List names = persons.stream().map(Person::getName).collect(Collectors.toList()); + List names = persons.stream().map(Person::getName).collect(Collectors.toList()); //some comment } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListLambda.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListLambda.java index e1517740be28..9700feba43a7 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListLambda.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectArrayListLambda.java @@ -10,6 +10,6 @@ public class Collect { } void collectNames(List persons){ - List names = persons.stream().map(person -> "name: " + person.getName()).collect(Collectors.toList()); + List names = persons.stream().map(person -> "name: " + person.getName()).collect(Collectors.toList()); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectBoxed.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectBoxed.java index 5f8cdce462d7..5401a062acc7 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectBoxed.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectBoxed.java @@ -6,6 +6,6 @@ import java.util.stream.Collectors; public class Main { public void testPrimitiveMap(List data) { - List list = data.stream().filter(str -> str.startsWith("xyz")).mapToInt(String::length).filter(len -> len > 10).boxed().collect(Collectors.toList()); + List list = data.stream().filter(str -> str.startsWith("xyz")).mapToInt(String::length).filter(len -> len > 10).boxed().collect(Collectors.toList()); } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectHashSet.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectHashSet.java index 022b8e3ae576..5d6cab563c56 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectHashSet.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectHashSet.java @@ -10,6 +10,6 @@ public class Collect { } void collectNames(List persons){ - Set names = persons.stream().map(Person::getName).collect(Collectors.toSet()); + Set names = persons.stream().map(Person::getName).collect(Collectors.toSet()); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectInterrupted.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectInterrupted.java new file mode 100644 index 000000000000..9923f577a02d --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectInterrupted.java @@ -0,0 +1,17 @@ +// "Replace with collect" "true" +import java.util.*; +import java.util.stream.Collectors; + +public class Collect { + class Person { + String getName() { + return ""; + } + } + + void collectNames(List persons){ + Set names, other = new HashSet<>(); + names = persons.stream().map(Person::getName).collect(Collectors.toSet()); + System.out.println(names); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectInterruptedInLoop.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectInterruptedInLoop.java new file mode 100644 index 000000000000..8721aa441968 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectInterruptedInLoop.java @@ -0,0 +1,18 @@ +// "Replace with forEach" "true" +import java.util.*; + +public class Collect { + class Person { + String getName() { + return ""; + } + } + + void collectNames(List persons){ + Set names = new HashSet<>(); + for(int i=0; i<10; i++) { + persons.stream().map(Person::getName).forEach(names::add); + } + System.out.println(names); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectInterruptedUpdated.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectInterruptedUpdated.java new file mode 100644 index 000000000000..0d86145188f2 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectInterruptedUpdated.java @@ -0,0 +1,17 @@ +// "Replace with forEach" "true" +import java.util.*; + +public class Collect { + class Person { + String getName() { + return ""; + } + } + + void collectNames(List persons){ + Set names = new HashSet<>(); + names.add("Test"); + persons.stream().map(Person::getName).forEach(names::add); + System.out.println(names); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectInterruptedUsed.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectInterruptedUsed.java new file mode 100644 index 000000000000..2e2ea02812dc --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectInterruptedUsed.java @@ -0,0 +1,19 @@ +// "Replace with collect" "true" +import java.util.*; +import java.util.stream.Collectors; + +public class Collect { + class Person { + String getName() { + return ""; + } + } + + void collectNames(List persons){ + Set names = new HashSet<>(), other = new HashSet<>(); + if(persons != null) { + names = persons.stream().map(Person::getName).collect(Collectors.toSet()); + } + System.out.println(names); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectLinkedHashSet.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectLinkedHashSet.java index 031edc64f14d..9ac23c8f4984 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectLinkedHashSet.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectLinkedHashSet.java @@ -10,6 +10,6 @@ public class Collect { } void collectNames(List persons){ - Set names = persons.stream().map(Person::getName).collect(Collectors.toCollection(LinkedHashSet::new)); + Set names = persons.stream().map(Person::getName).collect(Collectors.toCollection(LinkedHashSet::new)); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectToObj.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectToObj.java index bb8a76602fc1..38b8180bf6c4 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectToObj.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterCollectToObj.java @@ -6,6 +6,6 @@ import java.util.stream.Collectors; public class Main { public void testPrimitiveMap(List data) { - List list = data.stream().filter(str -> str.startsWith("xyz")).mapToInt(String::length).filter(len -> len > 10).mapToObj(String::valueOf).collect(Collectors.toList()); + List list = data.stream().filter(str -> str.startsWith("xyz")).mapToInt(String::length).filter(len -> len > 10).mapToObj(String::valueOf).collect(Collectors.toList()); } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterContinueNested.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterContinueNested.java index c54f06a9c72c..3b4195b6d70d 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterContinueNested.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterContinueNested.java @@ -6,7 +6,7 @@ import java.util.stream.Collectors; public class Main { public List test(Map> map) { - List result = map.entrySet().stream().filter(entry -> !entry.getKey().isEmpty()).map(Map.Entry::getValue).filter(Objects::nonNull).flatMap(Collection::stream).map(String::trim).filter(trimmed -> !trimmed.isEmpty()).collect(Collectors.toList()); + List result = map.entrySet().stream().filter(entry -> !entry.getKey().isEmpty()).map(Map.Entry::getValue).filter(Objects::nonNull).flatMap(Collection::stream).map(String::trim).filter(trimmed -> !trimmed.isEmpty()).collect(Collectors.toList()); return result; } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterContinueNestedElse.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterContinueNestedElse.java index c54f06a9c72c..3b4195b6d70d 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterContinueNestedElse.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterContinueNestedElse.java @@ -6,7 +6,7 @@ import java.util.stream.Collectors; public class Main { public List test(Map> map) { - List result = map.entrySet().stream().filter(entry -> !entry.getKey().isEmpty()).map(Map.Entry::getValue).filter(Objects::nonNull).flatMap(Collection::stream).map(String::trim).filter(trimmed -> !trimmed.isEmpty()).collect(Collectors.toList()); + List result = map.entrySet().stream().filter(entry -> !entry.getKey().isEmpty()).map(Map.Entry::getValue).filter(Objects::nonNull).flatMap(Collection::stream).map(String::trim).filter(trimmed -> !trimmed.isEmpty()).collect(Collectors.toList()); return result; } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFilterFlatMapCollectionFilterMapCollect.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFilterFlatMapCollectionFilterMapCollect.java index a7a5a0f83364..091106c433cd 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFilterFlatMapCollectionFilterMapCollect.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFilterFlatMapCollectionFilterMapCollect.java @@ -4,6 +4,6 @@ import java.util.stream.Collectors; public class Main { public void test(List> nested) { - List result = nested.stream().filter(Objects::nonNull).flatMap(Collection::stream).filter(str -> str.startsWith("xyz")).map(String::trim).collect(Collectors.toList()); + List result = nested.stream().filter(Objects::nonNull).flatMap(Collection::stream).filter(str -> str.startsWith("xyz")).map(String::trim).collect(Collectors.toList()); } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFilterFlatMapMapFilterCollect.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFilterFlatMapMapFilterCollect.java index e6be8c957ec4..dba2e1608027 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFilterFlatMapMapFilterCollect.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFilterFlatMapMapFilterCollect.java @@ -6,6 +6,6 @@ import java.util.stream.Collectors; public class Main { public void test(List list) { - List result = list.stream().filter(arr -> arr.length > 2).flatMap(Arrays::stream).map(String::trim).filter(trimmed -> !trimmed.isEmpty()).collect(Collectors.toList()); + List result = list.stream().filter(arr -> arr.length > 2).flatMap(Arrays::stream).map(String::trim).filter(trimmed -> !trimmed.isEmpty()).collect(Collectors.toList()); } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFilterMapFlatMapArrayCollect.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFilterMapFlatMapArrayCollect.java index 46c9d614e531..81e1b7dbcc44 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFilterMapFlatMapArrayCollect.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFilterMapFlatMapArrayCollect.java @@ -7,6 +7,6 @@ import java.util.stream.Collectors; public class Main { public void test(Map map) { - List result = map.entrySet().stream().filter(entry -> entry.getKey().startsWith("x")).map(Map.Entry::getValue).flatMap(Arrays::stream).map(String::trim).collect(Collectors.toList()); + List result = map.entrySet().stream().filter(entry -> entry.getKey().startsWith("x")).map(Map.Entry::getValue).flatMap(Arrays::stream).map(String::trim).collect(Collectors.toList()); } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstAssignment.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstAssignment.java index 9ff0c0efd750..3938b777a914 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstAssignment.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstAssignment.java @@ -6,7 +6,7 @@ import java.util.Objects; public class Main { public void testMap(Map> map) throws Exception { - int firstSize = map.values().stream().filter(Objects::nonNull).findFirst().map(List::size).orElse(0); + int firstSize = map.values().stream().filter(Objects::nonNull).findFirst().map(List::size).orElse(0); // comment System.out.println(firstSize); } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstAssignmentCast.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstAssignmentCast.java index ce1ea6e97718..e301f4212d5f 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstAssignmentCast.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstAssignmentCast.java @@ -4,7 +4,7 @@ import java.util.List; public class Main { public void testCast(List data) { - String found = (String) data.stream().filter(obj -> obj instanceof String).findFirst().orElse(null); + String found = (String) data.stream().filter(obj -> obj instanceof String).findFirst().orElse(null); System.out.println(found); } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstAssignmentInterrupted.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstAssignmentInterrupted.java new file mode 100644 index 000000000000..edce43b3da0b --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstAssignmentInterrupted.java @@ -0,0 +1,18 @@ +// "Replace with findFirst()" "true" + +import java.util.List; +import java.util.Map; +import java.util.Objects; + +public class Main { + public void testMap(Map> map) throws Exception { + int firstSize; + int other = map.size(); + if(other > 10) { + System.out.println("Big"); + } + // comment + firstSize = map.values().stream().filter(Objects::nonNull).findFirst().map(List::size).orElse(0); + System.out.println(firstSize); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstAssignmentUsedInSameDeclaration.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstAssignmentUsedInSameDeclaration.java new file mode 100644 index 000000000000..3ea2190bb2bb --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstAssignmentUsedInSameDeclaration.java @@ -0,0 +1,14 @@ +// "Replace with findFirst()" "true" + +import java.util.List; +import java.util.Map; +import java.util.Objects; + +public class Main { + public void testMap(Map> map) throws Exception { + int firstSize = 0, other = firstSize; + // comment + firstSize = map.values().stream().filter(Objects::nonNull).findFirst().map(List::size).orElse(firstSize); + System.out.println(firstSize); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstAssignmentWithLabel.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstAssignmentWithLabel.java index e901baff38ee..ecfb21e12394 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstAssignmentWithLabel.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstAssignmentWithLabel.java @@ -7,7 +7,7 @@ import java.util.Objects; public class Main { public void testMap(Map> map) throws Exception { - String firstStr = map.values().stream().filter(Objects::nonNull).flatMap(Collection::stream).filter(str -> !str.isEmpty()).findFirst().orElse(""); + String firstStr = map.values().stream().filter(Objects::nonNull).flatMap(Collection::stream).filter(str -> !str.isEmpty()).findFirst().orElse(""); System.out.println(firstStr); } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFlatten2DArray.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFlatten2DArray.java index a74094c0dc8b..fb742c6b7dce 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFlatten2DArray.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFlatten2DArray.java @@ -7,7 +7,7 @@ import java.util.stream.Collectors; public class Main { public List test(String[][] arr) { - List result = Arrays.stream(arr).filter(Objects::nonNull).flatMap(Arrays::stream).collect(Collectors.toList()); + List result = Arrays.stream(arr).filter(Objects::nonNull).flatMap(Arrays::stream).collect(Collectors.toList()); return result; } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFlatten2DArrayPrimitive.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFlatten2DArrayPrimitive.java index 7fc05324430b..5b5a13aacf04 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFlatten2DArrayPrimitive.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFlatten2DArrayPrimitive.java @@ -7,7 +7,7 @@ import java.util.stream.Collectors; public class Main { public List test(int[][] arr) { - List result = Arrays.stream(arr).filter(Objects::nonNull).flatMapToInt(Arrays::stream).boxed().collect(Collectors.toList()); + List result = Arrays.stream(arr).filter(Objects::nonNull).flatMapToInt(Arrays::stream).boxed().collect(Collectors.toList()); return result; } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterSumInterruptedUnused.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterSumInterruptedUnused.java new file mode 100644 index 000000000000..de8298912da4 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterSumInterruptedUnused.java @@ -0,0 +1,15 @@ +// "Replace with sum()" "true" + +import java.util.List; + +public class Main { + public void testPrimitiveMap(List data) { + int sum; + if(Math.random() > 0.5) { + sum = 10; + } else { + sum = data.stream().filter(str -> str.startsWith("xyz")).mapToInt(String::length).filter(len -> len > 10).map(len -> len * 2).sum(); + } + System.out.println(sum); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterSumInterruptedUsed.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterSumInterruptedUsed.java new file mode 100644 index 000000000000..f9e15642def1 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterSumInterruptedUsed.java @@ -0,0 +1,15 @@ +// "Replace with sum()" "true" + +import java.util.List; + +public class Main { + public void testPrimitiveMap(List data) { + int sum = 0; + if(Math.random() > 0.5) { + System.out.println("oops"); + } else { + sum = data.stream().filter(str -> str.startsWith("xyz")).mapToInt(String::length).filter(len -> len > 10).map(len -> len * 2).sum(); + } + System.out.println(sum); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchAssignmentExtraCode.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchAssignmentExtraCode.java new file mode 100644 index 000000000000..ae1ff4ab7304 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchAssignmentExtraCode.java @@ -0,0 +1,20 @@ +// "Replace with anyMatch()" "true" + +import java.util.List; + +public class Main { + public void testAssignment(List data) { + boolean found = false; + if (data.size() > 10) { + System.out.println("Big data"); + } + for(String str : data) { + String trimmed = str.trim(); + if(!trimmed.isEmpty()) { + found = true; + break; + } + } + System.out.println(found); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchAssignmentNonTrivial.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchAssignmentNonTrivial.java index 742d43ee19a6..ab0ed9ccce36 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchAssignmentNonTrivial.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchAssignmentNonTrivial.java @@ -16,5 +16,6 @@ public class Main { } } } + System.out.println(found); } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchAssignmentNonTrivialUnassigned.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchAssignmentNonTrivialUnassigned.java new file mode 100644 index 000000000000..9fd6306271dc --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchAssignmentNonTrivialUnassigned.java @@ -0,0 +1,21 @@ +// "Replace with anyMatch()" "true" + +import java.util.List; + +public class Main { + public void testAssignment(List data) { + boolean found = false; + if(Math.random() > 0.5) { + System.out.println("oops"); + } else { + for (String str : data) { + String trimmed = str.trim(); + if (!trimmed.isEmpty()) { + found = true; + break; + } + } + } + System.out.println(found); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchAssignmentTryCatch.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchAssignmentTryCatch.java new file mode 100644 index 000000000000..74a945dbf159 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchAssignmentTryCatch.java @@ -0,0 +1,22 @@ +// "Replace with anyMatch()" "true" + +import java.util.List; + +public class Main { + public void testAssignment(List data) { + boolean found = false; + try { + for (String str : data) { + String trimmed = str.trim(); + if (!trimmed.isEmpty()) { + found = true; + break; + } + } + System.out.println(found); + } + catch(Exception ex) { + ex.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchAssignmentTryCatch2.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchAssignmentTryCatch2.java new file mode 100644 index 000000000000..ad9783e71a0a --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeAnyMatchAssignmentTryCatch2.java @@ -0,0 +1,22 @@ +// "Replace with anyMatch()" "true" + +import java.util.List; + +public class Main { + public void testAssignment(List data) { + boolean found = false; + try { + for (String str : data) { + String trimmed = str.trim(); + if (!trimmed.isEmpty()) { + found = true; + break; + } + } + } + catch(Exception ex) { + ex.printStackTrace(); + } + System.out.println(found); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectInterrupted.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectInterrupted.java new file mode 100644 index 000000000000..beeebbc22879 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectInterrupted.java @@ -0,0 +1,18 @@ +// "Replace with collect" "true" +import java.util.*; + +public class Collect { + class Person { + String getName() { + return ""; + } + } + + void collectNames(List persons){ + Set names = new HashSet<>(), other = new HashSet<>(); + for (Person person : persons) { + names.add(person.getName()); + } + System.out.println(names); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectInterruptedInLoop.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectInterruptedInLoop.java new file mode 100644 index 000000000000..da174b7f9203 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectInterruptedInLoop.java @@ -0,0 +1,20 @@ +// "Replace with forEach" "true" +import java.util.*; + +public class Collect { + class Person { + String getName() { + return ""; + } + } + + void collectNames(List persons){ + Set names = new HashSet<>(); + for(int i=0; i<10; i++) { + for (Person person : persons) { + names.add(person.getName()); + } + } + System.out.println(names); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectInterruptedUpdated.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectInterruptedUpdated.java new file mode 100644 index 000000000000..807ad23e0f6c --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectInterruptedUpdated.java @@ -0,0 +1,19 @@ +// "Replace with forEach" "true" +import java.util.*; + +public class Collect { + class Person { + String getName() { + return ""; + } + } + + void collectNames(List persons){ + Set names = new HashSet<>(); + names.add("Test"); + for (Person person : persons) { + names.add(person.getName()); + } + System.out.println(names); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectInterruptedUsed.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectInterruptedUsed.java new file mode 100644 index 000000000000..5121108ae0e9 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeCollectInterruptedUsed.java @@ -0,0 +1,20 @@ +// "Replace with collect" "true" +import java.util.*; + +public class Collect { + class Person { + String getName() { + return ""; + } + } + + void collectNames(List persons){ + Set names = new HashSet<>(), other = new HashSet<>(); + if(persons != null) { + for (Person person : persons) { + names.add(person.getName()); + } + } + System.out.println(names); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFindFirstAssignmentInterrupted.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFindFirstAssignmentInterrupted.java new file mode 100644 index 000000000000..f197faa7d174 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFindFirstAssignmentInterrupted.java @@ -0,0 +1,22 @@ +// "Replace with findFirst()" "true" + +import java.util.List; +import java.util.Map; + +public class Main { + public void testMap(Map> map) throws Exception { + int firstSize = 0; + int other = map.size(); + if(other > 10) { + System.out.println("Big"); + } + for(List list : map.values()) { + if(list != null) { + firstSize = list.size(); + // comment + break; + } + } + System.out.println(firstSize); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFindFirstAssignmentUsedInSameDeclaration.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFindFirstAssignmentUsedInSameDeclaration.java new file mode 100644 index 000000000000..5b2dad630004 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFindFirstAssignmentUsedInSameDeclaration.java @@ -0,0 +1,18 @@ +// "Replace with findFirst()" "true" + +import java.util.List; +import java.util.Map; + +public class Main { + public void testMap(Map> map) throws Exception { + int firstSize = 0, other = firstSize; + for(List list : map.values()) { + if(list != null) { + firstSize = list.size(); + // comment + break; + } + } + System.out.println(firstSize); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeSumInterruptedUnused.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeSumInterruptedUnused.java new file mode 100644 index 000000000000..6d1bec15b905 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeSumInterruptedUnused.java @@ -0,0 +1,22 @@ +// "Replace with sum()" "true" + +import java.util.List; + +public class Main { + public void testPrimitiveMap(List data) { + int sum = 0; + if(Math.random() > 0.5) { + sum = 10; + } else { + for (String str : data) { + if (str.startsWith("xyz")) { + int len = str.length(); + if (len > 10) { + sum += len * 2; + } + } + } + } + System.out.println(sum); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeSumInterruptedUsed.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeSumInterruptedUsed.java new file mode 100644 index 000000000000..e33ab51f1b7c --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeSumInterruptedUsed.java @@ -0,0 +1,22 @@ +// "Replace with sum()" "true" + +import java.util.List; + +public class Main { + public void testPrimitiveMap(List data) { + int sum = 0; + if(Math.random() > 0.5) { + System.out.println("oops"); + } else { + for (String str : data) { + if (str.startsWith("xyz")) { + int len = str.length(); + if (len > 10) { + sum += len * 2; + } + } + } + } + System.out.println(sum); + } +} \ No newline at end of file