private boolean calcInsertOffset()

in Dart/src/com/jetbrains/lang/dart/ide/moveCode/DartStatementMover.java [229:387]


  private boolean calcInsertOffset(@NotNull PsiFile file,
                                   @NotNull Editor editor,
                                   @NotNull LineRange range,
                                   final @NotNull MoveInfo info,
                                   final boolean down) {
    int destLine = getDestLineForAnon(editor, range, down);

    int startLine = down ? range.endLine : range.startLine - 1;
    if (destLine < 0 || startLine < 0) return false;
    boolean firstTime = true;
    boolean isExpr = isMovingExpr(info.toMove);
    PsiElement elementStart = null;
    if (isExpr) {
      int offset = editor.logicalPositionToOffset(new LogicalPosition(startLine, 0));
      elementStart = firstNonWhiteMovableElement(offset, file, true);
      if (elementStart instanceof DartArgumentList) {
        elementStart = elementStart.getFirstChild();
      }
      else if (isRightBracket(elementStart) && info.toMove.firstElement instanceof DartNamedArgument) {
        elementStart = elementStart.getParent().getParent(); // Possibly a named arg with list value
      }
      if (elementStart instanceof DartExpression || elementStart instanceof DartNamedArgument) {
        TextRange elementTextRange = elementStart.getTextRange();
        LogicalPosition pos = editor.offsetToLogicalPosition(elementTextRange.getEndOffset());
        int endOffset = editor.logicalPositionToOffset(new LogicalPosition(pos.line + 1, 0));
        PsiElement elementEnd = firstNonWhiteMovableElement(endOffset, file, false);
        if (elementEnd instanceof DartArgumentList && elementStart instanceof DartNamedArgument) {
          elementEnd = elementEnd.getLastChild();
          if (!isComma(elementEnd)) {
            return false; // Require trailing comma
          }
          else {
            info.toMove2 = new LineRange(startLine, pos.line + 1);
            return true;
          }
        }
        if (elementEnd != null && isComma(elementEnd)) {
          PsiElement elementTail = UsefulPsiTreeUtil.getPrevSiblingSkipWhiteSpacesAndComments(elementEnd, true);
          if (elementTail instanceof DartExpressionList) {
            elementTail = elementTail.getLastChild();
          }
          if (elementStart == elementTail) {
            if (down) {
              info.toMove2 = new LineRange(startLine, pos.line + 1);
            }
            else {
              destLine = pos.line;
              elementTextRange = elementTail.getTextRange();
              pos = editor.offsetToLogicalPosition(elementTextRange.getStartOffset());
              info.toMove2 = new LineRange(pos.line, destLine + 1);
            }
            return true;
          }
        }
      }
      else if (elementStart != null && isRightParen(elementStart)) {
        PsiElement start = elementStart.getParent().getParent();
        TextRange elementTextRange = start.getTextRange();
        LogicalPosition pos = editor.offsetToLogicalPosition(elementTextRange.getStartOffset());
        int startOffset = editor.logicalPositionToOffset(new LogicalPosition(pos.line, 0));
        PsiElement startElement = firstNonWhiteMovableElement(startOffset, file, true);
        if (startElement == start) {
          info.toMove2 = new LineRange(pos.line, down ? startLine : startLine + 1);
          return true;
        }
      }
    }
    while (true) {
      int offset = editor.logicalPositionToOffset(new LogicalPosition(destLine, 0));
      PsiElement element = firstNonWhiteMovableElement(offset, file, !isExpr || !down);
      if (firstTime) {
        if (element != null && element.getNode().getElementType() == (down ? DartTokenTypes.RBRACE : DartTokenTypes.LBRACE)) {
          PsiElement elementParent = element.getParent();
          if (elementParent != null && (isStatement(elementParent) || elementParent instanceof DartBlock)) {
            return true;
          }
        }
      }

      if (element instanceof DartStatements) element = element.getFirstChild();
      while (element != null && !(element instanceof PsiFile)) {
        TextRange elementTextRange = element.getTextRange();
        if (elementTextRange.isEmpty() || !elementTextRange.grown(-1).shiftRight(1).contains(offset)) {
          PsiElement elementToSurround = null;
          boolean found = false;
          if (isExpr) {
            if (firstTime && element instanceof DartExpression) {
              found = true;
            }
            else if (isComma(element) && UsefulPsiTreeUtil.getPrevSiblingSkipWhiteSpacesAndComments(element, true) == elementStart) {
              found = true;
            }
            else if (element instanceof DartArgumentList) {
              element = element.getParent();
              if (element.getParent() == elementStart) {
                element = element.getParent().getNextSibling();
                boolean hasComma = false;
                while (element != null) {
                  if (UsefulPsiTreeUtil.isWhitespaceOrComment(element)) {
                    if (element.getText().contains("\n")) {
                      destLine += 1;
                      break;
                    }
                  }
                  else if (isComma(element)) {
                    hasComma = true;
                  }
                  else {
                    break;
                  }
                  element = element.getNextSibling();
                }
                if (!hasComma) {
                  return false; // Disallow move if following expr has no trailing comma
                }
                found = true;
              }
            }
          }
          else if ((isStatement(element) || element instanceof PsiComment)
                   && statementCanBePlacedAlong(element)) {
            found = true;
            if (!(element.getParent() instanceof IDartBlock)) {
              elementToSurround = element;
            }
          }
          else if ((element.getNode().getElementType() == DartTokenTypes.RBRACE &&
                    element.getParent() instanceof IDartBlock &&
                    (!isStatement(element.getParent().getParent()) || statementCanBePlacedAlong(element.getParent().getParent())))
                   || (!down && element instanceof DartStatements)) {
            // Before/after code block closing/opening brace.
            found = true;
          }
          if (found) {
            if (elementToSurround != null) {
              final SmartPointerManager manager = SmartPointerManager.getInstance(elementToSurround.getProject());
              statementToSurroundWithCodeBlock = manager.createSmartPsiElementPointer(elementToSurround);
            }
            info.toMove = range;
            int endLine = destLine;
            if (startLine > endLine) {
              int tmp = endLine;
              endLine = startLine;
              startLine = tmp;
            }

            info.toMove2 = new LineRange(startLine, down ? endLine : endLine + 1);
            return true;
          }
        }
        element = element.getParent();
      }
      firstTime = false;
      destLine += down ? 1 : -1;
      if (destLine <= 0 || destLine >= editor.getDocument().getLineCount()) {
        return false;
      }
    }
  }