KT-20282 'Move statement up' works incorrectly for statement after 'finally' block if 'try' block contains closure

This commit is contained in:
Toshiaki Kameyama
2018-03-01 19:23:11 +09:00
committed by Nikolay Krasko
parent d3b1b7a5be
commit 9d6b36c249
16 changed files with 247 additions and 6 deletions
@@ -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<KtWhenEntry> 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<KtCatchClause> 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();
@@ -0,0 +1,10 @@
// MOVE: up
fun test() {
try {
run {
}
} catch (e: Exception) {
} catch (e: Throwable) {
}
<caret>println()
}
@@ -0,0 +1,10 @@
// MOVE: up
fun test() {
try {
run {
}
} catch (e: Exception) {
} catch (e: Throwable) {
<caret>println()
}
}
@@ -0,0 +1,9 @@
// MOVE: up
fun test(i: Int) {
if (i == 1) {
run {
}
} else {
}
<caret>println()
}
@@ -0,0 +1,9 @@
// MOVE: up
fun test(i: Int) {
if (i == 1) {
run {
}
} else {
<caret>println()
}
}
@@ -0,0 +1,11 @@
// MOVE: up
fun test(i: Int) {
if (i == 1) {
run {
}
} else if (i == 2) {
} else if (i == 3) {
} else {
}
<caret>println()
}
@@ -0,0 +1,11 @@
// MOVE: up
fun test(i: Int) {
if (i == 1) {
run {
}
} else if (i == 2) {
} else if (i == 3) {
} else {
<caret>println()
}
}
@@ -0,0 +1,10 @@
// MOVE: up
fun test(i: Int) {
if (i == 1) {
run {
}
} else if (i == 2) {
} else if (i == 3) {
}
<caret>println()
}
@@ -0,0 +1,10 @@
// MOVE: up
fun test(i: Int) {
if (i == 1) {
run {
}
} else if (i == 2) {
} else if (i == 3) {
<caret>println()
}
}
@@ -0,0 +1,11 @@
// MOVE: up
fun test() {
try {
run {
}
} catch (e: Exception) {
} catch (e: Throwable) {
} finally {
}
<caret>println()
}
@@ -0,0 +1,11 @@
// MOVE: up
fun test() {
try {
run {
}
} catch (e: Exception) {
} catch (e: Throwable) {
} finally {
<caret>println()
}
}
@@ -0,0 +1,14 @@
// MOVE: up
fun test(i: Int) {
when (i) {
1 -> {
run {
}
}
2 -> {
}
else -> {
}
}
<caret>println()
}
@@ -0,0 +1,14 @@
// MOVE: up
fun test(i: Int) {
when (i) {
1 -> {
run {
}
}
2 -> {
}
else -> {
<caret>println()
}
}
}
@@ -0,0 +1,14 @@
// MOVE: up
fun test(i: Int) {
when (i) {
1 -> {
run {
}
}
2 -> {
}
3 -> {
}
}
<caret>println()
}
@@ -0,0 +1,14 @@
// MOVE: up
fun test(i: Int) {
when (i) {
1 -> {
run {
}
}
2 -> {
}
3 -> {
<caret>println()
}
}
}
@@ -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");