|
20 | 20 | package org.sonar.java.checks; |
21 | 21 |
|
22 | 22 | import com.google.common.collect.ImmutableList; |
| 23 | +import com.google.common.collect.Iterables; |
23 | 24 | import org.sonar.api.server.rule.RulesDefinition; |
24 | 25 | import org.sonar.check.Priority; |
25 | 26 | import org.sonar.check.Rule; |
|
32 | 33 | import org.sonar.plugins.java.api.tree.CaseGroupTree; |
33 | 34 | import org.sonar.plugins.java.api.tree.CaseLabelTree; |
34 | 35 | import org.sonar.plugins.java.api.tree.ClassTree; |
| 36 | +import org.sonar.plugins.java.api.tree.StatementTree; |
35 | 37 | import org.sonar.plugins.java.api.tree.SyntaxToken; |
36 | 38 | import org.sonar.plugins.java.api.tree.Tree; |
37 | 39 | import org.sonar.plugins.java.api.tree.Tree.Kind; |
@@ -104,57 +106,93 @@ public void visitNode(Tree tree) { |
104 | 106 | } |
105 | 107 | expectedLevel += indentationLevel; |
106 | 108 | isBlockAlreadyReported = false; |
107 | | - checkCaseGroup(tree); |
108 | | - checkClassTree(tree); |
109 | | - checkBlock(tree); |
| 109 | + |
| 110 | + switch (tree.kind()) { |
| 111 | + case CLASS: |
| 112 | + case ENUM: |
| 113 | + case INTERFACE: |
| 114 | + case ANNOTATION_TYPE: |
| 115 | + checkClass((ClassTree) tree); |
| 116 | + break; |
| 117 | + case CASE_GROUP: |
| 118 | + checkCaseGroup((CaseGroupTree) tree); |
| 119 | + break; |
| 120 | + case BLOCK: |
| 121 | + checkBlock((BlockTree) tree); |
| 122 | + break; |
| 123 | + default: |
| 124 | + break; |
| 125 | + } |
110 | 126 | } |
111 | 127 |
|
112 | | - private void checkCaseGroup(Tree tree) { |
113 | | - if (tree.is(Kind.CASE_GROUP)) { |
114 | | - List<CaseLabelTree> labels = ((CaseGroupTree) tree).labels(); |
115 | | - if (labels.size() >= 2) { |
116 | | - CaseLabelTree previousCaseLabelTree = labels.get(labels.size() - 2); |
117 | | - lastCheckedLine = LastSyntaxTokenFinder.lastSyntaxToken(previousCaseLabelTree).line(); |
118 | | - } |
119 | | - checkIndentation(((CaseGroupTree) tree).body()); |
| 128 | + private void checkClass(ClassTree classTree) { |
| 129 | + // Exclude anonymous classes |
| 130 | + if (classTree.simpleName() != null) { |
| 131 | + checkIndentation(classTree.members()); |
120 | 132 | } |
121 | 133 | } |
122 | 134 |
|
123 | | - private void checkClassTree(Tree tree) { |
124 | | - if (isClassTree(tree)) { |
125 | | - ClassTree classTree = (ClassTree) tree; |
126 | | - // Exclude anonymous classes |
127 | | - if (classTree.simpleName() != null) { |
128 | | - checkIndentation(classTree.members()); |
129 | | - } |
| 135 | + private void checkBlock(BlockTree blockTree) { |
| 136 | + adjustBlockForExceptionalParents(blockTree.parent()); |
| 137 | + checkIndentation(blockTree.body()); |
| 138 | + } |
| 139 | + |
| 140 | + private void checkCaseGroup(CaseGroupTree tree) { |
| 141 | + List<CaseLabelTree> labels = tree.labels(); |
| 142 | + if (labels.size() >= 2) { |
| 143 | + CaseLabelTree previousCaseLabelTree = labels.get(labels.size() - 2); |
| 144 | + lastCheckedLine = LastSyntaxTokenFinder.lastSyntaxToken(previousCaseLabelTree).line(); |
| 145 | + } |
| 146 | + List<StatementTree> body = tree.body(); |
| 147 | + List<StatementTree> newBody = body; |
| 148 | + int bodySize = body.size(); |
| 149 | + if (bodySize > 0 && body.get(0).is(Kind.BLOCK)) { |
| 150 | + expectedLevel -= indentationLevel; |
| 151 | + checkIndentation(body.get(0), Iterables.getLast(labels).colonToken().column() + 2); |
| 152 | + newBody = body.subList(1, bodySize); |
| 153 | + } |
| 154 | + checkIndentation(newBody); |
| 155 | + if (bodySize > 0 && body.get(0).is(Kind.BLOCK)) { |
| 156 | + expectedLevel += indentationLevel; |
130 | 157 | } |
131 | 158 | } |
132 | 159 |
|
133 | | - private void checkBlock(Tree tree) { |
134 | | - if (tree.is(Kind.BLOCK)) { |
135 | | - if (tree.parent().is(Kind.LAMBDA_EXPRESSION)) { |
136 | | - expectedLevel += indentationLevel; |
137 | | - } |
138 | | - checkIndentation(((BlockTree) tree).body()); |
139 | | - if (tree.parent().is(Kind.LAMBDA_EXPRESSION)) { |
140 | | - expectedLevel -= indentationLevel; |
141 | | - } |
| 160 | + private void adjustBlockForExceptionalParents(Tree parent) { |
| 161 | + if (parent.is(Kind.CASE_GROUP)) { |
| 162 | + expectedLevel -= indentationLevel; |
| 163 | + } else if (parent.is(Kind.LAMBDA_EXPRESSION)) { |
| 164 | + expectedLevel += indentationLevel; |
| 165 | + } |
| 166 | + } |
| 167 | + |
| 168 | + private void restoreBlockForExceptionalParents(Tree parent) { |
| 169 | + if (parent.is(Kind.CASE_GROUP)) { |
| 170 | + expectedLevel += indentationLevel; |
| 171 | + } else if (parent.is(Kind.LAMBDA_EXPRESSION)) { |
| 172 | + expectedLevel -= indentationLevel; |
142 | 173 | } |
143 | 174 | } |
144 | 175 |
|
145 | 176 | private void checkIndentation(List<? extends Tree> trees) { |
146 | 177 | for (Tree tree : trees) { |
147 | | - SyntaxToken firstSyntaxToken = FirstSyntaxTokenFinder.firstSyntaxToken(tree); |
148 | | - if (firstSyntaxToken.column() != expectedLevel && !isExcluded(tree, firstSyntaxToken.line())) { |
149 | | - addIssue(tree, "Make this line start at column " + (expectedLevel + 1) + "."); |
150 | | - isBlockAlreadyReported = true; |
151 | | - } |
152 | | - lastCheckedLine = LastSyntaxTokenFinder.lastSyntaxToken(tree).line(); |
| 178 | + checkIndentation(tree, expectedLevel); |
153 | 179 | } |
154 | 180 | } |
155 | 181 |
|
| 182 | + private void checkIndentation(Tree tree, int expectedLevel) { |
| 183 | + SyntaxToken firstSyntaxToken = FirstSyntaxTokenFinder.firstSyntaxToken(tree); |
| 184 | + if (firstSyntaxToken.column() != expectedLevel && !isExcluded(tree, firstSyntaxToken.line())) { |
| 185 | + addIssue(tree, "Make this line start at column " + (expectedLevel + 1) + "."); |
| 186 | + isBlockAlreadyReported = true; |
| 187 | + } |
| 188 | + lastCheckedLine = LastSyntaxTokenFinder.lastSyntaxToken(tree).line(); |
| 189 | + } |
| 190 | + |
156 | 191 | @Override |
157 | 192 | public void leaveNode(Tree tree) { |
| 193 | + if (tree.is(Kind.BLOCK)) { |
| 194 | + restoreBlockForExceptionalParents(tree.parent()); |
| 195 | + } |
158 | 196 | expectedLevel -= indentationLevel; |
159 | 197 | isBlockAlreadyReported = false; |
160 | 198 | lastCheckedLine = LastSyntaxTokenFinder.lastSyntaxToken(tree).line(); |
|
0 commit comments