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.coding;
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.CheckUtil;
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 @StatelessCheck
47 public class MultipleVariableDeclarationsCheck extends AbstractCheck {
48
49
50
51
52
53 public static final String MSG_MULTIPLE = "multiple.variable.declarations";
54
55
56
57
58
59 public static final String MSG_MULTIPLE_COMMA = "multiple.variable.declarations.comma";
60
61 @Override
62 public int[] getAcceptableTokens() {
63 return getRequiredTokens();
64 }
65
66 @Override
67 public int[] getDefaultTokens() {
68 return getRequiredTokens();
69 }
70
71 @Override
72 public int[] getRequiredTokens() {
73 return new int[] {TokenTypes.VARIABLE_DEF};
74 }
75
76 @Override
77 public void visitToken(DetailAST ast) {
78 DetailAST nextNode = ast.getNextSibling();
79
80 if (nextNode != null) {
81 final boolean isCommaSeparated = nextNode.getType() == TokenTypes.COMMA;
82
83 if (isCommaSeparated
84 || nextNode.getType() == TokenTypes.SEMI) {
85 nextNode = nextNode.getNextSibling();
86 }
87
88 if (nextNode != null
89 && nextNode.getType() == TokenTypes.VARIABLE_DEF) {
90 final DetailAST firstNode = CheckUtil.getFirstNode(ast);
91 if (isCommaSeparated) {
92
93
94
95
96
97
98 if (ast.getParent().getType() != TokenTypes.FOR_INIT) {
99 log(firstNode, MSG_MULTIPLE_COMMA);
100 }
101 }
102 else {
103 final DetailAST lastNode = getLastNode(ast);
104 final DetailAST firstNextNode = CheckUtil.getFirstNode(nextNode);
105
106 if (firstNextNode.getLineNo() == lastNode.getLineNo()) {
107 log(firstNode, MSG_MULTIPLE);
108 }
109 }
110 }
111 }
112 }
113
114
115
116
117
118
119 private static DetailAST getLastNode(final DetailAST node) {
120 DetailAST currentNode = node;
121 DetailAST child = node.getFirstChild();
122 while (child != null) {
123 final DetailAST newNode = getLastNode(child);
124 if (newNode.getLineNo() > currentNode.getLineNo()
125 || newNode.getLineNo() == currentNode.getLineNo()
126 && newNode.getColumnNo() > currentNode.getColumnNo()) {
127 currentNode = newNode;
128 }
129 child = child.getNextSibling();
130 }
131
132 return currentNode;
133 }
134
135 }