From 93592a4c9e9f1bbefbf7ad5e2f93fe4f0fdd0532 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Fri, 18 Oct 2024 10:02:32 +0200 Subject: [PATCH] [java-refactoring] CodeBlockSurrounder: avoid collapsing with unrelated if-statement Fixes IDEA-360579 Inline Method creates uncompilable code (cherry picked from commit cd73e3e730b8cef37f4a26235a2ab3db812f02ff) IJ-CR-147183 GitOrigin-RevId: 0258e753bfb5f7e66bc4a0526769fe8ba07aa02c --- .../siyeh/ig/psiutils/CodeBlockSurrounder.java | 8 +++++--- .../inlineMethod/BooleanResultInIfChain.java | 16 ++++++++++++++++ .../BooleanResultInIfChain.java.after | 15 +++++++++++++++ .../refactoring/inline/InlineMethodTest.java | 2 ++ 4 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 java/java-tests/testData/refactoring/inlineMethod/BooleanResultInIfChain.java create mode 100644 java/java-tests/testData/refactoring/inlineMethod/BooleanResultInIfChain.java.after diff --git a/java/java-analysis-impl/src/com/siyeh/ig/psiutils/CodeBlockSurrounder.java b/java/java-analysis-impl/src/com/siyeh/ig/psiutils/CodeBlockSurrounder.java index ead74f2db8f6..07d5feda8000 100644 --- a/java/java-analysis-impl/src/com/siyeh/ig/psiutils/CodeBlockSurrounder.java +++ b/java/java-analysis-impl/src/com/siyeh/ig/psiutils/CodeBlockSurrounder.java @@ -835,6 +835,7 @@ public abstract class CodeBlockSurrounder { private static class AndOrToIfSurrounder extends CodeBlockSurrounder { private final @NotNull PsiPolyadicExpression myPolyadicExpression; private final @NotNull CodeBlockSurrounder myUpstream; + private PsiIfStatement myCreatedIf; AndOrToIfSurrounder(@NotNull PsiExpression expression, @NotNull PsiPolyadicExpression polyadicExpression, @@ -894,7 +895,7 @@ public abstract class CodeBlockSurrounder { } @NotNull - private static PsiStatement splitReturn(@NotNull PsiStatement returnOrYieldStatement, + private PsiStatement splitReturn(@NotNull PsiStatement returnOrYieldStatement, @NotNull PsiPolyadicExpression condition, @NotNull PsiExpression lOperands, @NotNull PsiExpression rOperands, @@ -906,7 +907,8 @@ public abstract class CodeBlockSurrounder { String extractedCondition = orChain ? ct.text(lOperands) : BoolUtils.getNegatedExpressionText(lOperands, ct); String ifText = "if(" + extractedCondition + ") " + keyword + " " + orChain + ";"; PsiStatement ifStatement = factory.createStatementFromText(ifText, returnOrYieldStatement); - CodeStyleManager.getInstance(project).reformat(returnOrYieldStatement.getParent().addBefore(ifStatement, returnOrYieldStatement)); + myCreatedIf = (PsiIfStatement)CodeStyleManager.getInstance(project) + .reformat(returnOrYieldStatement.getParent().addBefore(ifStatement, returnOrYieldStatement)); ct.replaceAndRestoreComments(Objects.requireNonNull(condition), rOperands); return returnOrYieldStatement; } @@ -936,7 +938,7 @@ public abstract class CodeBlockSurrounder { } } PsiIfStatement ifStatement = tryCast(PsiTreeUtil.skipWhitespacesAndCommentsBackward(anchor), PsiIfStatement.class); - if (ifStatement == null) return; + if (ifStatement == null || ifStatement != myCreatedIf) return; PsiStatement result = collapseIf(ifStatement, "&&", "||"); if (result == null) return; myUpstream.collapse(myUpstream.anchor(result)); diff --git a/java/java-tests/testData/refactoring/inlineMethod/BooleanResultInIfChain.java b/java/java-tests/testData/refactoring/inlineMethod/BooleanResultInIfChain.java new file mode 100644 index 000000000000..f53193b433cf --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineMethod/BooleanResultInIfChain.java @@ -0,0 +1,16 @@ +// IDEA-360579 +class Hades { + void persephone(boolean xyz, int param) { + if(xyz && !inlineMe(param)){ + System.out.println(); + } + } + + boolean inlineMe(int param) { + boolean result = false; + if (param >= 10) { + result = param != 20; + } + return result; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inlineMethod/BooleanResultInIfChain.java.after b/java/java-tests/testData/refactoring/inlineMethod/BooleanResultInIfChain.java.after new file mode 100644 index 000000000000..5aec1eff2fd8 --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineMethod/BooleanResultInIfChain.java.after @@ -0,0 +1,15 @@ +// IDEA-360579 +class Hades { + void persephone(boolean xyz, int param) { + if(xyz) { + boolean result = false; + if (param >= 10) { + result = param != 20; + } + if (!result) { + System.out.println(); + } + } + } + +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/refactoring/inline/InlineMethodTest.java b/java/java-tests/testSrc/com/intellij/java/refactoring/inline/InlineMethodTest.java index cf616533e568..5de46a4a5214 100644 --- a/java/java-tests/testSrc/com/intellij/java/refactoring/inline/InlineMethodTest.java +++ b/java/java-tests/testSrc/com/intellij/java/refactoring/inline/InlineMethodTest.java @@ -592,6 +592,8 @@ public class InlineMethodTest extends LightRefactoringTestCase { public void testRenameLocalClassDoubleConflict() { doTest(); } + public void testBooleanResultInIfChain() { doTest(); } + public void testInlineSingleImplementation() { TestDialogManager.setTestDialog(TestDialog.YES, getTestRootDisposable()); doTest();