1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.puppycrawl.tools.checkstyle.gui;
21
22 import java.util.HashMap;
23 import java.util.Map;
24
25 import com.puppycrawl.tools.checkstyle.JavadocDetailNodeParser;
26 import com.puppycrawl.tools.checkstyle.api.DetailAST;
27 import com.puppycrawl.tools.checkstyle.api.DetailNode;
28 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
29 import com.puppycrawl.tools.checkstyle.gui.MainFrameModel.ParseMode;
30 import com.puppycrawl.tools.checkstyle.utils.JavadocUtil;
31 import com.puppycrawl.tools.checkstyle.utils.TokenUtil;
32
33
34
35
36
37 public class ParseTreeTablePresentation {
38
39
40 private static final String UNKNOWN_COLUMN_MSG = "Unknown column";
41
42
43 private static final String[] COLUMN_NAMES = {
44 "Tree",
45 "Type",
46 "Line",
47 "Column",
48 "Text",
49 };
50
51
52 private final Map<DetailAST, DetailNode> blockCommentToJavadocTree = new HashMap<>();
53
54
55 private DetailAST root;
56
57
58 private ParseMode parseMode;
59
60
61
62
63
64
65 public ParseTreeTablePresentation(DetailAST parseTree) {
66 root = parseTree;
67 }
68
69
70
71
72
73
74 protected final void setRoot(DetailAST parseTree) {
75 root = parseTree;
76 }
77
78
79
80
81
82
83 protected void setParseMode(ParseMode mode) {
84 parseMode = mode;
85 }
86
87
88
89
90
91
92 public int getColumnCount() {
93 return COLUMN_NAMES.length;
94 }
95
96
97
98
99
100
101
102 public String getColumnName(int column) {
103 return COLUMN_NAMES[column];
104 }
105
106
107
108
109
110
111
112
113
114
115 public Class<?> getColumnClass(int column) {
116 final Class<?> columnClass;
117
118 switch (column) {
119 case 0:
120 columnClass = ParseTreeTableModel.class;
121 break;
122 case 1:
123 case 4:
124 columnClass = String.class;
125 break;
126 case 2:
127 case 3:
128 columnClass = Integer.class;
129 break;
130 default:
131 throw new IllegalStateException(UNKNOWN_COLUMN_MSG);
132 }
133 return columnClass;
134 }
135
136
137
138
139
140
141
142
143 public Object getValueAt(Object node, int column) {
144 final Object result;
145
146 if (node instanceof DetailNode) {
147 result = getValueAtDetailNode((DetailNode) node, column);
148 }
149 else {
150 result = getValueAtDetailAST((DetailAST) node, column);
151 }
152
153 return result;
154 }
155
156
157
158
159
160
161
162
163 public Object getChild(Object parent, int index) {
164 final Object result;
165
166 if (parent instanceof DetailNode) {
167 result = ((DetailNode) parent).getChildren()[index];
168 }
169 else {
170 result = getChildAtDetailAst((DetailAST) parent, index);
171 }
172
173 return result;
174 }
175
176
177
178
179
180
181
182 public int getChildCount(Object parent) {
183 final int result;
184
185 if (parent instanceof DetailNode) {
186 result = ((DetailNode) parent).getChildren().length;
187 }
188 else {
189 if (parseMode == ParseMode.JAVA_WITH_JAVADOC_AND_COMMENTS
190 && ((DetailAST) parent).getType() == TokenTypes.COMMENT_CONTENT
191 && JavadocUtil.isJavadocComment(((DetailAST) parent).getParent())) {
192
193
194 result = 1;
195 }
196 else {
197 result = ((DetailAST) parent).getChildCount();
198 }
199 }
200
201 return result;
202 }
203
204
205
206
207
208
209 public Object getRoot() {
210 return root;
211 }
212
213
214
215
216
217
218
219 public boolean isLeaf(Object node) {
220 return getChildCount(node) == 0;
221 }
222
223
224
225
226
227
228
229
230
231
232
233
234
235 public int getIndexOfChild(Object parent, Object child) {
236 int index = -1;
237 for (int i = 0; i < getChildCount(parent); i++) {
238 if (getChild(parent, i).equals(child)) {
239 index = i;
240 break;
241 }
242 }
243 return index;
244 }
245
246
247
248
249
250
251
252
253 public boolean isCellEditable(int column) {
254 return false;
255 }
256
257
258
259
260
261
262
263
264
265 private Object getChildAtDetailAst(DetailAST parent, int index) {
266 final Object result;
267 if (parseMode == ParseMode.JAVA_WITH_JAVADOC_AND_COMMENTS
268 && parent.getType() == TokenTypes.COMMENT_CONTENT
269 && JavadocUtil.isJavadocComment(parent.getParent())) {
270 result = getJavadocTree(parent.getParent());
271 }
272 else {
273 int currentIndex = 0;
274 DetailAST child = parent.getFirstChild();
275 while (currentIndex < index) {
276 child = child.getNextSibling();
277 currentIndex++;
278 }
279 result = child;
280 }
281
282 return result;
283 }
284
285
286
287
288
289
290
291
292
293 private static Object getValueAtDetailNode(DetailNode node, int column) {
294 final Object value;
295
296 switch (column) {
297 case 0:
298
299 value = null;
300 break;
301 case 1:
302 value = JavadocUtil.getTokenName(node.getType());
303 break;
304 case 2:
305 value = node.getLineNumber();
306 break;
307 case 3:
308 value = node.getColumnNumber();
309 break;
310 case 4:
311 value = node.getText();
312 break;
313 default:
314 throw new IllegalStateException(UNKNOWN_COLUMN_MSG);
315 }
316 return value;
317 }
318
319
320
321
322
323
324
325
326
327 private static Object getValueAtDetailAST(DetailAST ast, int column) {
328 final Object value;
329
330 switch (column) {
331 case 0:
332
333 value = null;
334 break;
335 case 1:
336 value = TokenUtil.getTokenName(ast.getType());
337 break;
338 case 2:
339 value = ast.getLineNo();
340 break;
341 case 3:
342 value = ast.getColumnNo();
343 break;
344 case 4:
345 value = ast.getText();
346 break;
347 default:
348 throw new IllegalStateException(UNKNOWN_COLUMN_MSG);
349 }
350 return value;
351 }
352
353
354
355
356
357
358
359 private DetailNode getJavadocTree(DetailAST blockComment) {
360 return blockCommentToJavadocTree.computeIfAbsent(blockComment,
361 ParseTreeTablePresentation::parseJavadocTree);
362 }
363
364
365
366
367
368
369
370 private static DetailNode parseJavadocTree(DetailAST blockComment) {
371 return new JavadocDetailNodeParser().parseJavadocAsDetailNode(blockComment).getTree();
372 }
373
374 }