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 isOnTokenWithModifiers(blockComment, TokenTypes.COMPACT_CTOR_DEF)
200 || isOnTokenWithAnnotation(blockComment, TokenTypes.COMPACT_CTOR_DEF);
201 }
202
203
204
205
206
207
208
209 public static boolean isOnEnumConstant(DetailAST blockComment) {
210 final DetailAST parent = blockComment.getParent();
211 boolean result = false;
212 if (parent.getType() == TokenTypes.ENUM_CONSTANT_DEF) {
213 final DetailAST prevSibling = getPrevSiblingSkipComments(blockComment);
214 if (prevSibling.getType() == TokenTypes.ANNOTATIONS && !prevSibling.hasChildren()) {
215 result = true;
216 }
217 }
218 else if (parent.getType() == TokenTypes.ANNOTATION
219 && parent.getParent().getParent().getType() == TokenTypes.ENUM_CONSTANT_DEF) {
220 result = true;
221 }
222
223 return result;
224 }
225
226
227
228
229
230
231
232 public static boolean isOnAnnotationField(DetailAST blockComment) {
233 return isOnPlainClassMember(blockComment)
234 || isOnTokenWithModifiers(blockComment, TokenTypes.ANNOTATION_FIELD_DEF)
235 || isOnTokenWithAnnotation(blockComment, TokenTypes.ANNOTATION_FIELD_DEF);
236 }
237
238
239
240
241
242
243
244
245
246 private static boolean isOnPlainToken(DetailAST blockComment,
247 int parentTokenType, int nextTokenType) {
248 return blockComment.getParent().getType() == parentTokenType
249 && !getPrevSiblingSkipComments(blockComment).hasChildren()
250 && getNextSiblingSkipComments(blockComment).getType() == nextTokenType;
251 }
252
253
254
255
256
257
258
259
260 private static boolean isOnTokenWithModifiers(DetailAST blockComment, int tokenType) {
261 return blockComment.getParent().getType() == TokenTypes.MODIFIERS
262 && blockComment.getParent().getParent().getType() == tokenType
263 && getPrevSiblingSkipComments(blockComment) == null;
264 }
265
266
267
268
269
270
271
272
273 private static boolean isOnTokenWithAnnotation(DetailAST blockComment, int tokenType) {
274 return blockComment.getParent().getType() == TokenTypes.ANNOTATION
275 && getPrevSiblingSkipComments(blockComment.getParent()) == null
276 && blockComment.getParent().getParent().getParent().getType() == tokenType
277 && getPrevSiblingSkipComments(blockComment) == null;
278 }
279
280
281
282
283
284
285
286 private static boolean isOnPlainClassMember(DetailAST blockComment) {
287 DetailAST parent = blockComment.getParent();
288
289 while (parent.getType() == TokenTypes.DOT) {
290 parent = parent.getParent();
291 }
292 return (parent.getType() == TokenTypes.TYPE
293 || parent.getType() == TokenTypes.TYPE_PARAMETERS)
294
295 && !parent.getPreviousSibling().hasChildren()
296 && parent.getParent().getParent().getType() == TokenTypes.OBJBLOCK;
297 }
298
299
300
301
302
303
304
305 private static DetailAST getNextSiblingSkipComments(DetailAST node) {
306 DetailAST result = node;
307 while (result.getType() == TokenTypes.SINGLE_LINE_COMMENT
308 || result.getType() == TokenTypes.BLOCK_COMMENT_BEGIN) {
309 result = result.getNextSibling();
310 }
311 return result;
312 }
313
314
315
316
317
318
319
320 private static DetailAST getPrevSiblingSkipComments(DetailAST node) {
321 DetailAST result = node.getPreviousSibling();
322 while (result != null
323 && (result.getType() == TokenTypes.SINGLE_LINE_COMMENT
324 || result.getType() == TokenTypes.BLOCK_COMMENT_BEGIN)) {
325 result = result.getPreviousSibling();
326 }
327 return result;
328 }
329
330 }