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
44
45
46 public AnnotationOnSameLineCheck() {
47
48 }
49
50 @Override
51 public int[] getDefaultTokens() {
52 return new int[] {
53 TokenTypes.CLASS_DEF,
54 TokenTypes.INTERFACE_DEF,
55 TokenTypes.ENUM_DEF,
56 TokenTypes.METHOD_DEF,
57 TokenTypes.CTOR_DEF,
58 TokenTypes.VARIABLE_DEF,
59 TokenTypes.RECORD_DEF,
60 TokenTypes.COMPACT_CTOR_DEF,
61 };
62 }
63
64 @Override
65 public int[] getAcceptableTokens() {
66 return new int[] {
67 TokenTypes.CLASS_DEF,
68 TokenTypes.INTERFACE_DEF,
69 TokenTypes.ENUM_DEF,
70 TokenTypes.METHOD_DEF,
71 TokenTypes.CTOR_DEF,
72 TokenTypes.VARIABLE_DEF,
73 TokenTypes.PARAMETER_DEF,
74 TokenTypes.ANNOTATION_DEF,
75 TokenTypes.TYPECAST,
76 TokenTypes.LITERAL_THROWS,
77 TokenTypes.IMPLEMENTS_CLAUSE,
78 TokenTypes.TYPE_ARGUMENT,
79 TokenTypes.LITERAL_NEW,
80 TokenTypes.DOT,
81 TokenTypes.ANNOTATION_FIELD_DEF,
82 TokenTypes.RECORD_DEF,
83 TokenTypes.COMPACT_CTOR_DEF,
84 };
85 }
86
87 @Override
88 public int[] getRequiredTokens() {
89 return CommonUtil.EMPTY_INT_ARRAY;
90 }
91
92 @Override
93 public void visitToken(DetailAST ast) {
94 DetailAST nodeWithAnnotations = ast;
95 if (ast.getType() == TokenTypes.TYPECAST) {
96 nodeWithAnnotations = ast.findFirstToken(TokenTypes.TYPE);
97 }
98 DetailAST modifiersNode = nodeWithAnnotations.findFirstToken(TokenTypes.MODIFIERS);
99 if (modifiersNode == null) {
100 modifiersNode = nodeWithAnnotations.findFirstToken(TokenTypes.ANNOTATIONS);
101 }
102 if (modifiersNode != null) {
103 for (DetailAST annotationNode = modifiersNode.getFirstChild();
104 annotationNode != null;
105 annotationNode = annotationNode.getNextSibling()) {
106 if (annotationNode.getType() == TokenTypes.ANNOTATION
107 && !TokenUtil.areOnSameLine(annotationNode,
108 modifiersNode.getNextSibling())) {
109 log(annotationNode, MSG_KEY_ANNOTATION_ON_SAME_LINE,
110 getAnnotationName(annotationNode));
111 }
112 }
113 }
114 }
115
116
117
118
119
120
121
122 private static String getAnnotationName(DetailAST annotation) {
123 DetailAST identNode = annotation.findFirstToken(TokenTypes.IDENT);
124 if (identNode == null) {
125 identNode = annotation.findFirstToken(TokenTypes.DOT).getLastChild();
126 }
127 return identNode.getText();
128 }
129
130 }