package org.jetbrains.javafx.formatter; import com.intellij.formatting.*; import com.intellij.lang.ASTNode; import com.intellij.lang.FileASTNode; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.formatter.FormatterUtil; import com.intellij.psi.formatter.common.AbstractBlock; import com.intellij.psi.impl.source.tree.LeafElement; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.javafx.lang.lexer.JavaFxTokenTypes; import org.jetbrains.javafx.lang.parser.JavaFxElementTypes; import java.util.ArrayList; import java.util.List; /** * Created by IntelliJ IDEA. * * @author Alexey.Ivanov */ class JavaFxFormattingBlock extends AbstractBlock { protected final Indent myIndent; protected final Indent myChildIndent; protected final CodeStyleSettings myCodeStyleSettings; public JavaFxFormattingBlock(@NotNull final FileASTNode node, @NotNull final CodeStyleSettings codeStyleSettings) { this(node, codeStyleSettings, Indent.getAbsoluteNoneIndent(), Indent.getNoneIndent()); } public JavaFxFormattingBlock(@NotNull final ASTNode node, @NotNull final CodeStyleSettings codeStyleSettings, final Indent indent, final Indent childIndent) { this(node, null, null, codeStyleSettings, indent, childIndent); } protected JavaFxFormattingBlock(@NotNull final ASTNode node, @Nullable final Wrap wrap, @Nullable final Alignment alignment, @NotNull final CodeStyleSettings codeStyleSettings, final Indent indent, final Indent childIndent) { super(node, wrap, alignment); myCodeStyleSettings = codeStyleSettings; myIndent = indent; myChildIndent = childIndent; } @Override protected List buildChildren() { if (isLeaf()) { return EMPTY; } final List result = new ArrayList(); ASTNode child = myNode.getFirstChildNode(); while (child != null) { if (!FormatterUtil.containsWhiteSpacesOnly(child) && child.getTextLength() > 0) { processChild(result, child); } child = child.getTreeNext(); } return result; } private void processChild(final List blocks, final ASTNode node) { final IElementType type = node.getElementType(); final Indent childIndent = calcIndent(node, type); if (type == JavaFxElementTypes.BLOCK_EXPRESSION || type == JavaFxElementTypes.OBJECT_LITERAL || type == JavaFxElementTypes.SEQUENCE_LITERAL || type == JavaFxElementTypes.CLASS_DEFINITION) { blocks.add(new JavaFxBlockFormattingBlock(node, myCodeStyleSettings, childIndent, Indent.getNormalIndent(false))); } else { blocks.add(new JavaFxFormattingBlock(node, myCodeStyleSettings, childIndent, Indent.getNoneIndent())); } } protected Indent calcIndent(final ASTNode child, final IElementType childType) { return (childType == JavaFxTokenTypes.LBRACE || childType == JavaFxTokenTypes.RBRACE) ? Indent.getNoneIndent() : myChildIndent; } @Override public Spacing getSpacing(final Block child1, final Block child2) { return null; } @Override public boolean isLeaf() { return (myNode instanceof LeafElement); } @Override protected Indent getChildIndent() { return myChildIndent; } @Override public Indent getIndent() { return myIndent; } private static class JavaFxBlockFormattingBlock extends JavaFxFormattingBlock { private boolean myInsideBraces; public JavaFxBlockFormattingBlock(@NotNull final ASTNode node, @NotNull final CodeStyleSettings codeStyleSettings, final Indent indent, final Indent childIndent) { super(node, codeStyleSettings, indent, childIndent); } @Override protected Indent calcIndent(final ASTNode child, final IElementType childType) { if (JavaFxFormattingUtil.isBrace(childType)) { myInsideBraces = (childType == JavaFxTokenTypes.LBRACE || childType == JavaFxTokenTypes.LBRACK); return Indent.getNoneIndent(); } return myInsideBraces ? myChildIndent : Indent.getNoneIndent(); } } }