diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInsight/upDownMover/KotlinExpressionMover.java b/idea/src/org/jetbrains/kotlin/idea/codeInsight/upDownMover/KotlinExpressionMover.java index 3cd704e18ee..74a14015f62 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInsight/upDownMover/KotlinExpressionMover.java +++ b/idea/src/org/jetbrains/kotlin/idea/codeInsight/upDownMover/KotlinExpressionMover.java @@ -229,16 +229,57 @@ public class KotlinExpressionMover extends AbstractKotlinUpDownMover { @Nullable private static LineRange getExpressionTargetRange(@NotNull Editor editor, @NotNull PsiElement sibling, boolean down) { - if (sibling instanceof KtIfExpression && !down) { - KtExpression elseBranch = ((KtIfExpression) sibling).getElse(); - if (elseBranch instanceof KtBlockExpression) { - sibling = elseBranch; - } - } PsiElement start = sibling; PsiElement end = sibling; + if (!down) { + if (sibling instanceof KtIfExpression) { + KtIfExpression ifExpression = (KtIfExpression) sibling; + KtExpression elseExpression = ifExpression.getElse(); + while (elseExpression instanceof KtIfExpression) { + KtIfExpression elseIfExpression = (KtIfExpression) elseExpression; + KtExpression next = elseIfExpression.getElse(); + if (next == null) { + elseExpression = elseIfExpression.getThen(); + break; + } + elseExpression = next; + } + if (elseExpression instanceof KtBlockExpression) { + sibling = elseExpression; + start = sibling; + } + + } else if (sibling instanceof KtWhenExpression) { + List entries = ((KtWhenExpression) sibling).getEntries(); + if (!entries.isEmpty()) { + KtWhenEntry lastEntry = null; + for (KtWhenEntry entry : entries) { + if (entry.getExpression() instanceof KtBlockExpression) lastEntry = entry; + } + if (lastEntry != null) { + sibling = lastEntry; + start = sibling; + } + } + + } else if (sibling instanceof KtTryExpression) { + KtTryExpression tryExpression = (KtTryExpression) sibling; + KtFinallySection finallyBlock = tryExpression.getFinallyBlock(); + if (finallyBlock != null) { + sibling = finallyBlock; + start = sibling; + } else { + List clauses = tryExpression.getCatchClauses(); + if (!clauses.isEmpty()) { + sibling = clauses.get(clauses.size() - 1); + start = sibling; + } + } + } + } + // moving out of code block if (sibling.getNode().getElementType() == (down ? KtTokens.RBRACE : KtTokens.LBRACE)) { PsiElement parent = sibling.getParent(); diff --git a/idea/testData/codeInsight/moveUpDown/expressions/intoCatch.kt b/idea/testData/codeInsight/moveUpDown/expressions/intoCatch.kt new file mode 100644 index 00000000000..671db8bdee7 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/intoCatch.kt @@ -0,0 +1,10 @@ +// MOVE: up +fun test() { + try { + run { + } + } catch (e: Exception) { + } catch (e: Throwable) { + } + println() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/intoCatch.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/intoCatch.kt.after new file mode 100644 index 00000000000..d1060047d75 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/intoCatch.kt.after @@ -0,0 +1,10 @@ +// MOVE: up +fun test() { + try { + run { + } + } catch (e: Exception) { + } catch (e: Throwable) { + println() + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/intoElse3.kt b/idea/testData/codeInsight/moveUpDown/expressions/intoElse3.kt new file mode 100644 index 00000000000..321d3d680f3 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/intoElse3.kt @@ -0,0 +1,9 @@ +// MOVE: up +fun test(i: Int) { + if (i == 1) { + run { + } + } else { + } + println() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/intoElse3.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/intoElse3.kt.after new file mode 100644 index 00000000000..8fc9ad0e4fc --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/intoElse3.kt.after @@ -0,0 +1,9 @@ +// MOVE: up +fun test(i: Int) { + if (i == 1) { + run { + } + } else { + println() + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/intoElse4.kt b/idea/testData/codeInsight/moveUpDown/expressions/intoElse4.kt new file mode 100644 index 00000000000..909eb680075 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/intoElse4.kt @@ -0,0 +1,11 @@ +// MOVE: up +fun test(i: Int) { + if (i == 1) { + run { + } + } else if (i == 2) { + } else if (i == 3) { + } else { + } + println() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/intoElse4.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/intoElse4.kt.after new file mode 100644 index 00000000000..b0632b58e04 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/intoElse4.kt.after @@ -0,0 +1,11 @@ +// MOVE: up +fun test(i: Int) { + if (i == 1) { + run { + } + } else if (i == 2) { + } else if (i == 3) { + } else { + println() + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/intoElseIf.kt b/idea/testData/codeInsight/moveUpDown/expressions/intoElseIf.kt new file mode 100644 index 00000000000..8acbf918d7d --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/intoElseIf.kt @@ -0,0 +1,10 @@ +// MOVE: up +fun test(i: Int) { + if (i == 1) { + run { + } + } else if (i == 2) { + } else if (i == 3) { + } + println() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/intoElseIf.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/intoElseIf.kt.after new file mode 100644 index 00000000000..2f1806c23d5 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/intoElseIf.kt.after @@ -0,0 +1,10 @@ +// MOVE: up +fun test(i: Int) { + if (i == 1) { + run { + } + } else if (i == 2) { + } else if (i == 3) { + println() + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/intoFinally.kt b/idea/testData/codeInsight/moveUpDown/expressions/intoFinally.kt new file mode 100644 index 00000000000..ebe1ecbe47f --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/intoFinally.kt @@ -0,0 +1,11 @@ +// MOVE: up +fun test() { + try { + run { + } + } catch (e: Exception) { + } catch (e: Throwable) { + } finally { + } + println() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/intoFinally.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/intoFinally.kt.after new file mode 100644 index 00000000000..5284448ebd8 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/intoFinally.kt.after @@ -0,0 +1,11 @@ +// MOVE: up +fun test() { + try { + run { + } + } catch (e: Exception) { + } catch (e: Throwable) { + } finally { + println() + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/intoWhenElse.kt b/idea/testData/codeInsight/moveUpDown/expressions/intoWhenElse.kt new file mode 100644 index 00000000000..c22736524f3 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/intoWhenElse.kt @@ -0,0 +1,14 @@ +// MOVE: up +fun test(i: Int) { + when (i) { + 1 -> { + run { + } + } + 2 -> { + } + else -> { + } + } + println() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/intoWhenElse.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/intoWhenElse.kt.after new file mode 100644 index 00000000000..2c5b1fa8f6b --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/intoWhenElse.kt.after @@ -0,0 +1,14 @@ +// MOVE: up +fun test(i: Int) { + when (i) { + 1 -> { + run { + } + } + 2 -> { + } + else -> { + println() + } + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/intoWhenEntry.kt b/idea/testData/codeInsight/moveUpDown/expressions/intoWhenEntry.kt new file mode 100644 index 00000000000..b60b5bf109f --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/intoWhenEntry.kt @@ -0,0 +1,14 @@ +// MOVE: up +fun test(i: Int) { + when (i) { + 1 -> { + run { + } + } + 2 -> { + } + 3 -> { + } + } + println() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/intoWhenEntry.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/intoWhenEntry.kt.after new file mode 100644 index 00000000000..7381e49c36e --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/intoWhenEntry.kt.after @@ -0,0 +1,14 @@ +// MOVE: up +fun test(i: Int) { + when (i) { + 1 -> { + run { + } + } + 2 -> { + } + 3 -> { + println() + } + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/moveUpDown/MoveStatementTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/moveUpDown/MoveStatementTestGenerated.java index 67fa2881e52..6264416b011 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/moveUpDown/MoveStatementTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/moveUpDown/MoveStatementTestGenerated.java @@ -987,6 +987,12 @@ public class MoveStatementTestGenerated extends AbstractMoveStatementTest { doTestExpression(fileName); } + @TestMetadata("intoCatch.kt") + public void testIntoCatch() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/moveUpDown/expressions/intoCatch.kt"); + doTestExpression(fileName); + } + @TestMetadata("intoClosure1.kt") public void testIntoClosure1() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/moveUpDown/expressions/intoClosure1.kt"); @@ -1017,6 +1023,30 @@ public class MoveStatementTestGenerated extends AbstractMoveStatementTest { doTestExpression(fileName); } + @TestMetadata("intoElse3.kt") + public void testIntoElse3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/moveUpDown/expressions/intoElse3.kt"); + doTestExpression(fileName); + } + + @TestMetadata("intoElse4.kt") + public void testIntoElse4() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/moveUpDown/expressions/intoElse4.kt"); + doTestExpression(fileName); + } + + @TestMetadata("intoElseIf.kt") + public void testIntoElseIf() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/moveUpDown/expressions/intoElseIf.kt"); + doTestExpression(fileName); + } + + @TestMetadata("intoFinally.kt") + public void testIntoFinally() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/moveUpDown/expressions/intoFinally.kt"); + doTestExpression(fileName); + } + @TestMetadata("intoNestedClosure1.kt") public void testIntoNestedClosure1() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/moveUpDown/expressions/intoNestedClosure1.kt"); @@ -1035,6 +1065,18 @@ public class MoveStatementTestGenerated extends AbstractMoveStatementTest { doTestExpression(fileName); } + @TestMetadata("intoWhenElse.kt") + public void testIntoWhenElse() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/moveUpDown/expressions/intoWhenElse.kt"); + doTestExpression(fileName); + } + + @TestMetadata("intoWhenEntry.kt") + public void testIntoWhenEntry() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/moveUpDown/expressions/intoWhenEntry.kt"); + doTestExpression(fileName); + } + @TestMetadata("lambda1.kt") public void testLambda1() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/moveUpDown/expressions/lambda1.kt");