public static void deleteStatementTail(PsiElement container, @NotNull PsiElement statement) {
   PsiElement next = statement.getNextSibling();
   while (next != null) {
     final ASTNode node = next.getNode();
     final IElementType type = node.getElementType();
     if (type == mSEMI) {
       final PsiElement nnext = next.getNextSibling();
       container.deleteChildRange(next, next);
       next = nnext;
     } else if (type == mNLS || type == TokenType.WHITE_SPACE && next.getText().contains("\n")) {
       final String text = next.getText();
       final int first = text.indexOf("\n");
       final int second = text.indexOf("\n", first + 1);
       if (second < 0) {
         container.deleteChildRange(next, next);
         return;
       }
       final String substring = text.substring(second);
       container
           .getNode()
           .replaceChild(
               node,
               createSingleLeafElement(
                   type, substring, 0, substring.length(), null, container.getManager()));
       return;
     } else {
       break;
     }
   }
 }
 @Override
 public boolean flip(PsiElement left, PsiElement right) {
   if (left instanceof PsiVariable && right instanceof PsiVariable) {
     final PsiElement first = left.getFirstChild();
     if (!(first instanceof PsiModifierList)) {
       return false;
     }
     final PsiElement child = PsiTreeUtil.skipSiblingsForward(first, PsiWhiteSpace.class);
     if (!(child instanceof PsiTypeElement)) {
       return false;
     }
     final PsiElement last = child.getNextSibling();
     if (!(last instanceof PsiWhiteSpace)) {
       return false;
     }
     final PsiElement anchor = right.getFirstChild();
     if (!(anchor instanceof PsiIdentifier)) {
       return false;
     }
     final PsiElement semiColon = right.getLastChild();
     if (!(semiColon instanceof PsiJavaToken)) {
       return false;
     }
     right.addRangeBefore(first, last, anchor);
     left.deleteChildRange(first, last);
     left.add(semiColon);
     semiColon.delete();
     final PsiElement copy = left.copy();
     left.replace(right);
     right.replace(copy);
     return true;
   }
   return false;
 }
  private static void generateElseBranchTextAndRemoveTailStatements(
      @NotNull GrIfStatement ifStatement, @NotNull GrIfStatement newIf) {
    final GrStatement thenBranch = newIf.getThenBranch();
    assert thenBranch != null;

    GrStatement elseBranch = ifStatement.getElseBranch();
    if (elseBranch != null) {
      thenBranch.replaceWithStatement(elseBranch);
      return;
    }

    PsiElement parent = ifStatement.getParent();
    if (!(parent instanceof GrStatementOwner)) return;

    if (!isTailAfterIf(ifStatement, ((GrStatementOwner) parent))) return;

    final PsiElement start = ifStatement.getNextSibling();
    PsiElement end =
        parent instanceof GrCodeBlock
            ? ((GrCodeBlock) parent).getRBrace().getPrevSibling()
            : parent.getLastChild();

    final GrOpenBlock block = ((GrBlockStatement) thenBranch).getBlock();
    block.addRangeAfter(start, end, block.getLBrace());
    parent.deleteChildRange(start, end);
  }
  @Override
  @Nullable
  protected TextRange surroundStatement(
      @NotNull Project project, @NotNull Editor editor, @NotNull PsiElement[] elements)
      throws IncorrectOperationException {
    PyTryExceptStatement tryStatement =
        PyElementGenerator.getInstance(project)
            .createFromText(LanguageLevel.getDefault(), PyTryExceptStatement.class, getTemplate());
    final PsiElement parent = elements[0].getParent();
    final PyStatementList statementList = tryStatement.getTryPart().getStatementList();
    statementList.addRange(elements[0], elements[elements.length - 1]);
    statementList.getFirstChild().delete();
    tryStatement = (PyTryExceptStatement) parent.addBefore(tryStatement, elements[0]);
    parent.deleteChildRange(elements[0], elements[elements.length - 1]);

    final PsiFile psiFile = parent.getContainingFile();
    final Document document = psiFile.getViewProvider().getDocument();
    final TextRange range = tryStatement.getTextRange();
    assert document != null;
    final RangeMarker rangeMarker = document.createRangeMarker(range);

    final PsiElement element = psiFile.findElementAt(rangeMarker.getStartOffset());
    tryStatement = PsiTreeUtil.getParentOfType(element, PyTryExceptStatement.class);
    if (tryStatement != null) {
      return getResultRange(tryStatement);
    }
    return null;
  }
  public static PsiElement[] move(
      @NotNull PsiElement container,
      @NotNull PsiElement[] statements,
      boolean generateDefaultInitializers) {
    if (statements.length == 0) {
      return statements;
    }

    Project project = container.getProject();

    List<PsiElement> resultStatements = new ArrayList<PsiElement>();
    List<KtProperty> propertiesDeclarations = new ArrayList<KtProperty>();

    // Dummy element to add new declarations at the beginning
    KtPsiFactory psiFactory = KtPsiFactoryKt.KtPsiFactory(project);
    PsiElement dummyFirstStatement =
        container.addBefore(psiFactory.createExpression("dummyStatement"), statements[0]);

    try {
      SearchScope scope = new LocalSearchScope(container);
      int lastStatementOffset = statements[statements.length - 1].getTextRange().getEndOffset();

      for (PsiElement statement : statements) {
        if (needToDeclareOut(statement, lastStatementOffset, scope)) {
          if (statement instanceof KtProperty
              && ((KtProperty) statement).getInitializer() != null) {
            KtProperty property = (KtProperty) statement;
            KtProperty declaration =
                createVariableDeclaration(property, generateDefaultInitializers);
            declaration = (KtProperty) container.addBefore(declaration, dummyFirstStatement);
            propertiesDeclarations.add(declaration);
            container.addAfter(psiFactory.createNewLine(), declaration);

            KtBinaryExpression assignment = createVariableAssignment(property);
            resultStatements.add(property.replace(assignment));
          } else {
            PsiElement newStatement = container.addBefore(statement, dummyFirstStatement);
            container.addAfter(psiFactory.createNewLine(), newStatement);
            container.deleteChildRange(statement, statement);
          }
        } else {
          resultStatements.add(statement);
        }
      }
    } finally {
      dummyFirstStatement.delete();
    }

    ShortenReferences.DEFAULT.process(propertiesDeclarations);

    return PsiUtilCore.toPsiElementArray(resultStatements);
  }
  @Override
  public TextRange surroundStatements(
      Project project, Editor editor, PsiElement container, PsiElement[] statements)
      throws IncorrectOperationException {
    PsiManager manager = PsiManager.getInstance(project);
    PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
    CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project);

    statements = SurroundWithUtil.moveDeclarationsOut(container, statements, false);
    if (statements.length == 0) {
      return null;
    }

    @NonNls String text = "try{\n}finally{\n\n}";
    PsiTryStatement tryStatement = (PsiTryStatement) factory.createStatementFromText(text, null);
    tryStatement = (PsiTryStatement) codeStyleManager.reformat(tryStatement);

    tryStatement =
        (PsiTryStatement) container.addAfter(tryStatement, statements[statements.length - 1]);

    PsiCodeBlock tryBlock = tryStatement.getTryBlock();
    if (tryBlock == null) {
      return null;
    }
    SurroundWithUtil.indentCommentIfNecessary(tryBlock, statements);
    tryBlock.addRange(statements[0], statements[statements.length - 1]);
    container.deleteChildRange(statements[0], statements[statements.length - 1]);

    PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock();
    if (finallyBlock == null) {
      return null;
    }
    int offset = finallyBlock.getTextRange().getStartOffset() + 2;
    editor.getCaretModel().moveToOffset(offset);
    final Document document = editor.getDocument();
    PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(document);
    editor.getSelectionModel().removeSelection();
    final PsiStatement firstTryStmt = tryBlock.getStatements()[0];
    final int indent =
        firstTryStmt.getTextOffset()
            - document.getLineStartOffset(document.getLineNumber(firstTryStmt.getTextOffset()));
    EditorModificationUtil.insertStringAtCaret(editor, StringUtil.repeat(" ", indent), false, true);
    return new TextRange(editor.getCaretModel().getOffset(), editor.getCaretModel().getOffset());
  }
