Beispiel #1
0
  private static BraceStatus checkForMovableDownClosingBrace(
      @NotNull PsiElement closingBrace,
      @NotNull PsiElement block,
      @NotNull Editor editor,
      @NotNull MoveInfo info) {
    PsiElement current = block;
    PsiElement nextElement = null;
    PsiElement nextExpression = null;
    do {
      PsiElement sibling = firstNonWhiteElement(current.getNextSibling(), true);
      if (sibling != null && nextElement == null) {
        nextElement = sibling;
      }

      if (sibling instanceof JetExpression) {
        nextExpression = sibling;
        break;
      }

      current = current.getParent();
    } while (current != null && !(PsiTreeUtil.instanceOf(current, BLOCKLIKE_ELEMENT_CLASSES)));

    if (nextExpression == null) return BraceStatus.NOT_MOVABLE;

    Document doc = editor.getDocument();

    info.toMove = new LineRange(closingBrace, closingBrace, doc);
    info.toMove2 = new LineRange(nextElement, nextExpression);
    info.indentSource = true;

    return BraceStatus.MOVABLE;
  }
Beispiel #2
0
  @Override
  public boolean checkAvailable(
      @NotNull Editor editor, @NotNull PsiFile file, @NotNull MoveInfo info, boolean down) {
    parametersOrArgsToMove = null;

    if (!super.checkAvailable(editor, file, info, down)) return false;

    switch (checkForMovableClosingBrace(editor, file, info, down)) {
      case NOT_MOVABLE:
        {
          info.toMove2 = null;
          return true;
        }
      case MOVABLE:
        return true;
      default:
        break;
    }

    LineRange oldRange = info.toMove;

    Pair<PsiElement, PsiElement> psiRange = getElementRange(editor, file, oldRange);
    if (psiRange == null) return false;

    //noinspection unchecked
    PsiElement firstElement = getMovableElement(psiRange.getFirst(), false);
    PsiElement lastElement = getMovableElement(psiRange.getSecond(), true);

    if (firstElement == null || lastElement == null) return false;

    if (isForbiddenMove(firstElement, down) || isForbiddenMove(lastElement, down)) {
      info.toMove2 = null;
      return true;
    }

    if ((firstElement instanceof JetParameter || firstElement instanceof JetValueArgument)
        && PsiTreeUtil.isAncestor(lastElement, firstElement, false)) {
      lastElement = firstElement;
    }

    LineRange sourceRange = getSourceRange(firstElement, lastElement, editor, oldRange);
    if (sourceRange == null) return false;

    PsiElement sibling =
        getLastNonWhiteSiblingInLine(adjustSibling(editor, sourceRange, info, down), editor, down);

    // Either reached last sibling, or jumped over multi-line whitespace
    if (sibling == null) return true;

    info.toMove = sourceRange;
    info.toMove2 = getTargetRange(editor, sourceRange.firstElement, sibling, down);
    return true;
  }
Beispiel #3
0
  protected static PsiElement adjustSibling(
      @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) {
      if (getElementLineCount(whiteSpaceTestSubject, editor) > 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) {
      JetCallExpression callExpression =
          PsiTreeUtil.getParentOfType(element, JetCallExpression.class);
      if (callExpression != null) {
        JetBlockExpression dslBlock = getDSLLambdaBlock(callExpression, down);
        if (PsiTreeUtil.isAncestor(dslBlock, element, false)) {
          //noinspection ConstantConditions
          PsiElement blockParent = dslBlock.getParent();
          return down
              ? JetPsiUtil.findChildByType(blockParent, JetTokens.RBRACE)
              : JetPsiUtil.findChildByType(blockParent, JetTokens.LBRACE);
        }
      }

      info.toMove2 = null;
      return null;
    }

    return sibling;
  }
Beispiel #4
0
  private static BraceStatus checkForMovableUpClosingBrace(
      @NotNull PsiElement closingBrace,
      PsiElement block,
      @NotNull Editor editor,
      @NotNull MoveInfo info) {
    //noinspection unchecked
    PsiElement prev = JetPsiUtil.getLastChildByType(block, JetExpression.class);
    if (prev == null) return BraceStatus.NOT_MOVABLE;

    Document doc = editor.getDocument();

    info.toMove = new LineRange(closingBrace, closingBrace, doc);
    info.toMove2 = new LineRange(prev, prev, doc);
    info.indentSource = true;

    return BraceStatus.MOVABLE;
  }