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 isOnInterface(DetailAST blockComment) {
105 return isOnPlainToken(blockComment, TokenTypes.INTERFACE_DEF, TokenTypes.LITERAL_INTERFACE)
106 || isOnTokenWithModifiers(blockComment, TokenTypes.INTERFACE_DEF)
107 || isOnTokenWithAnnotation(blockComment, TokenTypes.INTERFACE_DEF);
108 }
109
110
111
112
113
114
115
116 public static boolean isOnEnum(DetailAST blockComment) {
117 return isOnPlainToken(blockComment, TokenTypes.ENUM_DEF, TokenTypes.ENUM)
118 || isOnTokenWithModifiers(blockComment, TokenTypes.ENUM_DEF)
119 || isOnTokenWithAnnotation(blockComment, TokenTypes.ENUM_DEF);
120 }
121
122
123
124
125
126
127
128 public static boolean isOnAnnotationDef(DetailAST blockComment) {
129 return isOnPlainToken(blockComment, TokenTypes.ANNOTATION_DEF, TokenTypes.AT)
130 || isOnTokenWithModifiers(blockComment, TokenTypes.ANNOTATION_DEF)
131 || isOnTokenWithAnnotation(blockComment, TokenTypes.ANNOTATION_DEF);
132 }
133
134
135
136
137
138
139
140
141 public static boolean isOnMember(DetailAST blockComment) {
142 return isOnMethod(blockComment)
143 || isOnField(blockComment)
144 || isOnConstructor(blockComment)
145 || isOnEnumConstant(blockComment)
146 || isOnAnnotationField(blockComment)
147 || isOnCompactConstructor(blockComment);
148 }
149
150
151
152
153
154
155
156 public static boolean isOnMethod(DetailAST blockComment) {
157 return isOnPlainClassMember(blockComment)
158 || isOnTokenWithModifiers(blockComment, TokenTypes.METHOD_DEF)
159 || isOnTokenWithAnnotation(blockComment, TokenTypes.METHOD_DEF);
160 }
161
162
163
164
165
166
167
168 public static boolean isOnField(DetailAST blockComment) {
169 return isOnPlainClassMember(blockComment)
170 || isOnTokenWithModifiers(blockComment, TokenTypes.VARIABLE_DEF)
171 && blockComment.getParent().getParent().getParent()
172 .getType() == TokenTypes.OBJBLOCK
173 || isOnTokenWithAnnotation(blockComment, TokenTypes.VARIABLE_DEF)
174 && blockComment.getParent().getParent().getParent()
175 .getParent().getType() == TokenTypes.OBJBLOCK;
176 }
177
178
179
180
181
182
183
184 public static boolean isOnConstructor(DetailAST blockComment) {
185 return isOnPlainToken(blockComment, TokenTypes.CTOR_DEF, TokenTypes.IDENT)
186 || isOnTokenWithModifiers(blockComment, TokenTypes.CTOR_DEF)
187 || isOnTokenWithAnnotation(blockComment, TokenTypes.CTOR_DEF)
188 || isOnPlainClassMember(blockComment);
189 }
190
191
192
193
194
195
196
197
198 public static boolean isOnCompactConstructor(DetailAST blockComment) {
199 return isOnPlainToken(blockComment, TokenTypes.COMPACT_CTOR_DEF, TokenTypes.IDENT)
200 || isOnTokenWithModifiers(blockComment, TokenTypes.COMPACT_CTOR_DEF)
201 || isOnTokenWithAnnotation(blockComment, TokenTypes.COMPACT_CTOR_DEF);
202 }
203
204
205
206
207
208
209
210 public static boolean isOnEnumConstant(DetailAST blockComment) {
211 final DetailAST parent = blockComment.getParent();
212 boolean result = false;
213 if (parent.getType() == TokenTypes.ENUM_CONSTANT_DEF) {
214 final DetailAST prevSibling = getPrevSiblingSkipComments(blockComment);
215 if (prevSibling.getType() == TokenTypes.ANNOTATIONS && !prevSibling.hasChildren()) {
216 result = true;
217 }
218 }
219 else if (parent.getType() == TokenTypes.ANNOTATION
220 && parent.getParent().getParent().getType() == TokenTypes.ENUM_CONSTANT_DEF) {
221 result = true;
222 }
223
224 return result;
225 }
226
227
228
229
230
231
232
233 public static boolean isOnAnnotationField(DetailAST blockComment) {
234 return isOnPlainClassMember(blockComment)
235 || isOnTokenWithModifiers(blockComment, TokenTypes.ANNOTATION_FIELD_DEF)
236 || isOnTokenWithAnnotation(blockComment, TokenTypes.ANNOTATION_FIELD_DEF);
237 }
238
239
240
241
242
243
244
245
246
247 private static boolean isOnPlainToken(DetailAST blockComment,
248 int parentTokenType, int nextTokenType) {
249 return blockComment.getParent().getType() == parentTokenType
250 && !getPrevSiblingSkipComments(blockComment).hasChildren()
251 && getNextSiblingSkipComments(blockComment).getType() == nextTokenType;
252 }
253
254
255
256
257
258
259
260
261 private static boolean isOnTokenWithModifiers(DetailAST blockComment, int tokenType) {
262 return blockComment.getParent().getType() == TokenTypes.MODIFIERS
263 && blockComment.getParent().getParent().getType() == tokenType
264 && getPrevSiblingSkipComments(blockComment) == null;
265 }
266
267
268
269
270
271
272
273
274 private static boolean isOnTokenWithAnnotation(DetailAST blockComment, int tokenType) {
275 return blockComment.getParent().getType() == TokenTypes.ANNOTATION
276 && getPrevSiblingSkipComments(blockComment.getParent()) == null
277 && blockComment.getParent().getParent().getParent().getType() == tokenType
278 && getPrevSiblingSkipComments(blockComment) == null;
279 }
280
281
282
283
284
285
286
287 private static boolean isOnPlainClassMember(DetailAST blockComment) {
288 DetailAST parent = blockComment.getParent();
289
290 while (parent.getType() == TokenTypes.DOT) {
291 parent = parent.getParent();
292 }
293 return (parent.getType() == TokenTypes.TYPE
294 || parent.getType() == TokenTypes.TYPE_PARAMETERS)
295
296 && !parent.getPreviousSibling().hasChildren()
297 && parent.getParent().getParent().getType() == TokenTypes.OBJBLOCK;
298 }
299
300
301
302
303
304
305
306 private static DetailAST getNextSiblingSkipComments(DetailAST node) {
307 DetailAST result = node;
308 while (result.getType() == TokenTypes.SINGLE_LINE_COMMENT
309 || result.getType() == TokenTypes.BLOCK_COMMENT_BEGIN) {
310 result = result.getNextSibling();
311 }
312 return result;
313 }
314
315
316
317
318
319
320
321 private static DetailAST getPrevSiblingSkipComments(DetailAST node) {
322 DetailAST result = node.getPreviousSibling();
323 while (result != null
324 && (result.getType() == TokenTypes.SINGLE_LINE_COMMENT
325 || result.getType() == TokenTypes.BLOCK_COMMENT_BEGIN)) {
326 result = result.getPreviousSibling();
327 }
328 return result;
329 }
330
331 }