Example #7
0
  // Delete given element and all the elements separating it from the neighboring elements of the
  // same class
  public static void deleteElementWithDelimiters(@NotNull PsiElement element) {
    PsiElement paramBefore = PsiTreeUtil.getPrevSiblingOfType(element, element.getClass());

    PsiElement from;
    PsiElement to;
    if (paramBefore != null) {
      from = paramBefore.getNextSibling();
      to = element;
    } else {
      PsiElement paramAfter = PsiTreeUtil.getNextSiblingOfType(element, element.getClass());

      from = element;
      to = paramAfter != null ? paramAfter.getPrevSibling() : element;
    }

    PsiElement parent = element.getParent();

    parent.deleteChildRange(from, to);
  }
  @Nullable
  @Override
  protected TextRange surroundStatements(
      Project project, Editor editor, PsiElement container, PsiElement[] statements) {
    statements =
        MoveDeclarationsOutHelper.move(container, statements, isGenerateDefaultInitializers());

    if (statements.length == 0) {
      KotlinSurrounderUtils.showErrorHint(
          project, editor, KotlinSurrounderUtils.SURROUND_WITH_ERROR);
      return null;
    }

    KtIfExpression ifExpression =
        (KtIfExpression) KtPsiFactoryKt.KtPsiFactory(project).createExpression(getCodeTemplate());
    ifExpression =
        (KtIfExpression) container.addAfter(ifExpression, statements[statements.length - 1]);

    // TODO move a comment for first statement

    KtBlockExpression thenBranch = (KtBlockExpression) ifExpression.getThen();
    assert thenBranch != null
        : "Then branch should exist for created if expression: " + ifExpression.getText();
    // Add statements in then branch of created if
    KotlinSurrounderUtils.addStatementsInBlock(thenBranch, statements);

    // Delete statements from original code
    container.deleteChildRange(statements[0], statements[statements.length - 1]);

    ifExpression = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(ifExpression);

    KtExpression condition = ifExpression.getCondition();
    assert condition != null
        : "Condition should exists for created if expression: " + ifExpression.getText();
    // Delete condition from created if
    TextRange range = condition.getTextRange();
    TextRange textRange = new TextRange(range.getStartOffset(), range.getStartOffset());
    editor.getDocument().deleteString(range.getStartOffset(), range.getEndOffset());
    return textRange;
  }