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.utils;
21
22 import com.puppycrawl.tools.checkstyle.api.DetailAST;
23 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
24
25
26
27
28
29 public final class BlockCommentPosition {
30
31
32
33
34 private BlockCommentPosition() {
35 }
36
37
38
39
40
41
42
43 public static boolean isOnType(DetailAST blockComment) {
44 return isOnClass(blockComment)
45 || isOnInterface(blockComment)
46 || isOnEnum(blockComment)
47 || isOnAnnotationDef(blockComment)
48 || isOnRecord(blockComment);
49 }
50
51
52
53
54
55
56
57 public static boolean isOnClass(DetailAST blockComment) {
58 return isOnPlainToken(blockComment, TokenTypes.CLASS_DEF, TokenTypes.LITERAL_CLASS)
59 || isOnTokenWithModifiers(blockComment, TokenTypes.CLASS_DEF)
60 || isOnTokenWithAnnotation(blockComment, TokenTypes.CLASS_DEF);
61 }
62
63
64
65
66
67
68
69 public static boolean isOnRecord(DetailAST blockComment) {
70 return isOnPlainToken(blockComment, TokenTypes.RECORD_DEF, TokenTypes.LITERAL_RECORD)
71 || isOnTokenWithModifiers(blockComment, TokenTypes.RECORD_DEF)
72 || isOnTokenWithAnnotation(blockComment, TokenTypes.RECORD_DEF);
73 }
74
75
76
77
78
79
80
81 public static boolean isOnPackage(DetailAST blockComment) {
82 boolean result = isOnTokenWithAnnotation(blockComment, TokenTypes.PACKAGE_DEF);
83
84 if (!result) {
85 DetailAST nextSibling = blockComment.getNextSibling();
86
87 while (nextSibling != null
88 && nextSibling.getType() == TokenTypes.SINGLE_LINE_COMMENT) {
89 nextSibling = nextSibling.getNextSibling();
90 }
91
92 result = nextSibling != null && nextSibling.getType() == TokenTypes.PACKAGE_DEF;
93 }
94
95 return result;
96 }
97
98
99
100
101
102
103
104 public static boolean isOnModule(DetailAST blockComment) {
105 return isOnModuleWithoutAnnotation(blockComment)
106 || isOnTokenWithAnnotation(blockComment, TokenTypes.MODULE_DEF);
107 }
108
109
110
111
112
113
114
115 public static boolean isOnInterface(DetailAST blockComment) {
116 return isOnPlainToken(blockComment, TokenTypes.INTERFACE_DEF, TokenTypes.LITERAL_INTERFACE)
117 || isOnTokenWithModifiers(blockComment, TokenTypes.INTERFACE_DEF)
118 || isOnTokenWithAnnotation(blockComment, TokenTypes.INTERFACE_DEF);
119 }
120
121
122
123
124
125
126
127 public static boolean isOnEnum(DetailAST blockComment) {
128 return isOnPlainToken(blockComment, TokenTypes.ENUM_DEF, TokenTypes.ENUM)
129 || isOnTokenWithModifiers(blockComment, TokenTypes.ENUM_DEF)
130 || isOnTokenWithAnnotation(blockComment, TokenTypes.ENUM_DEF);
131 }
132
133
134
135
136
137
138
139 public static boolean isOnAnnotationDef(DetailAST blockComment) {
140 return isOnPlainToken(blockComment, TokenTypes.ANNOTATION_DEF, TokenTypes.AT)
141 || isOnTokenWithModifiers(blockComment, TokenTypes.ANNOTATION_DEF)
142 || isOnTokenWithAnnotation(blockComment, TokenTypes.ANNOTATION_DEF);
143 }
144
145
146
147
148
149
150
151
152 public static boolean isOnMember(DetailAST blockComment) {
153 return isOnMethod(blockComment)
154 || isOnField(blockComment)
155 || isOnConstructor(blockComment)
156 || isOnEnumConstant(blockComment)
157 || isOnAnnotationField(blockComment)
158 || isOnCompactConstructor(blockComment);
159 }
160
161
162
163
164
165
166
167 public static boolean isOnMethod(DetailAST blockComment) {
168 return isOnPlainClassMember(blockComment)
169 || isOnTokenWithModifiers(blockComment, TokenTypes.METHOD_DEF)
170 || isOnTokenWithAnnotation(blockComment, TokenTypes.METHOD_DEF);
171 }
172
173
174
175
176
177
178
179 public static boolean isOnField(DetailAST blockComment) {
180 return isOnPlainClassMember(blockComment)
181 || isOnTokenWithModifiers(blockComment, TokenTypes.VARIABLE_DEF)
182 && isTypeMemberContainer(blockComment.getParent().getParent().getParent())
183 || isOnTokenWithAnnotation(blockComment, TokenTypes.VARIABLE_DEF)
184 && isTypeMemberContainer(
185 blockComment.getParent().getParent().getParent().getParent());
186 }
187
188
189
190
191
192
193
194 public static boolean isOnConstructor(DetailAST blockComment) {
195 return isOnPlainToken(blockComment, TokenTypes.CTOR_DEF, TokenTypes.IDENT)
196 || isOnTokenWithModifiers(blockComment, TokenTypes.CTOR_DEF)
197 || isOnTokenWithAnnotation(blockComment, TokenTypes.CTOR_DEF)
198 || isOnPlainClassMember(blockComment);
199 }
200
201
202
203
204
205
206
207
208 public static boolean isOnCompactConstructor(DetailAST blockComment) {
209 return isOnPlainToken(blockComment, TokenTypes.COMPACT_CTOR_DEF, TokenTypes.IDENT)
210 || isOnTokenWithModifiers(blockComment, TokenTypes.COMPACT_CTOR_DEF)
211 || isOnTokenWithAnnotation(blockComment, TokenTypes.COMPACT_CTOR_DEF);
212 }
213
214
215
216
217
218
219
220 public static boolean isOnEnumConstant(DetailAST blockComment) {
221 final DetailAST parent = blockComment.getParent();
222 boolean result = false;
223 if (parent.getType() == TokenTypes.ENUM_CONSTANT_DEF) {
224 final DetailAST prevSibling = getPrevSiblingSkipComments(blockComment);
225 if (prevSibling.getType() == TokenTypes.ANNOTATIONS && !prevSibling.hasChildren()) {
226 result = true;
227 }
228 }
229 else if (parent.getType() == TokenTypes.ANNOTATION
230 && parent.getParent().getParent().getType() == TokenTypes.ENUM_CONSTANT_DEF) {
231 result = true;
232 }
233
234 return result;
235 }
236
237
238
239
240
241
242
243 public static boolean isOnAnnotationField(DetailAST blockComment) {
244 return isOnPlainClassMember(blockComment)
245 || isOnTokenWithModifiers(blockComment, TokenTypes.ANNOTATION_FIELD_DEF)
246 || isOnTokenWithAnnotation(blockComment, TokenTypes.ANNOTATION_FIELD_DEF);
247 }
248
249
250
251
252
253
254
255
256
257
258 private static boolean isOnModuleWithoutAnnotation(DetailAST blockComment) {
259 final DetailAST prevSibling = getPrevSiblingSkipComments(blockComment);
260 return blockComment.getParent().getType() == TokenTypes.MODULE_DEF
261 && prevSibling.getType() == TokenTypes.ANNOTATIONS
262 && !prevSibling.hasChildren();
263 }
264
265
266
267
268
269
270
271
272
273 private static boolean isOnPlainToken(DetailAST blockComment,
274 int parentTokenType, int nextTokenType) {
275 return blockComment.getParent().getType() == parentTokenType
276 && !getPrevSiblingSkipComments(blockComment).hasChildren()
277 && getNextSiblingSkipComments(blockComment).getType() == nextTokenType;
278 }
279
280
281
282
283
284
285
286
287 private static boolean isOnTokenWithModifiers(DetailAST blockComment, int tokenType) {
288 return blockComment.getParent().getType() == TokenTypes.MODIFIERS
289 && blockComment.getParent().getParent().getType() == tokenType
290 && getPrevSiblingSkipComments(blockComment) == null;
291 }
292
293
294
295
296
297
298
299
300 private static boolean isOnTokenWithAnnotation(DetailAST blockComment, int tokenType) {
301 return blockComment.getParent().getType() == TokenTypes.ANNOTATION
302 && getPrevSiblingSkipComments(blockComment.getParent()) == null
303 && blockComment.getParent().getParent().getParent().getType() == tokenType
304 && getPrevSiblingSkipComments(blockComment) == null;
305 }
306
307
308
309
310
311
312
313 private static boolean isOnPlainClassMember(DetailAST blockComment) {
314 DetailAST parent = blockComment.getParent();
315
316 while (parent.getType() == TokenTypes.DOT) {
317 parent = parent.getParent();
318 }
319 return (parent.getType() == TokenTypes.TYPE
320 || parent.getType() == TokenTypes.TYPE_PARAMETERS)
321
322 && !parent.getPreviousSibling().hasChildren()
323 && isTypeMemberContainer(parent.getParent().getParent());
324 }
325
326
327
328
329
330
331
332
333
334
335 private static boolean isTypeMemberContainer(DetailAST container) {
336 return container.getType() == TokenTypes.OBJBLOCK
337 || container.getType() == TokenTypes.COMPACT_COMPILATION_UNIT;
338 }
339
340
341
342
343
344
345
346 private static DetailAST getNextSiblingSkipComments(DetailAST node) {
347 DetailAST result = node;
348 while (result.getType() == TokenTypes.SINGLE_LINE_COMMENT
349 || result.getType() == TokenTypes.BLOCK_COMMENT_BEGIN) {
350 result = result.getNextSibling();
351 }
352 return result;
353 }
354
355
356
357
358
359
360
361 private static DetailAST getPrevSiblingSkipComments(DetailAST node) {
362 DetailAST result = node.getPreviousSibling();
363 while (result != null
364 && (result.getType() == TokenTypes.SINGLE_LINE_COMMENT
365 || result.getType() == TokenTypes.BLOCK_COMMENT_BEGIN)) {
366 result = result.getPreviousSibling();
367 }
368 return result;
369 }
370
371 }