Search in sources :

Example 16 with LineRange

use of com.intellij.codeInsight.editorActions.moveUpDown.LineRange in project intellij-plugins by JetBrains.

the class DartStatementMover method checkMovingInsideOutside.

private boolean checkMovingInsideOutside(PsiFile file, final Editor editor, @NotNull final MoveInfo info, final boolean down) {
    final int offset = editor.getCaretModel().getOffset();
    PsiElement elementAtOffset = file.getViewProvider().findElementAt(offset, DartLanguage.INSTANCE);
    if (elementAtOffset == null)
        return false;
    PsiElement guard = elementAtOffset;
    boolean isExpr = isMovingExpr(info.toMove);
    if (isExpr) {
        guard = PsiTreeUtil.getParentOfType(guard, DartMethodDeclaration.class, DartListLiteralExpression.class, DartArgumentList.class, DartArguments.class, DartFunctionDeclarationWithBodyOrNative.class, DartClass.class, PsiComment.class);
    } else {
        guard = PsiTreeUtil.getParentOfType(guard, DartMethodDeclaration.class, DartFunctionDeclarationWithBodyOrNative.class, DartClass.class, PsiComment.class);
    }
    PsiElement brace = soloRightBraceBeingMoved(file, editor);
    if (brace != null) {
        int line = editor.getDocument().getLineNumber(offset);
        final LineRange toMove = new LineRange(line, line + 1);
        toMove.firstElement = toMove.lastElement = brace;
        info.toMove = toMove;
    }
    // Cannot move in/outside method/class/function/comment.
    if (!calcInsertOffset(file, editor, info.toMove, info, down))
        return false;
    int insertOffset = down ? getLineStartSafeOffset(editor.getDocument(), info.toMove2.endLine) : editor.getDocument().getLineStartOffset(info.toMove2.startLine);
    PsiElement elementAtInsertOffset = file.getViewProvider().findElementAt(insertOffset, DartLanguage.INSTANCE);
    PsiElement newGuard;
    if (isExpr) {
        newGuard = PsiTreeUtil.getParentOfType(elementAtInsertOffset, DartMethodDeclaration.class, DartListLiteralExpression.class, DartArgumentList.class, DartArguments.class, DartFunctionDeclarationWithBodyOrNative.class, DartClass.class, PsiComment.class);
    } else {
        newGuard = PsiTreeUtil.getParentOfType(elementAtInsertOffset, DartMethodDeclaration.class, DartFunctionDeclarationWithBodyOrNative.class, DartClass.class, PsiComment.class);
    }
    if (brace != null && PsiTreeUtil.getParentOfType(brace, IDartBlock.class, false) != PsiTreeUtil.getParentOfType(elementAtInsertOffset, IDartBlock.class, false)) {
        info.indentSource = true;
    }
    if (newGuard == guard && isInside(insertOffset, newGuard) == isInside(offset, guard)) {
        return true;
    }
    if (newGuard == null || guard == null) {
        return false;
    }
    if (NESTED_GUARDS.contains(newGuard.getNode().getElementType()) && NESTED_GUARDS.contains(guard.getNode().getElementType())) {
        PsiElement parent = PsiTreeUtil.findCommonParent(guard, newGuard);
        if (parent == guard || parent == newGuard) {
            return isInside(insertOffset, newGuard) == isInside(offset, guard);
        }
    }
    return false;
}
Also used : LineRange(com.intellij.codeInsight.editorActions.moveUpDown.LineRange) LeafPsiElement(com.intellij.psi.impl.source.tree.LeafPsiElement)

Example 17 with LineRange

use of com.intellij.codeInsight.editorActions.moveUpDown.LineRange in project intellij-plugins by JetBrains.

the class DartStatementMover method expandLineRangeToCoverPsiElements.

