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 f7577105681a..32496face5cb 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/StreamApiMigrationInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/StreamApiMigrationInspection.java @@ -186,10 +186,10 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo if(nonFinalVariables.isEmpty() && tb.getSingleStatement() instanceof PsiReturnStatement) { PsiReturnStatement returnStatement = (PsiReturnStatement)tb.getSingleStatement(); PsiExpression value = returnStatement.getReturnValue(); - if(isLiteral(value, Boolean.TRUE) || isLiteral(value, Boolean.FALSE)) { - boolean foundResult = (boolean)((PsiLiteralExpression)value).getValue(); - PsiReturnStatement nextReturnStatement = getNextReturnStatement(statement); - if(nextReturnStatement != null) { + PsiReturnStatement nextReturnStatement = getNextReturnStatement(statement); + if(nextReturnStatement != null) { + if(isLiteral(value, Boolean.TRUE) || isLiteral(value, Boolean.FALSE)) { + boolean foundResult = (boolean)((PsiLiteralExpression)value).getValue(); if(isLiteral(nextReturnStatement.getReturnValue(), !foundResult)) { String methodName; if (foundResult) { @@ -205,8 +205,12 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo } } registerProblem(holder, isOnTheFly, statement, methodName, new ReplaceWithMatchFix(methodName)); + return; } } + if(nextReturnStatement.getReturnValue() instanceof PsiLiteralExpression) { + registerProblem(holder, isOnTheFly, statement, "findFirst", new ReplaceWithFindFirstFix()); + } } } } @@ -891,6 +895,43 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo } } + private static class ReplaceWithFindFirstFix extends MigrateToStreamFix { + @NotNull + @Override + public String getFamilyName() { + return "Replace with findFirst()"; + } + + @Override + void migrate(@NotNull Project project, + @NotNull ProblemDescriptor descriptor, + @NotNull PsiForeachStatement foreachStatement, + @NotNull PsiExpression iteratedValue, + @NotNull PsiStatement body, + @NotNull TerminalBlock tb, + @NotNull List intermediateOps) { + PsiReturnStatement returnStatement = (PsiReturnStatement)tb.getSingleStatement(); + PsiExpression value = returnStatement.getReturnValue(); + if(value == null) return; + PsiReturnStatement nextReturnStatement = getNextReturnStatement(foreachStatement); + if(nextReturnStatement == null) return; + PsiExpression orElseExpression = nextReturnStatement.getReturnValue(); + if(!(orElseExpression instanceof PsiLiteralExpression)) return; + final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project); + StringBuilder builder = generateStream(iteratedValue, intermediateOps).append(".findFirst()"); + if (!(value instanceof PsiReferenceExpression) || ((PsiReferenceExpression)value).resolve() != tb.getVariable()) { + builder.append(".map(").append(tb.getVariable().getName()).append(" -> ").append(value.getText()).append(")"); + } + builder.append(".orElse(").append(orElseExpression.getText()).append(")"); + boolean siblings = nextReturnStatement.getParent() == foreachStatement.getParent(); + PsiElement result = foreachStatement.replace(elementFactory.createStatementFromText("return " + builder + ";", foreachStatement)); + if(siblings) { + nextReturnStatement.delete(); + } + simplifyAndFormat(project, result); + } + } + private static class ReplaceWithSumFix extends MigrateToStreamFix { @NotNull diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirst.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirst.java new file mode 100644 index 000000000000..30d217244b04 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirst.java @@ -0,0 +1,10 @@ +// "Replace with findFirst()" "true" + +import java.util.Collection; +import java.util.List; + +public class Main { + public static String find(List> list) { + return list.stream().flatMap(Collection::stream).filter(string -> string.startsWith("ABC")).findFirst().map(string -> string.substring(3)).orElse(""); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstOuterIf.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstOuterIf.java new file mode 100644 index 000000000000..7efce7fc4105 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/afterFindFirstOuterIf.java @@ -0,0 +1,13 @@ +// "Replace with findFirst()" "true" + +import java.util.Collection; +import java.util.List; + +public class Main { + public static String find(List> list) { + if(list != null) { + return list.stream().flatMap(Collection::stream).filter(string -> string.startsWith("ABC")).findFirst().orElse(null); + } + return null; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFindFirst.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFindFirst.java new file mode 100644 index 000000000000..8aac00f55962 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFindFirst.java @@ -0,0 +1,16 @@ +// "Replace with findFirst()" "true" + +import java.util.List; + +public class Main { + public static String find(List> list) { + for(List innerList : list) { + for(String string : innerList) { + if(string.startsWith("ABC")) { + return string.substring(3); + } + } + } + return ""; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFindFirstOuterIf.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFindFirstOuterIf.java new file mode 100644 index 000000000000..c44a1e221256 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeFindFirstOuterIf.java @@ -0,0 +1,18 @@ +// "Replace with findFirst()" "true" + +import java.util.List; + +public class Main { + public static String find(List> list) { + if(list != null) { + for (List innerList : list) { + for (String string : innerList) { + if (string.startsWith("ABC")) { + return string; + } + } + } + } + return null; + } +} \ No newline at end of file