formatter tests and minor fixes
[idea/javafx-plugin.git] / src / org / jetbrains / javafx / formatter / JavaFxFormattingBlock.java
1 package org.jetbrains.javafx.formatter;
2
3 import com.intellij.formatting.*;
4 import com.intellij.lang.ASTNode;
5 import com.intellij.lang.FileASTNode;
6 import com.intellij.psi.codeStyle.CodeStyleSettings;
7 import com.intellij.psi.formatter.FormatterUtil;
8 import com.intellij.psi.formatter.common.AbstractBlock;
9 import com.intellij.psi.impl.source.tree.LeafElement;
10 import com.intellij.psi.tree.IElementType;
11 import org.jetbrains.annotations.NotNull;
12 import org.jetbrains.annotations.Nullable;
13 import org.jetbrains.javafx.lang.lexer.JavaFxTokenTypes;
14 import org.jetbrains.javafx.lang.parser.JavaFxElementTypes;
15
16 import java.util.ArrayList;
17 import java.util.List;
18
19 /**
20  * Created by IntelliJ IDEA.
21  *
22  * @author Alexey.Ivanov
23  */
24 class JavaFxFormattingBlock extends AbstractBlock {
25   protected final Indent myIndent;
26   protected final Indent myChildIndent;
27   protected final CodeStyleSettings myCodeStyleSettings;
28
29   public JavaFxFormattingBlock(@NotNull final FileASTNode node, @NotNull final CodeStyleSettings codeStyleSettings) {
30     this(node, codeStyleSettings, Indent.getAbsoluteNoneIndent(), Indent.getNoneIndent());
31   }
32
33   public JavaFxFormattingBlock(@NotNull final ASTNode node,
34                                @NotNull final CodeStyleSettings codeStyleSettings,
35                                final Indent indent,
36                                final Indent childIndent) {
37     this(node, null, null, codeStyleSettings, indent, childIndent);
38   }
39
40   protected JavaFxFormattingBlock(@NotNull final ASTNode node,
41                                   @Nullable final Wrap wrap,
42                                   @Nullable final Alignment alignment,
43                                   @NotNull final CodeStyleSettings codeStyleSettings,
44                                   final Indent indent,
45                                   final Indent childIndent) {
46     super(node, wrap, alignment);
47     myCodeStyleSettings = codeStyleSettings;
48     myIndent = indent;
49     myChildIndent = childIndent;
50   }
51
52   @Override
53   protected List<Block> buildChildren() {
54     if (isLeaf()) {
55       return EMPTY;
56     }
57
58     final List<Block> result = new ArrayList<Block>();
59     ASTNode child = myNode.getFirstChildNode();
60     while (child != null) {
61       if (!FormatterUtil.containsWhiteSpacesOnly(child) && child.getTextLength() > 0) {
62         processChild(result, child);
63       }
64       child = child.getTreeNext();
65     }
66     return result;
67   }
68
69   private void processChild(final List<Block> blocks, final ASTNode node) {
70     final IElementType type = node.getElementType();
71     final Indent childIndent = calcIndent(node, type);
72
73     if (type == JavaFxElementTypes.BLOCK_EXPRESSION ||
74         type == JavaFxElementTypes.OBJECT_LITERAL ||
75         type == JavaFxElementTypes.SEQUENCE_LITERAL ||
76         type == JavaFxElementTypes.CLASS_DEFINITION) {
77       blocks.add(new JavaFxBlockFormattingBlock(node, myCodeStyleSettings, childIndent, Indent.getNormalIndent(false)));
78     }
79     else {
80       blocks.add(new JavaFxFormattingBlock(node, myCodeStyleSettings, childIndent, Indent.getNoneIndent()));
81     }
82   }
83
84   protected Indent calcIndent(final ASTNode child, final IElementType childType) {
85     return (childType == JavaFxTokenTypes.LBRACE || childType == JavaFxTokenTypes.RBRACE) ? Indent.getNoneIndent() : myChildIndent;
86   }
87
88   @Override
89   public Spacing getSpacing(final Block child1, final Block child2) {
90     return null;
91   }
92
93   @Override
94   public boolean isLeaf() {
95     return (myNode instanceof LeafElement);
96   }
97
98   @Override
99   protected Indent getChildIndent() {
100     return myChildIndent;
101   }
102
103   @Override
104   public Indent getIndent() {
105     return myIndent;
106   }
107
108   private static class JavaFxBlockFormattingBlock extends JavaFxFormattingBlock {
109     private boolean myInsideBraces;
110
111     public JavaFxBlockFormattingBlock(@NotNull final ASTNode node,
112                                       @NotNull final CodeStyleSettings codeStyleSettings,
113                                       final Indent indent,
114                                       final Indent childIndent) {
115       super(node, codeStyleSettings, indent, childIndent);
116     }
117
118     @Override
119     protected Indent calcIndent(final ASTNode child, final IElementType childType) {
120       if (JavaFxFormattingUtil.isBrace(childType)) {
121         myInsideBraces = (childType == JavaFxTokenTypes.LBRACE || childType == JavaFxTokenTypes.LBRACK);
122         return Indent.getNoneIndent();
123       }
124       return myInsideBraces ? myChildIndent : Indent.getNoneIndent();
125     }
126   }
127 }