private static LineRange expandLineRangeToCoverPsiElements(final LineRange range, Editor editor, final PsiFile file) {
    Pair<PsiElement, PsiElement> psiRange = getElementRange(editor, file, range);
    if (psiRange == null) {
        return null;
    }
    if (psiRange.first instanceof DartStatements || psiRange.first instanceof DartExpressionList || psiRange.first instanceof DartArgumentList) {
        PsiElement first = psiRange.first;
        PsiElement last = psiRange.second;
        if (last != null) {
            PsiElement statement = first.getFirstChild();
            if (statement != null) {
                psiRange = Pair.create(statement, last);
            }
        }
    } else if (psiRange.first instanceof DartNamedArgument && psiRange.first.getParent() == psiRange.second) {
        psiRange = Pair.create(psiRange.first, psiRange.first);
    }
    if (psiRange.second instanceof DartStatements) {
        PsiElement first = psiRange.first;
        PsiElement last = psiRange.second;
        if (PsiTreeUtil.isAncestor(last, first, false)) {
            PsiElement statement = last.getLastChild();
            if (statement != null) {
                psiRange = Pair.create(first, statement);
            }
        }
    }
    if (isComma(psiRange.second)) {
        PsiElement first = psiRange.first;
        PsiElement last = UsefulPsiTreeUtil.getPrevSiblingSkipWhiteSpacesAndComments(psiRange.second, true);
        if (PsiTreeUtil.isAncestor(last, first, false)) {
            PsiElement statement = last.getLastChild();
            if (statement != null) {
                psiRange = Pair.create(first, statement);
            }
        }
    }
    final PsiElement parent = PsiTreeUtil.findCommonParent(psiRange.first, psiRange.second);
    Pair<PsiElement, PsiElement> elementRange = getElementRange(parent, psiRange.first, psiRange.second);
    if (elementRange == null) {
        return null;
    }
    int endOffset = elementRange.second.getTextRange().getEndOffset();
    Document document = editor.getDocument();
    if (endOffset > document.getTextLength()) {
        return null;
    }
    int endLine;
    if (endOffset == document.getTextLength()) {
        endLine = document.getLineCount();
    } else {
        endLine = editor.offsetToLogicalPosition(endOffset).line + 1;
        endLine = Math.min(endLine, document.getLineCount());
    }
    int startLine = Math.min(range.startLine, editor.offsetToLogicalPosition(elementRange.first.getTextOffset()).line);
    endLine = Math.max(endLine, range.endLine);
    return new LineRange(startLine, endLine);
}
Also used : Document(com.intellij.openapi.editor.Document) LineRange(com.intellij.codeInsight.editorActions.moveUpDown.LineRange) LeafPsiElement(com.intellij.psi.impl.source.tree.LeafPsiElement)

Example 18 with LineRange

use of com.intellij.codeInsight.editorActions.moveUpDown.LineRange in project intellij-community by JetBrains.

the class JsonLineMover method checkAvailable.

@Override
public boolean checkAvailable(@NotNull Editor editor, @NotNull PsiFile file, @NotNull MoveInfo info, boolean down) {
    myShouldAddComma = false;
    if (!(file instanceof JsonFile) || !super.checkAvailable(editor, file, info, down)) {
        return false;
    }
    Pair<PsiElement, PsiElement> movedElementRange = getElementRange(editor, file, info.toMove);
    if (!isValidElementRange(movedElementRange)) {
        return false;
    }
    // Tweak range to move if it's necessary
    movedElementRange = expandCommentsInRange(movedElementRange);
    info.toMove = new LineRange(movedElementRange.getFirst(), movedElementRange.getSecond());
    // Adjust destination range to prevent illegal offsets
    final int lineCount = editor.getDocument().getLineCount();
    if (down) {
        info.toMove2 = new LineRange(info.toMove.endLine, Math.min(info.toMove.endLine + 1, lineCount));
    } else {
        info.toMove2 = new LineRange(Math.max(info.toMove.startLine - 1, 0), info.toMove.startLine);
    }
    if (movedElementRange.getFirst() instanceof PsiComment && movedElementRange.getSecond() instanceof PsiComment) {
        return true;
    }
    // Check whether additional comma is needed
    final Pair<PsiElement, PsiElement> destElementRange = getElementRange(editor, file, info.toMove2);
    if (isValidElementRange(destElementRange) && movedElementRange.getFirst().getParent() == destElementRange.getSecond().getParent()) {
        final PsiElement commonParent = movedElementRange.getFirst().getParent();
        final PsiElement lowerRightElement = down ? destElementRange.getSecond() : movedElementRange.getSecond();
        // Destination rightmost element is not closing brace or bracket
        if (lowerRightElement instanceof JsonElement) {
            if (commonParent instanceof JsonArray && notFollowedByNextElementOrComma(lowerRightElement, JsonValue.class) || commonParent instanceof JsonObject && notFollowedByNextElementOrComma(lowerRightElement, JsonProperty.class)) {
                myShouldAddComma = true;
            }
        }
    }
    return true;
}
Also used : PsiComment(com.intellij.psi.PsiComment) LineRange(com.intellij.codeInsight.editorActions.moveUpDown.LineRange) PsiElement(com.intellij.psi.PsiElement)

