ASTNode (final ASTNode element, final int startOffset, final int endOffset) { final PsiElement psiElement = SourceTreeToPsiMap.treeElementToPsi(element); assert psiElement != null; final PsiFile file = psiElement.getContainingFile(); final Document document = file.getViewProvider().getDocument(); final boolean delegateToTopLevel = shouldDelegateToTopLevel(document, file); PsiElement elementToFormat = delegateToTopLevel ? InjectedLanguageManager .getInstance(file.getProject()).getTopLevelFile(file) : psiElement; final PsiFile fileToFormat = elementToFormat.getContainingFile(); // Dirty workaround // In case we're formatting not the original file, we have to keep the formatting listener // if any and drop it after creating a VirtualFormattingModel. VirtualFormattingListener listener = VirtualFormattingImplKt.getVirtualFormattingListener(file); final FormattingModelBuilder builder; try { if (listener != null) { VirtualFormattingImplKt.setVirtualFormattingListener(fileToFormat, listener); } builder = LanguageFormatting.INSTANCE.forContext(fileToFormat); } finally { if (listener != null) { VirtualFormattingImplKt.setVirtualFormattingListener(fileToFormat, null); } } // End of dirty workaround if (builder != null) { RangeMarker rangeMarker = null; CodeFormattingData codeFormattingData = CodeFormattingData.getOrCreate(fileToFormat); try { if (document != null && endOffset < document.getTextLength()) { rangeMarker = document.createRangeMarker(startOffset, endOffset); } TextRange range = preprocess(codeFormattingData, element, TextRange.create(startOffset, endOffset)); if (delegateToTopLevel) { range = ((DocumentWindow)document).injectedToHost(range); } final FormattingModel model = CoreFormatterUtil.buildModel(builder, elementToFormat, range, mySettings, FormattingMode.REFORMAT); if (file.getTextLength() > 0) { try { final FormatTextRanges ranges = new FormatTextRanges(range, true); setDisabledRanges(fileToFormat, ranges); FormatterEx.getInstanceEx().format( model, mySettings, getIndentOptions(mySettings, file.getProject(), file, document, range), ranges ); } catch (IncorrectOperationException e) { LOG.error(e); } } if (!psiElement.isValid()) { if (rangeMarker != null) { final PsiElement at = file.findElementAt(rangeMarker.getStartOffset()); final PsiElement result = PsiTreeUtil.getParentOfType(at, psiElement.getClass(), false); assert result != null; rangeMarker.dispose(); return result.getNode(); } else { assert false; } } } finally { if (rangeMarker != null) { rangeMarker.dispose(); } codeFormattingData.dispose(); } } return element; }