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()); }
// 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; }