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.checks.annotation;
21
22 import com.puppycrawl.tools.checkstyle.StatelessCheck;
23 import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
24 import com.puppycrawl.tools.checkstyle.api.DetailAST;
25 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
26 import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
27 import com.puppycrawl.tools.checkstyle.utils.TokenUtil;
28
29
30
31
32
33
34
35
36
37 @StatelessCheck
38 public class AnnotationOnSameLineCheck extends AbstractCheck {
39
40
41 public static final String MSG_KEY_ANNOTATION_ON_SAME_LINE = "annotation.same.line";
42
43 @Override
44 public int[] getDefaultTokens() {
45 return new int[] {
46 TokenTypes.CLASS_DEF,
47 TokenTypes.INTERFACE_DEF,
48 TokenTypes.ENUM_DEF,
49 TokenTypes.METHOD_DEF,
50 TokenTypes.CTOR_DEF,
51 TokenTypes.VARIABLE_DEF,
52 TokenTypes.RECORD_DEF,
53 TokenTypes.COMPACT_CTOR_DEF,
54 };
55 }
56
57 @Override
58 public int[] getAcceptableTokens() {
59 return new int[] {
60 TokenTypes.CLASS_DEF,
61 TokenTypes.INTERFACE_DEF,
62 TokenTypes.ENUM_DEF,
63 TokenTypes.METHOD_DEF,
64 TokenTypes.CTOR_DEF,
65 TokenTypes.VARIABLE_DEF,
66 TokenTypes.PARAMETER_DEF,
67 TokenTypes.ANNOTATION_DEF,
68 TokenTypes.TYPECAST,
69 TokenTypes.LITERAL_THROWS,
70 TokenTypes.IMPLEMENTS_CLAUSE,
71 TokenTypes.TYPE_ARGUMENT,
72 TokenTypes.LITERAL_NEW,
73 TokenTypes.DOT,
74 TokenTypes.ANNOTATION_FIELD_DEF,
75 TokenTypes.RECORD_DEF,
76 TokenTypes.COMPACT_CTOR_DEF,
77 };
78 }
79
80 @Override
81 public int[] getRequiredTokens() {
82 return CommonUtil.EMPTY_INT_ARRAY;
83 }
84
85 @Override
86 public void visitToken(DetailAST ast) {
87 DetailAST nodeWithAnnotations = ast;
88 if (ast.getType() == TokenTypes.TYPECAST) {
89 nodeWithAnnotations = ast.findFirstToken(TokenTypes.TYPE);
90 }
91 DetailAST modifiersNode = nodeWithAnnotations.findFirstToken(TokenTypes.MODIFIERS);
92 if (modifiersNode == null) {
93 modifiersNode = nodeWithAnnotations.findFirstToken(TokenTypes.ANNOTATIONS);
94 }
95 if (modifiersNode != null) {
96 for (DetailAST annotationNode = modifiersNode.getFirstChild();
97 annotationNode != null;
98 annotationNode = annotationNode.getNextSibling()) {
99 if (annotationNode.getType() == TokenTypes.ANNOTATION
100 && !TokenUtil.areOnSameLine(annotationNode,
101 modifiersNode.getNextSibling())) {
102 log(annotationNode, MSG_KEY_ANNOTATION_ON_SAME_LINE,
103 getAnnotationName(annotationNode));
104 }
105 }
106 }
107 }
108
109
110
111
112
113
114
115 private static String getAnnotationName(DetailAST annotation) {
116 DetailAST identNode = annotation.findFirstToken(TokenTypes.IDENT);
117 if (identNode == null) {
118 identNode = annotation.findFirstToken(TokenTypes.DOT).getLastChild();
119 }
120 return identNode.getText();
121 }
122
123 }