From c3b4d6f849ae055cc13a4549252336b52398febb Mon Sep 17 00:00:00 2001 From: Roman Ivanov Date: Fri, 1 Sep 2017 12:37:18 +0700 Subject: [PATCH] support return in forEach replacement --- .../streamMigration/ForEachMigration.java | 2 ++ .../StreamApiMigrationInspection.java | 6 +++--- .../streamMigration/TerminalBlock.java | 18 ++++++++++++++++++ .../continue/afterContinueInside.java | 14 ++++++++++++++ .../continue/afterForEachContinue.java | 14 ++++++++++++++ .../continue/beforeContinueInside.java | 4 ++-- .../beforeForEachContinue.java | 0 .../foreach/afterForEachContinue.java | 13 ------------- 8 files changed, 53 insertions(+), 18 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/continue/afterContinueInside.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/continue/afterForEachContinue.java rename java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/{foreach => continue}/beforeForEachContinue.java (100%) delete mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/foreach/afterForEachContinue.java diff --git a/java/java-impl/src/com/intellij/codeInspection/streamMigration/ForEachMigration.java b/java/java-impl/src/com/intellij/codeInspection/streamMigration/ForEachMigration.java index 17220b58b8d9..46333df8eb63 100644 --- a/java/java-impl/src/com/intellij/codeInspection/streamMigration/ForEachMigration.java +++ b/java/java-impl/src/com/intellij/codeInspection/streamMigration/ForEachMigration.java @@ -84,6 +84,8 @@ class ForEachMigration extends BaseStreamApiMigration { return loopStatement.replace(factory.createStatementFromText(callText, loopStatement)); } + tb.replaceContinueWithReturn(factory); + String stream = tb.generate(true) + "." + getReplacement() + "("; PsiElement block = tb.convertToElement(factory); diff --git a/java/java-impl/src/com/intellij/codeInspection/streamMigration/StreamApiMigrationInspection.java b/java/java-impl/src/com/intellij/codeInspection/streamMigration/StreamApiMigrationInspection.java index c8712fde65bd..16d6b5a449e7 100644 --- a/java/java-impl/src/com/intellij/codeInspection/streamMigration/StreamApiMigrationInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/streamMigration/StreamApiMigrationInspection.java @@ -41,7 +41,6 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.util.ArrayUtil; -import com.intellij.util.containers.ContainerUtil; import com.siyeh.ig.psiutils.*; import one.util.streamex.StreamEx; import org.jetbrains.annotations.Contract; @@ -509,8 +508,9 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo } Collection exitPoints = tb.findExitPoints(controlFlow); if (exitPoints == null) return null; - if ((exitPoints.isEmpty()) && - nonFinalVariables.isEmpty()) { + boolean onlyNonLabeledContinue = StreamEx.of(exitPoints).allMatch(statement -> statement instanceof PsiContinueStatement && + ((PsiContinueStatement)statement).getLabelIdentifier() == null); + if (onlyNonLabeledContinue && nonFinalVariables.isEmpty()) { boolean shouldWarn = SUGGEST_FOREACH && (REPLACE_TRIVIAL_FOREACH || tb.hasOperations() || diff --git a/java/java-impl/src/com/intellij/codeInspection/streamMigration/TerminalBlock.java b/java/java-impl/src/com/intellij/codeInspection/streamMigration/TerminalBlock.java index b039d88688f5..b40f37f71032 100644 --- a/java/java-impl/src/com/intellij/codeInspection/streamMigration/TerminalBlock.java +++ b/java/java-impl/src/com/intellij/codeInspection/streamMigration/TerminalBlock.java @@ -463,6 +463,24 @@ class TerminalBlock { return block; } + + /** + * method replaces continue statement (without labels) to return statement + * @param factory factory to use to create new element if necessary + */ + void replaceContinueWithReturn(PsiElementFactory factory) { + for (int i = 0, length = myStatements.length; i < length; i++) { + PsiStatement statement = myStatements[i]; + if(statement instanceof PsiContinueStatement) { + myStatements[i] = factory.createStatementFromText("return;", null); + continue; + } + StreamEx.ofTree(statement, (PsiElement s) -> StreamEx.of(s.getChildren())) + .select(PsiContinueStatement.class) + .forEach(stmt -> stmt.replace(factory.createStatementFromText("return;", null))); + } + } + String generate() { return generate(false); } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/continue/afterContinueInside.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/continue/afterContinueInside.java new file mode 100644 index 000000000000..ba429ec21359 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/continue/afterContinueInside.java @@ -0,0 +1,14 @@ +// "Replace with forEach" "true" +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +class Sample { + List foo = new ArrayList<>(); + { + foo.stream().filter(Objects::isNull).forEach(s -> { + return; + }); + + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/continue/afterForEachContinue.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/continue/afterForEachContinue.java new file mode 100644 index 000000000000..9755433ba1ef --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/continue/afterForEachContinue.java @@ -0,0 +1,14 @@ +// "Replace with forEach" "true" + +import java.util.Arrays; +import java.util.Collection; + +public class Test { + void test(int[] arr) { + Arrays.stream(arr).forEach(x -> { + int y = x * 2; + if (x > y) return; + System.out.println(x); + }); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/continue/beforeContinueInside.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/continue/beforeContinueInside.java index 9ff6de7c05c7..5385fba46393 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/continue/beforeContinueInside.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/continue/beforeContinueInside.java @@ -1,4 +1,4 @@ -// "Replace with forEach" "false" +// "Replace with forEach" "true" import java.util.ArrayList; import java.util.List; @@ -12,4 +12,4 @@ class Sample { } } -} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/foreach/beforeForEachContinue.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/continue/beforeForEachContinue.java similarity index 100% rename from java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/foreach/beforeForEachContinue.java rename to java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/continue/beforeForEachContinue.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/foreach/afterForEachContinue.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/foreach/afterForEachContinue.java deleted file mode 100644 index 3cfd5591fabb..000000000000 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/foreach/afterForEachContinue.java +++ /dev/null @@ -1,13 +0,0 @@ -// "Replace with forEach" "true" - -import java.util.Collection; - -public class Test { - void test(int[] arr) { - for(int x : arr) { - int y = x*2; - if(x > y) continue; - System.out.println(x); - } - } -}