Move statement: Add or remove empty lines correctly
#KT-14946 Fixed
This commit is contained in:
committed by
klunnii
parent
73dec25eb1
commit
8a595ad165
+48
-13
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.idea.codeInsight.upDownMover;
|
||||
|
||||
import com.intellij.codeInsight.editorActions.moveUpDown.LineRange;
|
||||
import com.intellij.openapi.editor.CaretModel;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
@@ -36,6 +37,8 @@ import java.util.List;
|
||||
public class KotlinDeclarationMover extends AbstractKotlinUpDownMover {
|
||||
|
||||
private boolean moveEnumConstant = false;
|
||||
private boolean moveOutOfBlock = false;
|
||||
private boolean moveIntoBlock = false;
|
||||
|
||||
private static int findNearestNonWhitespace(@NotNull CharSequence sequence, int index) {
|
||||
char ch = sequence.charAt(--index);
|
||||
@@ -48,8 +51,8 @@ public class KotlinDeclarationMover extends AbstractKotlinUpDownMover {
|
||||
@Override
|
||||
public void afterMove(@NotNull Editor editor, @NotNull PsiFile file, @NotNull MoveInfo info, boolean down) {
|
||||
super.afterMove(editor, file, info, down);
|
||||
Document document = editor.getDocument();
|
||||
if (moveEnumConstant) {
|
||||
Document document = editor.getDocument();
|
||||
CharSequence cs = document.getCharsSequence();
|
||||
int end1 = findNearestNonWhitespace(cs, info.range1.getEndOffset());
|
||||
char c1 = cs.charAt(end1);
|
||||
@@ -72,6 +75,27 @@ public class KotlinDeclarationMover extends AbstractKotlinUpDownMover {
|
||||
document.insertString(end1 + 1, ",");
|
||||
}
|
||||
}
|
||||
if (moveIntoBlock || moveOutOfBlock) {
|
||||
if (down) {
|
||||
if (moveIntoBlock) {
|
||||
document.deleteString(info.range1.getEndOffset(), info.range2.getStartOffset());
|
||||
}
|
||||
else {
|
||||
int offset = info.range1.getEndOffset();
|
||||
document.insertString(offset, "\n");
|
||||
CaretModel caretModel = editor.getCaretModel();
|
||||
if (document.getCharsSequence().charAt(caretModel.getOffset() - 1) == '\n') caretModel.moveToOffset(offset + 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (moveIntoBlock) {
|
||||
document.deleteString(info.range2.getEndOffset(), info.range1.getStartOffset());
|
||||
}
|
||||
else {
|
||||
document.insertString(info.range2.getEndOffset(), "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -228,7 +252,7 @@ public class KotlinDeclarationMover extends AbstractKotlinUpDownMover {
|
||||
PsiElement nextParent = null;
|
||||
|
||||
// moving out of code block
|
||||
if (sibling.getNode().getElementType() == (down ? KtTokens.RBRACE : KtTokens.LBRACE)) {
|
||||
if (isMovingOutOfBlock(sibling, down)) {
|
||||
// elements which aren't immediately placed in class body can't leave the block
|
||||
PsiElement parent = sibling.getParent();
|
||||
if (!(parent instanceof KtClassBody)) return null;
|
||||
@@ -246,18 +270,14 @@ public class KotlinDeclarationMover extends AbstractKotlinUpDownMover {
|
||||
// moving into code block
|
||||
// element may move only into class body
|
||||
else {
|
||||
if (sibling instanceof KtClassOrObject) {
|
||||
KtClassOrObject ktClassOrObject = (KtClassOrObject) sibling;
|
||||
KtClassBody classBody = ktClassOrObject.getBody();
|
||||
|
||||
// confined elements can't leave their block
|
||||
if (classBody != null) {
|
||||
nextParent = classBody;
|
||||
if (!down) {
|
||||
start = classBody.getRBrace();
|
||||
}
|
||||
end = down ? classBody.getLBrace() : classBody.getRBrace();
|
||||
KtClassBody classBody = getClassBody(sibling);
|
||||
// confined elements can't leave their block
|
||||
if (classBody != null) {
|
||||
nextParent = classBody;
|
||||
if (!down) {
|
||||
start = classBody.getRBrace();
|
||||
}
|
||||
end = down ? classBody.getLBrace() : classBody.getRBrace();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,6 +299,19 @@ public class KotlinDeclarationMover extends AbstractKotlinUpDownMover {
|
||||
return start != null && end != null ? new LineRange(start, end, editor.getDocument()) : null;
|
||||
}
|
||||
|
||||
private static boolean isMovingOutOfBlock(@NotNull PsiElement sibling, boolean down) {
|
||||
return sibling.getNode().getElementType() == (down ? KtTokens.RBRACE : KtTokens.LBRACE);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static KtClassBody getClassBody(PsiElement element) {
|
||||
if (element instanceof KtClassOrObject) {
|
||||
return ((KtClassOrObject) element).getBody();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkAvailable(@NotNull Editor editor, @NotNull PsiFile file, @NotNull MoveInfo info, boolean down) {
|
||||
if (!super.checkAvailable(editor, file, info, down)) return false;
|
||||
@@ -306,6 +339,8 @@ public class KotlinDeclarationMover extends AbstractKotlinUpDownMover {
|
||||
info.toMove2 = null;
|
||||
return true;
|
||||
}
|
||||
moveOutOfBlock = isMovingOutOfBlock(sibling, down);
|
||||
moveIntoBlock = getClassBody(sibling) != null;
|
||||
|
||||
info.toMove = sourceRange;
|
||||
info.toMove2 = getTargetRange(editor, sibling, down, sourceRange.firstElement);
|
||||
|
||||
+1
@@ -5,6 +5,7 @@ class A {
|
||||
val x = ""
|
||||
|
||||
}
|
||||
|
||||
// class B
|
||||
<caret>class B {
|
||||
|
||||
|
||||
+1
@@ -2,6 +2,7 @@
|
||||
<caret>class B {
|
||||
|
||||
}
|
||||
|
||||
// MOVE: up
|
||||
// class A
|
||||
class A {
|
||||
|
||||
+1
@@ -4,6 +4,7 @@ class A {
|
||||
// class B
|
||||
class B {
|
||||
}
|
||||
|
||||
// class C
|
||||
<caret>class C {
|
||||
|
||||
|
||||
+1
@@ -5,6 +5,7 @@ class A {
|
||||
<caret>class C {
|
||||
|
||||
}
|
||||
|
||||
// class B
|
||||
class B {
|
||||
}
|
||||
|
||||
+1
@@ -4,6 +4,7 @@ fun foo() {
|
||||
// class A
|
||||
class A {
|
||||
}
|
||||
|
||||
// class B
|
||||
<caret>class B {
|
||||
|
||||
|
||||
+1
@@ -5,6 +5,7 @@ fun foo() {
|
||||
<caret>class B {
|
||||
|
||||
}
|
||||
|
||||
// class A
|
||||
class A {
|
||||
}
|
||||
|
||||
Vendored
-1
@@ -1,6 +1,5 @@
|
||||
// class D
|
||||
class D {
|
||||
|
||||
// MOVE: down
|
||||
// class A
|
||||
<caret>class A
|
||||
|
||||
Vendored
-1
@@ -3,7 +3,6 @@
|
||||
class D {
|
||||
// class A
|
||||
<caret>class A
|
||||
|
||||
}
|
||||
|
||||
// class C
|
||||
|
||||
Vendored
-1
@@ -1,6 +1,5 @@
|
||||
// class D
|
||||
class D {
|
||||
|
||||
// MOVE: down
|
||||
// class A
|
||||
<caret>class A
|
||||
|
||||
Vendored
-1
@@ -3,5 +3,4 @@
|
||||
class D {
|
||||
// class A
|
||||
<caret>class A
|
||||
|
||||
}
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// MOVE: down
|
||||
class Outer {
|
||||
<caret>class N1 {
|
||||
fun foo1() {}
|
||||
}
|
||||
|
||||
class N2 {
|
||||
fun foo2() {}
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// MOVE: down
|
||||
class Outer {
|
||||
class N2 {
|
||||
<caret>class N1 {
|
||||
fun foo1() {}
|
||||
}
|
||||
fun foo2() {}
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// MOVE: down
|
||||
class Outer {
|
||||
class N2 {
|
||||
<caret>class N1 {
|
||||
fun foo1() {}
|
||||
}
|
||||
fun foo2() {}
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// MOVE: down
|
||||
class Outer {
|
||||
class N2 {
|
||||
fun foo2() {}
|
||||
<caret>class N1 {
|
||||
fun foo1() {}
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// MOVE: down
|
||||
class Outer {
|
||||
class N2 {
|
||||
fun foo2() {}
|
||||
<caret>class N1 {
|
||||
fun foo1() {}
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// MOVE: down
|
||||
class Outer {
|
||||
class N2 {
|
||||
fun foo2() {}
|
||||
}
|
||||
|
||||
<caret>class N1 {
|
||||
fun foo1() {}
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// MOVE: up
|
||||
class Outer {
|
||||
class N2 {
|
||||
fun foo2() {}
|
||||
}
|
||||
|
||||
<caret>class N1 {
|
||||
fun foo1() {}
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// MOVE: up
|
||||
class Outer {
|
||||
class N2 {
|
||||
fun foo2() {}
|
||||
<caret>class N1 {
|
||||
fun foo1() {}
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// MOVE: up
|
||||
class Outer {
|
||||
class N2 {
|
||||
fun foo2() {}
|
||||
<caret>class N1 {
|
||||
fun foo1() {}
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// MOVE: up
|
||||
class Outer {
|
||||
class N2 {
|
||||
<caret>class N1 {
|
||||
fun foo1() {}
|
||||
}
|
||||
fun foo2() {}
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// MOVE: up
|
||||
class Outer {
|
||||
class N2 {
|
||||
<caret>class N1 {
|
||||
fun foo1() {}
|
||||
}
|
||||
fun foo2() {}
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// MOVE: up
|
||||
class Outer {
|
||||
<caret>class N1 {
|
||||
fun foo1() {}
|
||||
}
|
||||
|
||||
class N2 {
|
||||
fun foo2() {}
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// MOVE: down
|
||||
class Outer {
|
||||
class N2 {
|
||||
fun foo2() {}
|
||||
<caret> class N1 {
|
||||
fun foo1() {}
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// MOVE: down
|
||||
class Outer {
|
||||
class N2 {
|
||||
fun foo2() {}
|
||||
}
|
||||
|
||||
<caret> class N1 {
|
||||
fun foo1() {}
|
||||
}
|
||||
}
|
||||
Vendored
+1
@@ -5,6 +5,7 @@ class A {
|
||||
val x = ""
|
||||
|
||||
}
|
||||
|
||||
// fun foo
|
||||
<caret>fun foo() {
|
||||
|
||||
|
||||
Vendored
+1
@@ -2,6 +2,7 @@
|
||||
<caret>fun foo() {
|
||||
|
||||
}
|
||||
|
||||
// MOVE: up
|
||||
// class A
|
||||
class A {
|
||||
|
||||
Vendored
+1
@@ -4,6 +4,7 @@ class A {
|
||||
// class B
|
||||
class B {
|
||||
}
|
||||
|
||||
// fun foo
|
||||
<caret>fun foo() {
|
||||
|
||||
|
||||
Vendored
+1
@@ -5,6 +5,7 @@ class A {
|
||||
<caret>fun foo() {
|
||||
|
||||
}
|
||||
|
||||
// class B
|
||||
class B {
|
||||
}
|
||||
|
||||
Vendored
+1
@@ -4,6 +4,7 @@ fun foo() {
|
||||
// class B
|
||||
class B {
|
||||
}
|
||||
|
||||
// fun foo
|
||||
<caret>fun foo() {
|
||||
|
||||
|
||||
Vendored
+1
@@ -5,6 +5,7 @@ fun foo() {
|
||||
<caret>fun foo() {
|
||||
|
||||
}
|
||||
|
||||
// class B
|
||||
class B {
|
||||
}
|
||||
|
||||
Vendored
+1
@@ -5,5 +5,6 @@ class A {
|
||||
val x = ""
|
||||
|
||||
}
|
||||
|
||||
// val y
|
||||
<caret>val y = ""
|
||||
|
||||
Vendored
+1
@@ -1,5 +1,6 @@
|
||||
// val x
|
||||
<caret>val x = ""
|
||||
|
||||
// MOVE: up
|
||||
// class A
|
||||
class A {
|
||||
|
||||
Vendored
+1
@@ -4,6 +4,7 @@ class A {
|
||||
// class B
|
||||
class B {
|
||||
}
|
||||
|
||||
// val y
|
||||
<caret>val y = ""
|
||||
}
|
||||
Vendored
+1
@@ -3,6 +3,7 @@
|
||||
class A {
|
||||
// val y
|
||||
<caret>val y = ""
|
||||
|
||||
// class B
|
||||
class B {
|
||||
}
|
||||
|
||||
Vendored
+1
@@ -4,6 +4,7 @@ fun foo() {
|
||||
// class B
|
||||
class B {
|
||||
}
|
||||
|
||||
// val y
|
||||
<caret>val y = ""
|
||||
}
|
||||
Vendored
+1
@@ -3,6 +3,7 @@
|
||||
fun foo() {
|
||||
// val y
|
||||
<caret>val y = ""
|
||||
|
||||
// class B
|
||||
class B {
|
||||
}
|
||||
|
||||
Generated
+35
@@ -194,6 +194,41 @@ public class MoveStatementTestGenerated extends AbstractMoveStatementTest {
|
||||
public void testClassWithoutBody4() throws Exception {
|
||||
runTest("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody4.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt-14946-1.kt")
|
||||
public void testKt_14946_1() throws Exception {
|
||||
runTest("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/kt-14946-1.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt-14946-2.kt")
|
||||
public void testKt_14946_2() throws Exception {
|
||||
runTest("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/kt-14946-2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt-14946-3.kt")
|
||||
public void testKt_14946_3() throws Exception {
|
||||
runTest("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/kt-14946-3.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt-14946-4.kt")
|
||||
public void testKt_14946_4() throws Exception {
|
||||
runTest("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/kt-14946-4.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt-14946-5.kt")
|
||||
public void testKt_14946_5() throws Exception {
|
||||
runTest("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/kt-14946-5.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt-14946-6.kt")
|
||||
public void testKt_14946_6() throws Exception {
|
||||
runTest("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/kt-14946-6.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt-14946-7.kt")
|
||||
public void testKt_14946_7() throws Exception {
|
||||
runTest("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/kt-14946-7.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer")
|
||||
|
||||
Reference in New Issue
Block a user