Add support of "braceless" blocks
This commit is contained in:
@@ -2,12 +2,9 @@ package org.jetbrains.jet.plugin.codeInsight.upDownMover;
|
|||||||
|
|
||||||
import com.intellij.codeInsight.editorActions.moveUpDown.LineMover;
|
import com.intellij.codeInsight.editorActions.moveUpDown.LineMover;
|
||||||
import com.intellij.codeInsight.editorActions.moveUpDown.LineRange;
|
import com.intellij.codeInsight.editorActions.moveUpDown.LineRange;
|
||||||
import com.intellij.openapi.editor.Document;
|
|
||||||
import com.intellij.openapi.editor.Editor;
|
import com.intellij.openapi.editor.Editor;
|
||||||
import com.intellij.openapi.util.TextRange;
|
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.PsiFile;
|
import com.intellij.psi.PsiFile;
|
||||||
import com.intellij.psi.PsiWhiteSpace;
|
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -17,41 +14,6 @@ public abstract class AbstractJetUpDownMover extends LineMover {
|
|||||||
protected AbstractJetUpDownMover() {
|
protected AbstractJetUpDownMover() {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static PsiElement adjustWhiteSpaceSibling(
|
|
||||||
@NotNull Editor editor,
|
|
||||||
@NotNull LineRange sourceRange,
|
|
||||||
@NotNull MoveInfo info,
|
|
||||||
boolean down
|
|
||||||
) {
|
|
||||||
PsiElement sibling = down ? sourceRange.lastElement.getNextSibling() : sourceRange.firstElement.getPrevSibling();
|
|
||||||
|
|
||||||
if (sibling instanceof PsiWhiteSpace) {
|
|
||||||
Document doc = editor.getDocument();
|
|
||||||
TextRange spaceRange = sibling.getTextRange();
|
|
||||||
|
|
||||||
int startLine = doc.getLineNumber(spaceRange.getStartOffset());
|
|
||||||
int endLine = doc.getLineNumber(spaceRange.getEndOffset());
|
|
||||||
|
|
||||||
if (endLine - startLine > 1) {
|
|
||||||
int nearLine = down ? sourceRange.endLine : sourceRange.startLine - 1;
|
|
||||||
|
|
||||||
info.toMove = sourceRange;
|
|
||||||
info.toMove2 = new LineRange(nearLine, nearLine + 1);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
sibling = firstNonWhiteElement(sibling, down);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sibling == null) {
|
|
||||||
info.toMove2 = null;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sibling;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
protected static PsiElement getSiblingOfType(@NotNull PsiElement element, boolean down, @NotNull Class<? extends PsiElement> type) {
|
protected static PsiElement getSiblingOfType(@NotNull PsiElement element, boolean down, @NotNull Class<? extends PsiElement> type) {
|
||||||
return down ? PsiTreeUtil.getNextSiblingOfType(element, type) : PsiTreeUtil.getPrevSiblingOfType(element, type);
|
return down ? PsiTreeUtil.getNextSiblingOfType(element, type) : PsiTreeUtil.getPrevSiblingOfType(element, type);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import com.intellij.openapi.util.TextRange;
|
|||||||
import com.intellij.psi.PsiComment;
|
import com.intellij.psi.PsiComment;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.PsiFile;
|
import com.intellij.psi.PsiFile;
|
||||||
|
import com.intellij.psi.PsiWhiteSpace;
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -181,15 +182,13 @@ public class JetExpressionMover extends AbstractJetUpDownMover {
|
|||||||
// moving out of code block
|
// moving out of code block
|
||||||
if (sibling.getNode().getElementType() == (down ? JetTokens.RBRACE : JetTokens.LBRACE)) {
|
if (sibling.getNode().getElementType() == (down ? JetTokens.RBRACE : JetTokens.LBRACE)) {
|
||||||
PsiElement parent = sibling.getParent();
|
PsiElement parent = sibling.getParent();
|
||||||
if (!(parent instanceof JetBlockExpression)) return null;
|
if (!(parent instanceof JetBlockExpression || parent instanceof JetFunctionLiteral)) return null;
|
||||||
|
|
||||||
JetBlockExpression block = (JetBlockExpression) parent;
|
|
||||||
|
|
||||||
JetBlockExpression newBlock = findClosestBlock(sibling, down);
|
JetBlockExpression newBlock = findClosestBlock(sibling, down);
|
||||||
if (newBlock == null) return null;
|
if (newBlock == null) return null;
|
||||||
|
|
||||||
if (PsiTreeUtil.isAncestor(newBlock, block, true)) {
|
if (PsiTreeUtil.isAncestor(newBlock, parent, true)) {
|
||||||
PsiElement outermostParent = JetPsiUtil.getOutermostParent(block, newBlock, true);
|
PsiElement outermostParent = JetPsiUtil.getOutermostParent(parent, newBlock, true);
|
||||||
|
|
||||||
if (down) {
|
if (down) {
|
||||||
end = outermostParent;
|
end = outermostParent;
|
||||||
@@ -212,7 +211,7 @@ public class JetExpressionMover extends AbstractJetUpDownMover {
|
|||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
JetElement blockLikeElement = JetPsiUtil.getOutermostJetElement(sibling, down, JetBlockExpression.class, JetWhenExpression.class, JetClassBody.class);
|
JetElement blockLikeElement = JetPsiUtil.getOutermostJetElement(sibling, down, JetBlockExpression.class, JetWhenExpression.class, JetClassBody.class);
|
||||||
if (blockLikeElement != null &&
|
if (blockLikeElement != null &&
|
||||||
!(PsiTreeUtil.instanceOf(blockLikeElement, FUNCTIONLIKE_ELEMENT_CLASSES))) {
|
!(PsiTreeUtil.instanceOf(blockLikeElement.getParent(), FUNCTIONLIKE_ELEMENT_CLASSES))) {
|
||||||
if (blockLikeElement instanceof JetWhenExpression) {
|
if (blockLikeElement instanceof JetWhenExpression) {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
blockLikeElement = JetPsiUtil.getOutermostJetElement(blockLikeElement, down, JetBlockExpression.class);
|
blockLikeElement = JetPsiUtil.getOutermostJetElement(blockLikeElement, down, JetBlockExpression.class);
|
||||||
@@ -299,8 +298,15 @@ public class JetExpressionMover extends AbstractJetUpDownMover {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static PsiElement getMovableElement(@NotNull PsiElement element) {
|
private static PsiElement getMovableElement(@NotNull PsiElement element, boolean lookRight) {
|
||||||
return PsiTreeUtil.getNonStrictParentOfType(element, MOVABLE_ELEMENT_CLASSES);
|
PsiElement movableElement = PsiTreeUtil.getNonStrictParentOfType(element, MOVABLE_ELEMENT_CLASSES);
|
||||||
|
if (movableElement == null) return null;
|
||||||
|
|
||||||
|
if (isBracelessBlock(movableElement)) {
|
||||||
|
movableElement = firstNonWhiteElement(lookRight ? movableElement.getLastChild() : movableElement.getFirstChild(), !lookRight);
|
||||||
|
}
|
||||||
|
|
||||||
|
return movableElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static enum MoveStatus {
|
private static enum MoveStatus {
|
||||||
@@ -318,6 +324,61 @@ public class JetExpressionMover extends AbstractJetUpDownMover {
|
|||||||
return MoveStatus.PERMITTED;
|
return MoveStatus.PERMITTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isBracelessBlock(@NotNull PsiElement element) {
|
||||||
|
if (!(element instanceof JetBlockExpression)) return false;
|
||||||
|
|
||||||
|
JetBlockExpression block = (JetBlockExpression) element;
|
||||||
|
|
||||||
|
return block.getLBrace() == null && block.getRBrace() == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static PsiElement adjustWhiteSpaceSibling(
|
||||||
|
@NotNull Editor editor,
|
||||||
|
@NotNull LineRange sourceRange,
|
||||||
|
@NotNull MoveInfo info,
|
||||||
|
boolean down
|
||||||
|
) {
|
||||||
|
PsiElement element = down ? sourceRange.lastElement : sourceRange.firstElement;
|
||||||
|
PsiElement sibling = down ? element.getNextSibling() : element.getPrevSibling();
|
||||||
|
|
||||||
|
PsiElement whiteSpaceTestSubject = sibling;
|
||||||
|
if (sibling == null) {
|
||||||
|
PsiElement parent = element.getParent();
|
||||||
|
if (parent != null && isBracelessBlock(parent)) {
|
||||||
|
whiteSpaceTestSubject = down ? parent.getNextSibling() : parent.getPrevSibling();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (whiteSpaceTestSubject instanceof PsiWhiteSpace) {
|
||||||
|
Document doc = editor.getDocument();
|
||||||
|
TextRange spaceRange = whiteSpaceTestSubject.getTextRange();
|
||||||
|
|
||||||
|
int startLine = doc.getLineNumber(spaceRange.getStartOffset());
|
||||||
|
int endLine = doc.getLineNumber(spaceRange.getEndOffset());
|
||||||
|
|
||||||
|
if (endLine - startLine > 1) {
|
||||||
|
int nearLine = down ? sourceRange.endLine : sourceRange.startLine - 1;
|
||||||
|
|
||||||
|
info.toMove = sourceRange;
|
||||||
|
info.toMove2 = new LineRange(nearLine, nearLine + 1);
|
||||||
|
info.indentTarget = false;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sibling != null) {
|
||||||
|
sibling = firstNonWhiteElement(sibling, down);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sibling == null) {
|
||||||
|
info.toMove2 = null;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sibling;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checkAvailable(@NotNull Editor editor, @NotNull PsiFile file, @NotNull MoveInfo info, boolean down) {
|
public boolean checkAvailable(@NotNull Editor editor, @NotNull PsiFile file, @NotNull MoveInfo info, boolean down) {
|
||||||
if (!super.checkAvailable(editor, file, info, down)) return false;
|
if (!super.checkAvailable(editor, file, info, down)) return false;
|
||||||
@@ -337,8 +398,8 @@ public class JetExpressionMover extends AbstractJetUpDownMover {
|
|||||||
if (psiRange == null) return false;
|
if (psiRange == null) return false;
|
||||||
|
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
PsiElement firstElement = getMovableElement(psiRange.getFirst());
|
PsiElement firstElement = getMovableElement(psiRange.getFirst(), false);
|
||||||
PsiElement lastElement = getMovableElement(psiRange.getSecond());
|
PsiElement lastElement = getMovableElement(psiRange.getSecond(), true);
|
||||||
|
|
||||||
if (firstElement == null || lastElement == null) return false;
|
if (firstElement == null || lastElement == null) return false;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// MOVE: down
|
||||||
|
val t = baz(
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
c
|
||||||
|
) {
|
||||||
|
<caret>val v = ""
|
||||||
|
val w = ""
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// MOVE: down
|
||||||
|
val t = baz(
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
c
|
||||||
|
) {
|
||||||
|
val w = ""
|
||||||
|
<caret>val v = ""
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// MOVE: up
|
||||||
|
// IS_APPLICABLE: false
|
||||||
|
val t = baz(
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
c
|
||||||
|
) {
|
||||||
|
<caret>val v = ""
|
||||||
|
val w = ""
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// MOVE: up
|
||||||
|
val t = baz(
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
c
|
||||||
|
) {
|
||||||
|
|
||||||
|
<caret>val v = ""
|
||||||
|
val w = ""
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// MOVE: up
|
||||||
|
val t = baz(
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
c
|
||||||
|
) {
|
||||||
|
<caret>val v = ""
|
||||||
|
|
||||||
|
val w = ""
|
||||||
|
}
|
||||||
+15
@@ -728,6 +728,21 @@ public class CodeMoverTestGenerated extends AbstractCodeMoverTest {
|
|||||||
doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/if4.kt");
|
doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/if4.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lambda1.kt")
|
||||||
|
public void testLambda1() throws Exception {
|
||||||
|
doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/lambda1.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lambda2.kt")
|
||||||
|
public void testLambda2() throws Exception {
|
||||||
|
doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/lambda2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lambda3.kt")
|
||||||
|
public void testLambda3() throws Exception {
|
||||||
|
doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/lambda3.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("when1.kt")
|
@TestMetadata("when1.kt")
|
||||||
public void testWhen1() throws Exception {
|
public void testWhen1() throws Exception {
|
||||||
doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/when1.kt");
|
doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/when1.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user