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 java.util.ArrayDeque;
23 import java.util.Collections;
24 import java.util.Deque;
25 import java.util.HashSet;
26 import java.util.Set;
27
28 import com.puppycrawl.tools.checkstyle.FileStatefulCheck;
29 import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
30 import com.puppycrawl.tools.checkstyle.api.DetailAST;
31 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
32 import com.puppycrawl.tools.checkstyle.utils.CheckUtil;
33 import com.puppycrawl.tools.checkstyle.utils.TokenUtil;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 @FileStatefulCheck
65 public final class ParameterAssignmentCheck extends AbstractCheck {
66
67
68
69
70
71 public static final String MSG_KEY = "parameter.assignment";
72
73
74 private final Deque<Set<String>> parameterNamesStack = new ArrayDeque<>();
75
76 private Set<String> parameterNames;
77
78 @Override
79 public int[] getDefaultTokens() {
80 return getRequiredTokens();
81 }
82
83 @Override
84 public int[] getRequiredTokens() {
85 return new int[] {
86 TokenTypes.CTOR_DEF,
87 TokenTypes.METHOD_DEF,
88 TokenTypes.ASSIGN,
89 TokenTypes.PLUS_ASSIGN,
90 TokenTypes.MINUS_ASSIGN,
91 TokenTypes.STAR_ASSIGN,
92 TokenTypes.DIV_ASSIGN,
93 TokenTypes.MOD_ASSIGN,
94 TokenTypes.SR_ASSIGN,
95 TokenTypes.BSR_ASSIGN,
96 TokenTypes.SL_ASSIGN,
97 TokenTypes.BAND_ASSIGN,
98 TokenTypes.BXOR_ASSIGN,
99 TokenTypes.BOR_ASSIGN,
100 TokenTypes.INC,
101 TokenTypes.POST_INC,
102 TokenTypes.DEC,
103 TokenTypes.POST_DEC,
104 TokenTypes.LAMBDA,
105 };
106 }
107
108 @Override
109 public int[] getAcceptableTokens() {
110 return getRequiredTokens();
111 }
112
113 @Override
114 public void beginTree(DetailAST rootAST) {
115
116 parameterNamesStack.clear();
117 parameterNames = Collections.emptySet();
118 }
119
120 @Override
121 public void visitToken(DetailAST ast) {
122 final int type = ast.getType();
123 if (TokenUtil.isOfType(type, TokenTypes.CTOR_DEF, TokenTypes.METHOD_DEF)) {
124 visitMethodDef(ast);
125 }
126 else if (type == TokenTypes.LAMBDA) {
127 if (ast.getParent().getType() != TokenTypes.SWITCH_RULE) {
128 visitLambda(ast);
129 }
130 }
131 else {
132 checkNestedIdent(ast);
133 }
134 }
135
136 @Override
137 public void leaveToken(DetailAST ast) {
138 final int type = ast.getType();
139 if (TokenUtil.isOfType(type, TokenTypes.CTOR_DEF, TokenTypes.METHOD_DEF)
140 || type == TokenTypes.LAMBDA
141 && ast.getParent().getType() != TokenTypes.SWITCH_RULE) {
142 parameterNames = parameterNamesStack.pop();
143 }
144 }
145
146
147
148
149
150
151 private void checkNestedIdent(DetailAST ast) {
152 final DetailAST identAST = ast.getFirstChild();
153
154 if (identAST != null
155 && identAST.getType() == TokenTypes.IDENT
156 && parameterNames.contains(identAST.getText())) {
157 log(ast, MSG_KEY, identAST.getText());
158 }
159 }
160
161
162
163
164
165
166 private void visitMethodDef(DetailAST ast) {
167 parameterNamesStack.push(parameterNames);
168 parameterNames = new HashSet<>();
169
170 visitMethodParameters(ast.findFirstToken(TokenTypes.PARAMETERS));
171 }
172
173
174
175
176
177
178 private void visitLambda(DetailAST lambdaAst) {
179 parameterNamesStack.push(parameterNames);
180 parameterNames = new HashSet<>();
181
182 DetailAST parameterAst = lambdaAst.findFirstToken(TokenTypes.PARAMETERS);
183 if (parameterAst == null) {
184 parameterAst = lambdaAst.getFirstChild();
185 }
186 visitLambdaParameters(parameterAst);
187 }
188
189
190
191
192
193
194 private void visitMethodParameters(DetailAST ast) {
195 visitParameters(ast);
196 }
197
198
199
200
201
202
203 private void visitLambdaParameters(DetailAST ast) {
204 if (ast.getType() == TokenTypes.IDENT) {
205 parameterNames.add(ast.getText());
206 }
207 else {
208 visitParameters(ast);
209 }
210 }
211
212
213
214
215
216
217 private void visitParameters(DetailAST parametersAst) {
218 DetailAST parameterDefAST =
219 parametersAst.findFirstToken(TokenTypes.PARAMETER_DEF);
220
221 while (parameterDefAST != null) {
222 if (!CheckUtil.isReceiverParameter(parameterDefAST)) {
223 final DetailAST param =
224 parameterDefAST.findFirstToken(TokenTypes.IDENT);
225 parameterNames.add(param.getText());
226 }
227 parameterDefAST = parameterDefAST.getNextSibling();
228 }
229 }
230
231 }