From ec7cd902e832893b80967204636f6320708f7a8d Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Mon, 16 Mar 2020 18:33:04 +0700 Subject: [PATCH] IDEA-235296 Refactor ensureCodeBlock: TrivialFunctionalExpressionUsageInspection updated GitOrigin-RevId: 4f92ab7fe8c79e22dc17479e172330e5c61332b7 --- .../afterBlockLambdaForInit.java | 12 +++++ .../afterBlockLambdaInFieldDeclaration.java | 11 +++++ .../afterBlockLambdaWhileStatement.java | 13 +++++ .../beforeBlockLambdaForInit.java | 2 +- .../beforeBlockLambdaInFieldDeclaration.java | 2 +- .../beforeBlockLambdaWhileStatement.java | 2 +- ...alFunctionalExpressionUsageInspection.java | 48 +++++++------------ 7 files changed, 56 insertions(+), 34 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/afterBlockLambdaForInit.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/afterBlockLambdaInFieldDeclaration.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/afterBlockLambdaWhileStatement.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/afterBlockLambdaForInit.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/afterBlockLambdaForInit.java new file mode 100644 index 000000000000..0cd5b3049999 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/afterBlockLambdaForInit.java @@ -0,0 +1,12 @@ +// "Replace method call on lambda with lambda body" "true" + +public class Main { + public static void main(String[] args) { + int i = 0; + System.out.println("Hello"); + System.out.println("World"); + for (; i < 10; ) { + System.out.println(i++); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/afterBlockLambdaInFieldDeclaration.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/afterBlockLambdaInFieldDeclaration.java new file mode 100644 index 000000000000..3d17cb5c866d --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/afterBlockLambdaInFieldDeclaration.java @@ -0,0 +1,11 @@ +// "Replace method call on lambda with lambda body" "true" +import java.util.function.Supplier; + +class Test { + String str; + + { + String s = ""; + str = s; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/afterBlockLambdaWhileStatement.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/afterBlockLambdaWhileStatement.java new file mode 100644 index 000000000000..36dc264644ea --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/afterBlockLambdaWhileStatement.java @@ -0,0 +1,13 @@ +// "Replace method call on lambda with lambda body" "true" + +import java.util.function.Predicate; + +public class Test { + public static void main(String[] args) { + while(true) { + System.out.println("hello"); + if (!Collections.singleton("abc").contains("ab")) break; + System.out.println("hello"); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/beforeBlockLambdaForInit.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/beforeBlockLambdaForInit.java index f7dfcdede254..d7f9198edf92 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/beforeBlockLambdaForInit.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/beforeBlockLambdaForInit.java @@ -1,4 +1,4 @@ -// "Replace method call on lambda with lambda body" "false" +// "Replace method call on lambda with lambda body" "true" public class Main { public static void main(String[] args) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/beforeBlockLambdaInFieldDeclaration.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/beforeBlockLambdaInFieldDeclaration.java index 714721e2826e..5768218f6fb9 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/beforeBlockLambdaInFieldDeclaration.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/beforeBlockLambdaInFieldDeclaration.java @@ -1,4 +1,4 @@ -// "Replace method call on lambda with lambda body" "false" +// "Replace method call on lambda with lambda body" "true" import java.util.function.Supplier; class Test { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/beforeBlockLambdaWhileStatement.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/beforeBlockLambdaWhileStatement.java index 5306916f8d20..959f2457a7f3 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/beforeBlockLambdaWhileStatement.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/trivialFunctionalExpressionUsage/beforeBlockLambdaWhileStatement.java @@ -1,4 +1,4 @@ -// "Replace method call on lambda with lambda body" "false" +// "Replace method call on lambda with lambda body" "true" import java.util.function.Predicate; diff --git a/plugins/InspectionGadgets/src/com/intellij/codeInspection/TrivialFunctionalExpressionUsageInspection.java b/plugins/InspectionGadgets/src/com/intellij/codeInspection/TrivialFunctionalExpressionUsageInspection.java index 78ab4ba0dd1e..0fa5fde68e5c 100644 --- a/plugins/InspectionGadgets/src/com/intellij/codeInspection/TrivialFunctionalExpressionUsageInspection.java +++ b/plugins/InspectionGadgets/src/com/intellij/codeInspection/TrivialFunctionalExpressionUsageInspection.java @@ -11,7 +11,6 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.util.InlineUtil; import com.intellij.refactoring.util.LambdaRefactoringUtil; -import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.ObjectUtils; import com.siyeh.InspectionGadgetsBundle; @@ -66,23 +65,9 @@ public class TrivialFunctionalExpressionUsageInspection extends AbstractBaseJava if (!(ArrayUtil.getLastElement(statements) instanceof PsiReturnStatement)) { return false; } - if (returnStatements[0].getReturnValue() != null) { - if (callParent instanceof PsiLocalVariable) { - return true; - } - } } - if(callParent instanceof PsiExpressionStatement) { - PsiElement statementParent = callParent.getParent(); - // Disable in "for" initialization or update - if(statementParent instanceof PsiForStatement && callParent != ((PsiForStatement)statementParent).getBody()) { - return false; - } - } - - return (callParent instanceof PsiStatement && !(callParent instanceof PsiLoopStatement)) || - callParent instanceof PsiLambdaExpression; + return CodeBlockSurrounder.canSurround(call); }; Predicate checkWrites = call -> Arrays.stream(expression.getParameterList().getParameters()) @@ -166,8 +151,9 @@ public class TrivialFunctionalExpressionUsageInspection extends AbstractBaseJava PsiExpression[] arguments = callExpression.getArgumentList().getExpressions(); if (Stream.of(arguments).noneMatch(SideEffectChecker::mayHaveSideEffects)) return lambda; - lambda = RefactoringUtil.ensureCodeBlock(lambda); - if (lambda == null) return null; + CodeBlockSurrounder surrounder = CodeBlockSurrounder.forExpression(lambda); + if (surrounder == null) return null; + lambda = (PsiLambdaExpression)surrounder.surround().getExpression(); callExpression = PsiTreeUtil.getParentOfType(lambda, PsiMethodCallExpression.class); if (callExpression == null) return lambda; arguments = callExpression.getArgumentList().getExpressions(); @@ -210,8 +196,10 @@ public class TrivialFunctionalExpressionUsageInspection extends AbstractBaseJava } private static void replaceCodeBlock(PsiLambdaExpression element) { - element = RefactoringUtil.ensureCodeBlock(element); - if (element == null) return; + CodeBlockSurrounder surrounder = CodeBlockSurrounder.forExpression(element); + if (surrounder == null) return; + CodeBlockSurrounder.SurroundResult result = surrounder.surround(); + element = (PsiLambdaExpression)result.getExpression(); PsiElement body = element.getBody(); if (!(body instanceof PsiCodeBlock)) return; PsiMethodCallExpression callExpression = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class); @@ -223,18 +211,16 @@ public class TrivialFunctionalExpressionUsageInspection extends AbstractBaseJava final PsiStatement[] statements = ((PsiCodeBlock)body).getStatements(); PsiReturnStatement statement = null; if (statements.length > 0) { - PsiElement anchor = PsiTreeUtil.getParentOfType(parent, PsiStatement.class, false); + PsiElement anchor = result.getAnchor(); statement = ObjectUtils.tryCast(statements[statements.length - 1], PsiReturnStatement.class); - if (anchor != null) { - PsiElement gParent = anchor.getParent(); - if (hasNameConflict(statements, anchor, element)) { - gParent.addBefore(JavaPsiFacade.getElementFactory(element.getProject()).createStatementFromText(ct.text(body), anchor), anchor); - } - else { - for (PsiElement child = body.getFirstChild(); child != null; child = child.getNextSibling()) { - if (child != statement && !(child instanceof PsiJavaToken)) { - gParent.addBefore(ct.markUnchanged(child), anchor); - } + PsiElement gParent = anchor.getParent(); + if (hasNameConflict(statements, anchor, element)) { + gParent.addBefore(JavaPsiFacade.getElementFactory(element.getProject()).createStatementFromText(ct.text(body), anchor), anchor); + } + else { + for (PsiElement child = body.getFirstChild(); child != null; child = child.getNextSibling()) { + if (child != statement && !(child instanceof PsiJavaToken)) { + gParent.addBefore(ct.markUnchanged(child), anchor); } } }