void (Appendable buffer, PsiElement root, int indent, boolean showWhitespaces, boolean showRanges, boolean showChildrenRanges, boolean showClassNames, @Nullable PairConsumer<? super PsiElement, ? super Consumer<? super PsiElement>> extra) { if (!showWhitespaces && root instanceof PsiWhiteSpace) return; StringUtil.repeatSymbol(buffer, ' ', indent); try { buffer.append(root.toString()); PsiElement child = root.getFirstChild(); if (child == null) { String text = root.getText(); assert text != null : "text is null for <" + root + ">"; buffer.append("('").append(fixWhiteSpaces(text)).append("')"); } if (showRanges) buffer.append(root.getTextRange().toString()); if (showClassNames) buffer.append("[").append(getPsiClassName(root)).append("]"); buffer.append("\n"); while (child != null) { psiToBuffer(buffer, child, indent + 2, showWhitespaces, showChildrenRanges, showChildrenRanges, showClassNames, extra); child = child.getNextSibling(); } if (extra != null) { Consumer<PsiElement> consumer = element -> psiToBuffer(buffer, element, indent + 2, !showWhitespaces, showChildrenRanges, showChildrenRanges, showClassNames, null); extra.consume(root, consumer); } } catch (IOException e) { LOG.error(e); } }