Example 19 with LineRange

use of com.intellij.codeInsight.editorActions.moveUpDown.LineRange in project intellij-community by JetBrains.

the class GroovyStatementMover method allRanges.

private List<LineRange> allRanges(final GroovyPsiElement scope, final boolean stmtLevel, final boolean topLevel) {
    final ArrayList<LineRange> result = new ArrayList<>();
    scope.accept(new PsiRecursiveElementVisitor() {

        int lastStart = -1;

        private void addRange(int endLine) {
            if (lastStart >= 0) {
                result.add(new LineRange(lastStart, endLine));
            }
            lastStart = endLine;
        }

        @Override
        public void visitElement(PsiElement element) {
            if (stmtLevel && element instanceof GrCodeBlock) {
                final PsiElement lBrace = ((GrCodeBlock) element).getLBrace();
                if (nlsAfter(lBrace)) {
                    assert lBrace != null;
                    addRange(new LineRange(lBrace).endLine);
                }
                addChildRanges(((GrCodeBlock) element).getStatements());
                final PsiElement rBrace = ((GrCodeBlock) element).getRBrace();
                if (nlsAfter(rBrace)) {
                    assert rBrace != null;
                    final int endLine = new LineRange(rBrace).endLine;
                    if (lastStart >= 0) {
                        for (int i = lastStart + 1; i < endLine; i++) {
                            addRange(i);
                        }
                    }
                }
            } else if (stmtLevel && element instanceof GrCaseSection) {
                final GrCaseLabel[] allLabels = ((GrCaseSection) element).getCaseLabels();
                final GrCaseLabel label = allLabels[0];
                if (nlsAfter(label)) {
                    addRange(new LineRange(label).endLine);
                }
                addChildRanges(((GrCaseSection) element).getStatements());
            } else if (element instanceof GroovyFileBase) {
                addChildRanges(((GroovyFileBase) element).getTopStatements());
            } else if (!stmtLevel && !topLevel && element instanceof GrTypeDefinitionBody) {
                addChildRanges(((GrTypeDefinitionBody) element).getMemberDeclarations());
            } else {
                super.visitElement(element);
            }
        }

        private boolean shouldDigInside(GroovyPsiElement statement) {
            if (stmtLevel && (statement instanceof GrMethod || statement instanceof GrTypeDefinition)) {
                return false;
            }
            if (statement instanceof GrVariableDeclaration && !stmtLevel) {
                return false;
            }
            return true;
        }

        private void addChildRanges(GroovyPsiElement[] statements) {
            for (int i = 0; i < statements.length; i++) {
                GroovyPsiElement statement = statements[i];
                if (nlsAfter(statement)) {
                    final LineRange range = getLineRange(statement);
                    if ((i == 0 || isStatement(statements[i - 1])) && isStatement(statement)) {
                        for (int j = lastStart; j < range.startLine; j++) {
                            addRange(j + 1);
                        }
                    }
                    lastStart = range.startLine;
                    if (shouldDigInside(statement)) {
                        statement.accept(this);
                    }
                    addRange(range.endLine);
                }
            }
        }
    });
    return result;
}
Also used : PsiRecursiveElementVisitor(com.intellij.psi.PsiRecursiveElementVisitor) GroovyFileBase(org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase) GroovyPsiElement(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement) GrCaseLabel(org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrCaseLabel) ArrayList(java.util.ArrayList) GrMethod(org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod) LineRange(com.intellij.codeInsight.editorActions.moveUpDown.LineRange) GrTypeDefinitionBody(org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinitionBody) GrVariableDeclaration(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration) GrTypeDefinition(org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition) GrCaseSection(org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrCaseSection) PsiElement(com.intellij.psi.PsiElement) GroovyPsiElement(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement) GrCodeBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock)

