Code mover fix: correct commas / semicolons after enum entries, relevant test fixes, extra tests

This commit is contained in:
Mikhail Glukhikh
2015-08-06 14:33:07 +03:00
parent 3f14e74b08
commit adf43519d6
16 changed files with 108 additions and 52 deletions
@@ -21,9 +21,7 @@ import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiComment;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -34,7 +32,44 @@ import java.util.ArrayList;
import java.util.List;
public class JetDeclarationMover extends AbstractJetUpDownMover {
public JetDeclarationMover() {
private boolean moveEnumConstant = false;
private static int findNearestNonWhitespace(@NotNull CharSequence sequence, int index) {
char ch = sequence.charAt(--index);
while (Character.isWhitespace(ch)) {
ch = sequence.charAt(--index);
}
return index;
}
@Override
public void afterMove(@NotNull Editor editor, @NotNull PsiFile file, @NotNull MoveInfo info, boolean down) {
super.afterMove(editor, file, info, down);
if (moveEnumConstant) {
Document document = editor.getDocument();
CharSequence cs = document.getCharsSequence();
int end1 = findNearestNonWhitespace(cs, info.range1.getEndOffset());
char c1 = cs.charAt(end1);
int end2 = findNearestNonWhitespace(cs, info.range2.getEndOffset());
char c2 = cs.charAt(end2);
if (c1 == c2 || (c1 != ',' && c2 != ',')) return;
if (c1 == ';' || c2 == ';') {
// Replace comma with semicolon and vice versa
document.replaceString(end1, end1 + 1, String.valueOf(c2));
document.replaceString(end2, end2 + 1, String.valueOf(c1));
}
else if (c1 == ',') {
// Move comma from the end of range1 to the end of range2
document.deleteString(end1, end1 + 1);
document.insertString(end2 + 1, ",");
}
else {
// Move comma from the end of range2 to the end of range1
document.deleteString(end2, end2 + 1);
document.insertString(end1 + 1, ",");
}
}
}
@NotNull
@@ -180,6 +215,7 @@ public class JetDeclarationMover extends AbstractJetUpDownMover {
// elements which aren't immediately placed in class body can't leave the block
PsiElement parent = sibling.getParent();
if (!(parent instanceof JetClassBody)) return null;
if (target instanceof JetEnumEntry) return null;
JetClassOrObject jetClassOrObject = (JetClassOrObject) parent.getParent();
assert jetClassOrObject != null;
@@ -226,10 +262,6 @@ public class JetDeclarationMover extends AbstractJetUpDownMover {
return start != null && end != null ? new LineRange(start, end, editor.getDocument()) : null;
}
private static boolean isEmptyPackageDirective(PsiElement adjustedSibling) {
return adjustedSibling instanceof JetPackageDirective && adjustedSibling.getTextLength() == 0;
}
@Override
public boolean checkAvailable(@NotNull Editor editor, @NotNull PsiFile file, @NotNull MoveInfo info, boolean down) {
if (!super.checkAvailable(editor, file, info, down)) return false;
@@ -242,6 +274,8 @@ public class JetDeclarationMover extends AbstractJetUpDownMover {
JetDeclaration firstDecl = getMovableDeclaration(psiRange.getFirst());
if (firstDecl == null) return false;
moveEnumConstant = firstDecl instanceof JetEnumEntry;
JetDeclaration lastDecl = getMovableDeclaration(psiRange.getSecond());
if (lastDecl == null) return false;
@@ -4,7 +4,7 @@ class A {
// class B
enum class B {
// X
<caret>X
<caret>X,
// Y
Y
}
@@ -4,7 +4,7 @@ class A {
// class B
enum class B {
// Y
Y
Y,
// X
<caret>X
}
@@ -5,7 +5,7 @@ class A {
// class B
enum class B {
// X
<caret>X
<caret>X,
// Y
Y
}
@@ -5,7 +5,7 @@ class A {
// class B
enum class B {
// X
X
X,
// Y
<caret>Y
}
@@ -4,7 +4,7 @@ class A {
// class B
enum class B {
// X
X
X,
// Y
<caret>Y
}
@@ -4,7 +4,7 @@ class A {
// class B
enum class B {
// Y
<caret>Y
<caret>Y,
// X
X
}
@@ -1,15 +1,16 @@
// MOVE: up
// IS_APPLICABLE: false
// class A
enum class A {
// U
U
U,
// V
V
V;
// class B
enum class B {
// X
<caret>X
<caret>X,
// Y
Y
}
@@ -1,16 +0,0 @@
// MOVE: up
// class A
enum class A {
// U
U
// V
V
// X
X
// class B
enum class B {
// Y
Y
}
}
@@ -1,15 +1,16 @@
// MOVE: down
// IS_APPLICABLE: false
// class A
enum class A {
// U
U
U,
// V
V
V;
// class B
enum class B {
// X
X
X,
// Y
<caret>Y
}
@@ -1,16 +0,0 @@
// MOVE: down
// class A
enum class A {
// U
U
// V
V
// class B
enum class B {
// X
X
}
// Y
<caret>Y
}
@@ -0,0 +1,10 @@
// MOVE: down
// class My
enum class My {
// first
FIRST,
// second
<caret>SECOND,
// last
LAST;
}
@@ -0,0 +1,10 @@
// MOVE: down
// class My
enum class My {
// first
FIRST,
// last
LAST,
// second
<caret>SECOND;
}
@@ -0,0 +1,10 @@
// MOVE: up
// class My
enum class My {
// first
FIRST,
// second
SECOND,
// last
<caret>LAST;
}
@@ -0,0 +1,10 @@
// MOVE: up
// class My
enum class My {
// first
FIRST,
// last
<caret>LAST,
// second
SECOND;
}
@@ -323,6 +323,18 @@ public class CodeMoverTestGenerated extends AbstractCodeMoverTest {
String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum6.kt");
doTestClassBodyDeclaration(fileName);
}
@TestMetadata("enum7.kt")
public void testEnum7() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum7.kt");
doTestClassBodyDeclaration(fileName);
}
@TestMetadata("enum8.kt")
public void testEnum8() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum8.kt");
doTestClassBodyDeclaration(fileName);
}
}
@TestMetadata("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function")