From 2e30e0c45755846dc3cd3af3126259737ee4511a Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Wed, 21 Nov 2018 17:29:44 +0100 Subject: [PATCH] switch expressions: ensure code block around extracted variable (IDEA-202630) --- .../introduceVariable/VariableExtractor.java | 6 ++++++ .../refactoring/util/EnsureCodeBlockImpl.java | 11 +++++++++++ ...eBlockAroundBreakStatementJava12Preview.after.java | 10 ++++++++++ ...ureCodeBlockAroundBreakStatementJava12Preview.java | 7 +++++++ .../java/refactoring/IntroduceVariableTest.java | 4 ++++ 5 files changed, 38 insertions(+) create mode 100644 java/java-tests/testData/refactoring/introduceVariable/EnsureCodeBlockAroundBreakStatementJava12Preview.after.java create mode 100644 java/java-tests/testData/refactoring/introduceVariable/EnsureCodeBlockAroundBreakStatementJava12Preview.java diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/VariableExtractor.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/VariableExtractor.java index cb2e64d47115..f16422394e8a 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/VariableExtractor.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/VariableExtractor.java @@ -120,6 +120,12 @@ class VariableExtractor { if (myAnchor instanceof PsiExpression) { myAnchor = RefactoringUtil.getParentStatement(RefactoringUtil.ensureCodeBlock(((PsiExpression)myAnchor)), false); } + else if (myAnchor instanceof PsiSwitchLabeledRuleStatement) { + PsiStatement body = ((PsiSwitchLabeledRuleStatement)myAnchor).getBody(); + if (body instanceof PsiExpressionStatement) { + myAnchor = RefactoringUtil.getParentStatement(RefactoringUtil.ensureCodeBlock(((PsiExpressionStatement)body).getExpression()), false); + } + } } private void highlight(PsiVariable var) { diff --git a/java/java-impl/src/com/intellij/refactoring/util/EnsureCodeBlockImpl.java b/java/java-impl/src/com/intellij/refactoring/util/EnsureCodeBlockImpl.java index 51eb01211624..7de185c3c84f 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/EnsureCodeBlockImpl.java +++ b/java/java-impl/src/com/intellij/refactoring/util/EnsureCodeBlockImpl.java @@ -81,6 +81,17 @@ class EnsureCodeBlockImpl { if (parent instanceof PsiReturnStatement && condition != null) { return replace(expression, parent, (oldParent, copy) -> splitReturn((PsiReturnStatement)oldParent, condition, operand)); } + if (parent instanceof PsiSwitchLabeledRuleStatement) { + PsiStatement body = ((PsiSwitchLabeledRuleStatement)parent).getBody(); + if (body instanceof PsiExpressionStatement) { + PsiExpression resultExpression = ((PsiExpressionStatement)body).getExpression(); + return replace(expression, body, (old, copy) -> { + PsiBlockStatement block = (PsiBlockStatement)old.replace(factory.createStatementFromText("{break a;}", resultExpression)); + PsiExpression copyExpression = ((PsiBreakStatement)block.getCodeBlock().getStatements()[0]).getExpression(); + return Objects.requireNonNull(copyExpression).replace(((PsiExpressionStatement)copy).getExpression()); + }); + } + } return expression; } diff --git a/java/java-tests/testData/refactoring/introduceVariable/EnsureCodeBlockAroundBreakStatementJava12Preview.after.java b/java/java-tests/testData/refactoring/introduceVariable/EnsureCodeBlockAroundBreakStatementJava12Preview.after.java new file mode 100644 index 000000000000..3679e1e44a01 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/EnsureCodeBlockAroundBreakStatementJava12Preview.after.java @@ -0,0 +1,10 @@ +class MyTest { + void m(int i) { + String s = switch (i) { + default -> { + String temp = "abc"; + break temp; + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/introduceVariable/EnsureCodeBlockAroundBreakStatementJava12Preview.java b/java/java-tests/testData/refactoring/introduceVariable/EnsureCodeBlockAroundBreakStatementJava12Preview.java new file mode 100644 index 000000000000..8e07177ea7a8 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/EnsureCodeBlockAroundBreakStatementJava12Preview.java @@ -0,0 +1,7 @@ +class MyTest { + void m(int i) { + String s = switch (i) { + default -> "abc"; + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/refactoring/IntroduceVariableTest.java b/java/java-tests/testSrc/com/intellij/java/refactoring/IntroduceVariableTest.java index f0fc48339c22..24384abe7aa6 100644 --- a/java/java-tests/testSrc/com/intellij/java/refactoring/IntroduceVariableTest.java +++ b/java/java-tests/testSrc/com/intellij/java/refactoring/IntroduceVariableTest.java @@ -247,6 +247,10 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase { doTest(new MockIntroduceVariableHandler("temp", true, false, false, CommonClassNames.JAVA_LANG_STRING)); } + public void testEnsureCodeBlockAroundBreakStatementJava12Preview() { + doTest(new MockIntroduceVariableHandler("temp", true, false, false, CommonClassNames.JAVA_LANG_STRING)); + } + public void testDeclareTernary() { doTest(new MockIntroduceVariableHandler("temp", true, false, false, CommonClassNames.JAVA_LANG_STRING)); }