Example 20 with LineRange

use of com.intellij.codeInsight.editorActions.moveUpDown.LineRange in project kotlin by JetBrains.

the class KotlinDeclarationMover method checkAvailable.

@Override
public boolean checkAvailable(@NotNull Editor editor, @NotNull PsiFile file, @NotNull MoveInfo info, boolean down) {
    if (!super.checkAvailable(editor, file, info, down))
        return false;
    LineRange oldRange = info.toMove;
    Pair<PsiElement, PsiElement> psiRange = getElementRange(editor, file, oldRange);
    if (psiRange == null)
        return false;
    KtDeclaration firstDecl = getMovableDeclaration(psiRange.getFirst());
    if (firstDecl == null)
        return false;
    moveEnumConstant = firstDecl instanceof KtEnumEntry;
    KtDeclaration lastDecl = getMovableDeclaration(psiRange.getSecond());
    if (lastDecl == null)
        return false;
    //noinspection ConstantConditions
    LineRange sourceRange = getSourceRange(firstDecl, lastDecl, editor, oldRange);
    if (sourceRange == null)
        return false;
    PsiElement sibling = getLastNonWhiteSiblingInLine(firstNonWhiteSibling(sourceRange, down), editor, down);
    // Either reached last sibling, or jumped over multi-line whitespace
    if (sibling == null) {
        info.toMove2 = null;
        return true;
    }
    info.toMove = sourceRange;
    info.toMove2 = getTargetRange(editor, sibling, down, sourceRange.firstElement);
    return true;
}
Also used : LineRange(com.intellij.codeInsight.editorActions.moveUpDown.LineRange) PsiElement(com.intellij.psi.PsiElement)

Aggregations

LineRange (com.intellij.codeInsight.editorActions.moveUpDown.LineRange)24 Document (com.intellij.openapi.editor.Document)8 PsiElement (com.intellij.psi.PsiElement)8 Nullable (org.jetbrains.annotations.Nullable)6 LeafPsiElement (com.intellij.psi.impl.source.tree.LeafPsiElement)4 TextRange (com.intellij.openapi.util.TextRange)3 LogicalPosition (com.intellij.openapi.editor.LogicalPosition)2 PsiComment (com.intellij.psi.PsiComment)2 GroovyFileBase (org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase)2 GroovyPsiElement (org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement)2 GrTypeDefinition (org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition)2 CaretModel (com.intellij.openapi.editor.CaretModel)1 SelectionModel (com.intellij.openapi.editor.SelectionModel)1 Project (com.intellij.openapi.project.Project)1 PsiRecursiveElementVisitor (com.intellij.psi.PsiRecursiveElementVisitor)1 ArrayList (java.util.ArrayList)1 KtBlockExpression (org.jetbrains.kotlin.psi.KtBlockExpression)1 KtFunctionLiteral (org.jetbrains.kotlin.psi.KtFunctionLiteral)1 GrVariableDeclaration (org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration)1 GrCodeBlock (org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock)1