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 static com.google.common.truth.Truth.assertWithMessage;
23 import static com.puppycrawl.tools.checkstyle.checks.coding.UnusedLocalVariableCheck.MSG_UNUSED_LOCAL_VARIABLE;
24 import static com.puppycrawl.tools.checkstyle.checks.coding.UnusedLocalVariableCheck.MSG_UNUSED_NAMED_LOCAL_VARIABLE;
25
26 import java.io.File;
27 import java.util.Collection;
28 import java.util.Map;
29 import java.util.Objects;
30 import java.util.Optional;
31 import java.util.function.Predicate;
32
33 import org.junit.jupiter.api.Test;
34
35 import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
36 import com.puppycrawl.tools.checkstyle.JavaParser;
37 import com.puppycrawl.tools.checkstyle.api.DetailAST;
38 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
39 import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
40 import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
41
42 public class UnusedLocalVariableCheckTest extends AbstractModuleTestSupport {
43
44 @Override
45 public String getPackageLocation() {
46 return "com/puppycrawl/tools/checkstyle/checks/coding/unusedlocalvariable";
47 }
48
49 @Test
50 public void testGetRequiredTokens() {
51 final UnusedLocalVariableCheck checkObj =
52 new UnusedLocalVariableCheck();
53 final int[] actual = checkObj.getRequiredTokens();
54 final int[] expected = {
55 TokenTypes.DOT,
56 TokenTypes.VARIABLE_DEF,
57 TokenTypes.IDENT,
58 TokenTypes.SLIST,
59 TokenTypes.LITERAL_FOR,
60 TokenTypes.OBJBLOCK,
61 TokenTypes.CLASS_DEF,
62 TokenTypes.INTERFACE_DEF,
63 TokenTypes.ANNOTATION_DEF,
64 TokenTypes.PACKAGE_DEF,
65 TokenTypes.LITERAL_NEW,
66 TokenTypes.METHOD_DEF,
67 TokenTypes.CTOR_DEF,
68 TokenTypes.STATIC_INIT,
69 TokenTypes.INSTANCE_INIT,
70 TokenTypes.COMPILATION_UNIT,
71 TokenTypes.LAMBDA,
72 TokenTypes.ENUM_DEF,
73 TokenTypes.RECORD_DEF,
74 TokenTypes.COMPACT_CTOR_DEF,
75 TokenTypes.PATTERN_VARIABLE_DEF,
76 };
77 assertWithMessage("Required tokens are invalid")
78 .that(actual)
79 .isEqualTo(expected);
80 }
81
82 @Test
83 public void testGetAcceptableTokens() {
84 final UnusedLocalVariableCheck typeParameterNameCheckObj =
85 new UnusedLocalVariableCheck();
86 final int[] actual = typeParameterNameCheckObj.getAcceptableTokens();
87 final int[] expected = {
88 TokenTypes.DOT,
89 TokenTypes.VARIABLE_DEF,
90 TokenTypes.IDENT,
91 TokenTypes.SLIST,
92 TokenTypes.LITERAL_FOR,
93 TokenTypes.OBJBLOCK,
94 TokenTypes.CLASS_DEF,
95 TokenTypes.INTERFACE_DEF,
96 TokenTypes.ANNOTATION_DEF,
97 TokenTypes.PACKAGE_DEF,
98 TokenTypes.LITERAL_NEW,
99 TokenTypes.METHOD_DEF,
100 TokenTypes.CTOR_DEF,
101 TokenTypes.STATIC_INIT,
102 TokenTypes.INSTANCE_INIT,
103 TokenTypes.COMPILATION_UNIT,
104 TokenTypes.LAMBDA,
105 TokenTypes.ENUM_DEF,
106 TokenTypes.RECORD_DEF,
107 TokenTypes.COMPACT_CTOR_DEF,
108 TokenTypes.PATTERN_VARIABLE_DEF,
109 };
110 assertWithMessage("Acceptable tokens are invalid")
111 .that(actual)
112 .isEqualTo(expected);
113 }
114
115 @Test
116 public void testUnusedLocalVariable() throws Exception {
117 final String[] expected = {
118 "28:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "sameName"),
119 "29:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "b"),
120 "32:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "testInLambdas"),
121 "34:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "coding"),
122 "35:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE,
123 "InputUnusedLocalVariable"),
124 "51:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "b"),
125 "55:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "c"),
126 "66:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "b"),
127 "68:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "c"),
128 "72:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "p"),
129 "82:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "f"),
130 "85:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "foo"),
131 "92:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
132 };
133 verifyWithInlineConfigParser(
134 getPath("InputUnusedLocalVariable.java"), expected);
135 }
136
137 @Test
138 public void testUnusedLocalVar2() throws Exception {
139 final String[] expected = {
140 "18:14: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "i"),
141 "20:14: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "j"),
142 "31:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
143 "32:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "b"),
144 "40:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "b"),
145 "41:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "Test"),
146 "42:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "obj"),
147 "62:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
148 "77:17: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "b"),
149 };
150 verifyWithInlineConfigParser(
151 getPath("InputUnusedLocalVariable2.java"),
152 expected);
153 }
154
155 @Test
156 public void testUnusedLocalVar3() throws Exception {
157 final String[] expected = {
158 "22:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
159 };
160 verifyWithInlineConfigParser(
161 getPath("InputUnusedLocalVariable3.java"),
162 expected);
163 }
164
165 @Test
166 public void testUnusedLocalVarInAnonInnerClasses() throws Exception {
167 final String[] expected = {
168 "15:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
169 "16:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "b"),
170 "18:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "obj"),
171 "23:17: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "obj"),
172 "33:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "obj2"),
173 "47:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "m"),
174 "48:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "l"),
175 "60:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "h"),
176 "63:17: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "v"),
177 "88:10: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "o"),
178 "97:18: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "o"),
179 "102:18: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "o"),
180 "106:17: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "o"),
181 };
182 verifyWithInlineConfigParser(
183 getPath("InputUnusedLocalVariableAnonInnerClasses.java"),
184 expected);
185 }
186
187 @Test
188 public void testUnusedLocalVarGenericAnonInnerClasses() throws Exception {
189 final String[] expected = {
190 "15:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "l"),
191 "16:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "obj"),
192 "35:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "l"),
193 "36:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "obj2"),
194 "49:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "s"),
195 "69:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "variable"),
196 "71:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "anotherVar"),
197 "80:47: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "obj2"),
198 };
199 verifyWithInlineConfigParser(
200 getPath("InputUnusedLocalVariableGenericAnonInnerClasses.java"),
201 expected);
202 }
203
204 @Test
205 public void testUnusedLocalVarDepthOfClasses() throws Exception {
206 final String[] expected = {
207 "29:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "r"),
208 "50:21: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
209 "65:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
210 "95:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "variable"),
211 };
212 verifyWithInlineConfigParser(
213 getPath("InputUnusedLocalVariableDepthOfClasses.java"),
214 expected);
215 }
216
217 @Test
218 public void testUnusedLocalVarNestedClasses() throws Exception {
219 final String[] expected = {
220 "22:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "V"),
221 "24:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "S"),
222 "25:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "Q"),
223 "37:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "variable"),
224 "45:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "anotherVariable"),
225 "68:21: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "s"),
226 "69:21: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "n"),
227 };
228 verifyWithInlineConfigParser(
229 getPath("InputUnusedLocalVariableNestedClasses.java"),
230 expected);
231 }
232
233 @Test
234 public void testUnusedLocalVarNestedClasses2() throws Exception {
235 final String[] expected = {
236 "30:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "q"),
237 "31:51: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "obj"),
238 "47:21: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "b"),
239 "58:21: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "b"),
240 "109:33: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "s"),
241 };
242 verifyWithInlineConfigParser(
243 getPath("InputUnusedLocalVariableNestedClasses2.java"),
244 expected);
245 }
246
247 @Test
248 public void testUnusedLocalVarNestedClasses3() throws Exception {
249 final String[] expected = {
250 "37:17: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "p2"),
251 "55:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "o"),
252 "94:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "b"),
253 "96:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
254 };
255
256 verifyWithInlineConfigParser(
257 getPath("InputUnusedLocalVariableNestedClasses3.java"),
258 expected);
259 }
260
261 @Test
262 public void testUnusedLocalVarNestedClasses4() throws Exception {
263 final String[] expected = {
264 "13:5: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
265 "14:5: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "ab"),
266 };
267
268 verifyWithInlineConfigParser(
269 getPath("InputUnusedLocalVariableNestedClasses4.java"),
270 expected);
271 }
272
273 @Test
274 public void testUnusedLocalVarNestedClasses5() throws Exception {
275 final String[] expected = {
276 "13:5: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
277 "14:5: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "ab"),
278 "20:11: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "abc"),
279 };
280
281 verifyWithInlineConfigParser(
282 getPath("InputUnusedLocalVariableNestedClasses5.java"),
283 expected);
284 }
285
286 @Test
287 public void testUnusedLocalVarNestedClasses6() throws Exception {
288 final String[] expected = {
289 "13:5: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
290 "14:5: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "ab"),
291 };
292
293 verifyWithInlineConfigParser(
294 getPath("InputUnusedLocalVariableNestedClasses6.java"),
295 expected);
296 }
297
298 @Test
299 public void testUnusedLocalVarNestedClasses7() throws Exception {
300 final String[] expected = {
301 "11:5: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
302 "12:5: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "ab"),
303 "17:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "ab"),
304 "24:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
305 "25:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "ab"),
306 "29:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
307 };
308
309 verifyWithInlineConfigParser(
310 getPath("InputUnusedLocalVariableNestedClasses7.java"),
311 expected);
312 }
313
314 @Test
315 public void testUnusedLocalVarTestWarningSeverity() throws Exception {
316 final String[] expected = {
317 "15:19: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "p2"),
318 };
319
320 verifyWithInlineConfigParser(
321 getPath("InputUnusedLocalVariableTestWarningSeverity.java"),
322 expected);
323 }
324
325 @Test
326 public void testUnusedLocalVarEnum() throws Exception {
327 final String[] expected = {
328 "23:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
329 "51:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
330 "78:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
331 "81:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "j"),
332 "93:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "d"),
333 };
334 verifyWithInlineConfigParser(
335 getPath("InputUnusedLocalVariableEnum.java"),
336 expected);
337 }
338
339 @Test
340 public void testUnusedLocalVarLambdas() throws Exception {
341 final String[] expected = {
342 "15:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "hoo"),
343 "20:17: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "j"),
344 "30:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "hoo2"),
345 "31:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "hoo3"),
346 "33:15: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "myComponent"),
347 "35:19: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "myComponent3"),
348 "41:25: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "j"),
349 "53:21: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "j"),
350 "66:17: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "ja"),
351 "74:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "k"),
352 };
353 verifyWithInlineConfigParser(
354 getPath("InputUnusedLocalVariableLambdaExpression.java"),
355 expected);
356 }
357
358 @Test
359 public void testUnusedLocalVariableLocalClasses() throws Exception {
360 final String[] expected = {
361 "15:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
362 "16:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "ab"),
363 };
364 verifyWithInlineConfigParser(
365 getPath("InputUnusedLocalVariableLocalClasses.java"),
366 expected);
367 }
368
369 @Test
370 public void testUnusedLocalVarRecords() throws Exception {
371 final String[] expected = {
372 "17:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "var1"),
373 "26:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "var1"),
374 "27:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "obj"),
375 "37:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "var2"),
376 };
377 verifyWithInlineConfigParser(
378 getPath("InputUnusedLocalVariableRecords.java"),
379 expected);
380 }
381
382 @Test
383 public void testUnusedLocalVarWithoutPackageStatement() throws Exception {
384 final String[] expected = {
385 "13:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
386 "25:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "var2"),
387 "46:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "var3"),
388 };
389 verifyWithInlineConfigParser(
390 getNonCompilablePath("InputUnusedLocalVariableNoPackageStatement.java"),
391 expected);
392 }
393
394 @Test
395 public void testCompactSourceFile() throws Exception {
396 final String[] expected = {
397 "13:5: " + getCheckMessage(MSG_UNUSED_NAMED_LOCAL_VARIABLE, "unused"),
398 };
399 verifyWithInlineConfigParser(
400 getNonCompilablePath("InputUnusedLocalVariableCompactSourceFile.java"),
401 expected);
402 }
403
404 @Test
405 public void testUnusedLocalVariableTernaryAndExpressions() throws Exception {
406 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
407 verifyWithInlineConfigParser(
408 getPath("InputUnusedLocalVariableTernaryAndExpressions.java"),
409 expected);
410 }
411
412 @Test
413 public void testUnusedLocalVariableSwitchStatement() throws Exception {
414 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
415 verifyWithInlineConfigParser(
416 getPath("InputUnusedLocalVariableSwitchStatement.java"),
417 expected);
418 }
419
420 @Test
421 public void testUnusedLocalVariableSwitchStatement2() throws Exception {
422 final String[] expected = {
423 "61:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "j"),
424 };
425 verifyWithInlineConfigParser(
426 getPath("InputUnusedLocalVariableSwitchStatement2.java"),
427 expected);
428 }
429
430 @Test
431 public void testUnusedLocalVariableSwitchExpression() throws Exception {
432 final String[] expected = {
433 "17:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "line2"),
434 };
435 verifyWithInlineConfigParser(
436 getPath("InputUnusedLocalVariableSwitchExpression.java"),
437 expected);
438 }
439
440 @Test
441 public void testUnusedLocalVariableWithAllowUnnamed() throws Exception {
442 final String[] expected = {
443 "22:13: " + getCheckMessage(MSG_UNUSED_NAMED_LOCAL_VARIABLE, "_x"),
444 "23:13: " + getCheckMessage(MSG_UNUSED_NAMED_LOCAL_VARIABLE, "__"),
445 "37:14: " + getCheckMessage(MSG_UNUSED_NAMED_LOCAL_VARIABLE, "__"),
446 "47:14: " + getCheckMessage(MSG_UNUSED_NAMED_LOCAL_VARIABLE, "__"),
447 };
448 verifyWithInlineConfigParser(
449 getNonCompilablePath("InputUnusedLocalVariableWithAllowUnnamed.java"),
450 expected);
451 }
452
453 @Test
454 public void testUnusedLocalVariableWithAllowUnnamedFalse() throws Exception {
455 final String[] expected = {
456 "21:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "_x"),
457 "22:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "__"),
458 "23:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "_"),
459 "33:14: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "_"),
460 "36:14: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "__"),
461 "44:14: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "_"),
462 "47:14: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "__"),
463 };
464 verifyWithInlineConfigParser(
465 getNonCompilablePath("InputUnusedLocalVariableWithAllowUnnamedFalse.java"),
466 expected);
467 }
468
469 @Test
470 public void testUnusedLocalVariablePatternVariablesCondition() throws Exception {
471 final String[] expected = {
472 "20:37: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "redBall"),
473 "22:46: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "greenBall"),
474 "41:39: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "redBall"),
475 "55:42: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "redBall"),
476 "61:40: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "redBall"),
477 "63:49: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "greenBall"),
478 "81:30: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "lr"),
479 };
480 verifyWithInlineConfigParser(
481 getNonCompilablePath("InputUnusedLocalVariablePatternVariablesCondition.java"),
482 expected);
483 }
484
485 @Test
486 public void testUnusedLocalVariablePatternVariablesCondition2() throws Exception {
487 final String[] expected = {
488 "24:68: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "lr"),
489 "44:33: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "s"),
490 "59:34: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "s1"),
491 "80:14: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "id"),
492 "89:14: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "_"),
493 };
494 verifyWithInlineConfigParser(
495 getNonCompilablePath("InputUnusedLocalVariablePatternVariablesCondition2.java"),
496 expected);
497 }
498
499 @Test
500 public void testUnusedLocalVariableNamedPatternVariable() throws Exception {
501 final String[] expected = {
502 "21:25: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "ignored"),
503 "22:26: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "ignored2"),
504 "28:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "x"),
505 "29:38: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "ignored"),
506 "36:30: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "y"),
507 "36:37: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "z"),
508 "42:57: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "ignoredAge"),
509 "58:43: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "inner"),
510 };
511 verifyWithInlineConfigParser(
512 getPath("InputUnusedLocalVariableAllowNamedPatternVariables.java"),
513 expected);
514 }
515
516 @Test
517 public void testUnusedLocalVariableNamedPatternVariableTrue() throws Exception {
518 final String[] expected = {
519 "21:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "x"),
520 "22:38: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "ignored"),
521 "30:46: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "s"),
522 };
523 verifyWithInlineConfigParser(
524 getPath("InputUnusedLocalVariableAllowNamedPatternVariablesTrue.java"),
525 expected);
526 }
527
528 @Test
529 public void testUnusedLocalVariableNamedPatternVariableInstanceof() throws Exception {
530 final String[] expected = {
531 "21:38: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "s"),
532 };
533 verifyWithInlineConfigParser(
534 getPath("InputUnusedLocalVariableAllowNamedPatternVariablesInstanceOf.java"),
535 expected);
536 }
537
538 @Test
539 public void testUnusedLocalVariableNamedPatternVariableLegacyJdkFormat() throws Exception {
540 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
541 verifyWithInlineConfigParser(
542 getPath("InputUnusedLocalVariableJdkVersionLegacyFormat.java"),
543 expected);
544 }
545
546 @Test
547 public void testClearStateVariables() throws Exception {
548 final UnusedLocalVariableCheck check = new UnusedLocalVariableCheck();
549 final Optional<DetailAST> methodDef = TestUtil.findTokenInAstByPredicate(
550 JavaParser.parseFile(
551 new File(getPath("InputUnusedLocalVariable.java")),
552 JavaParser.Options.WITHOUT_COMMENTS),
553 ast -> ast.getType() == TokenTypes.METHOD_DEF);
554 assertWithMessage("Ast should contain METHOD_DEF")
555 .that(methodDef.isPresent())
556 .isTrue();
557 final DetailAST variableDef = methodDef.orElseThrow().getLastChild()
558 .findFirstToken(TokenTypes.VARIABLE_DEF);
559 assertWithMessage("State is not cleared on beginTree")
560 .that(TestUtil.isStatefulFieldClearedDuringBeginTree(check, variableDef,
561 "variables",
562 variables -> {
563 return ((Collection<?>) variables).isEmpty();
564 }))
565 .isTrue();
566 }
567
568 @Test
569 public void testClearStateClasses() throws Exception {
570 final UnusedLocalVariableCheck check = new UnusedLocalVariableCheck();
571 final Optional<DetailAST> classDef = TestUtil.findTokenInAstByPredicate(
572 JavaParser.parseFile(
573 new File(getPath("InputUnusedLocalVariable.java")),
574 JavaParser.Options.WITHOUT_COMMENTS),
575 ast -> ast.getType() == TokenTypes.CLASS_DEF);
576 assertWithMessage("Ast should contain CLASS_DEF")
577 .that(classDef.isPresent())
578 .isTrue();
579 final DetailAST classDefToken = classDef.orElseThrow();
580 assertWithMessage("State is not cleared on beginTree")
581 .that(TestUtil.isStatefulFieldClearedDuringBeginTree(check, classDefToken,
582 "typeDeclarations",
583 typeDeclarations -> {
584 return ((Collection<?>) typeDeclarations).isEmpty();
585 }))
586 .isTrue();
587 assertWithMessage("State is not cleared on beginTree")
588 .that(TestUtil.isStatefulFieldClearedDuringBeginTree(check, classDefToken,
589 "typeDeclAstToTypeDeclDesc",
590 typeDeclAstToTypeDeclDesc -> {
591 return ((Map<?, ?>) typeDeclAstToTypeDeclDesc).isEmpty();
592 }))
593 .isTrue();
594 assertWithMessage("State is not cleared on beginTree")
595 .that(TestUtil.isStatefulFieldClearedDuringBeginTree(check, classDefToken,
596 "depth",
597 depth -> {
598 return (int) depth == 0;
599 }))
600 .isTrue();
601 }
602
603 @Test
604 public void testClearStateAnonInnerClass() throws Exception {
605 final UnusedLocalVariableCheck check = new UnusedLocalVariableCheck();
606 final DetailAST root = JavaParser.parseFile(
607 new File(getPath("InputUnusedLocalVariableAnonInnerClasses.java")),
608 JavaParser.Options.WITHOUT_COMMENTS);
609
610
611 final DetailAST classDefAst = root.findFirstToken(TokenTypes.CLASS_DEF);
612 final Optional<DetailAST> literalNew = TestUtil.findTokenInAstByPredicate(root,
613 ast -> ast.getType() == TokenTypes.LITERAL_NEW);
614 assertWithMessage("Ast should contain LITERAL_NEW")
615 .that(literalNew.isPresent())
616 .isTrue();
617 check.beginTree(root);
618 check.visitToken(classDefAst);
619 check.visitToken(literalNew.orElseThrow());
620 check.beginTree(null);
621 final Predicate<Object> isClear = anonInnerAstToTypeDesc -> {
622 return ((Map<?, ?>) anonInnerAstToTypeDesc).isEmpty();
623 };
624 assertWithMessage("State is not cleared on beginTree")
625 .that(isClear.test(TestUtil.getInternalState(
626 check, "anonInnerAstToTypeDeclDesc", Object.class)))
627 .isTrue();
628 final Predicate<Object> isQueueClear = anonInnerClassHolders -> {
629 return ((Collection<?>) anonInnerClassHolders).isEmpty();
630 };
631 assertWithMessage("State is not cleared on beginTree")
632 .that(isQueueClear.test(TestUtil.getInternalState(
633 check, "anonInnerClassHolders", Object.class)))
634 .isTrue();
635 }
636
637 @Test
638 public void testClearStatePackageDef() throws Exception {
639 final UnusedLocalVariableCheck check = new UnusedLocalVariableCheck();
640 final Optional<DetailAST> packageDef = TestUtil.findTokenInAstByPredicate(
641 JavaParser.parseFile(
642 new File(getPath("InputUnusedLocalVariable.java")),
643 JavaParser.Options.WITHOUT_COMMENTS),
644 ast -> ast.getType() == TokenTypes.PACKAGE_DEF);
645 assertWithMessage("Ast should contain PACKAGE_DEF")
646 .that(packageDef.isPresent())
647 .isTrue();
648 final DetailAST packageDefToken = packageDef.orElseThrow();
649 assertWithMessage("State is not cleared on beginTree")
650 .that(TestUtil.isStatefulFieldClearedDuringBeginTree(check, packageDefToken,
651 "packageName",
652 Objects::isNull))
653 .isTrue();
654 }
655
656 @Test
657 public void testUnusedLocalVarInAnonInnerClasses2() throws Exception {
658 final String[] expected = {
659 "21:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "s"),
660 };
661 verifyWithInlineConfigParser(
662 getPath("InputUnusedLocalVariableAnonInnerClasses2.java"),
663 expected);
664 }
665
666 @Test
667 public void testUnusedLocalVarInAnonInnerClasses3() throws Exception {
668 final String[] expected = {
669 "14:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
670 "21:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "obj"),
671 "33:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "s"),
672 };
673 verifyWithInlineConfigParser(
674 getPath("InputUnusedLocalVariableAnonInnerClasses3.java"),
675 expected);
676 }
677
678 @Test
679 public void testUnusedLocalVariablePatternVariables() throws Exception {
680 final String[] expected = {
681 "19:25: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "c"),
682 "20:28: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "r"),
683 "43:29: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "c"),
684 "44:32: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "r"),
685 };
686 verifyWithInlineConfigParser(
687 getNonCompilablePath(
688 "InputUnusedLocalVariablePatternVariables.java"),
689 expected);
690 }
691
692 @Test
693 public void testUnusedLocalVariablePatternVariables2() throws Exception {
694 final String[] expected = {
695 "14:26: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "i"),
696 "28:25: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "s"),
697 "47:35: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "s"),
698 };
699 verifyWithInlineConfigParser(
700 getPath(
701 "InputUnusedLocalVariablePatternVariables2.java"),
702 expected);
703 }
704
705 @Test
706 public void testUnusedLocalVariablePatternVariablesAllowUnnamed() throws Exception {
707 final String[] expected = {
708 "19:28: " + getCheckMessage(MSG_UNUSED_NAMED_LOCAL_VARIABLE, "c"),
709 "20:28: " + getCheckMessage(MSG_UNUSED_NAMED_LOCAL_VARIABLE, "r"),
710 "30:32: " + getCheckMessage(MSG_UNUSED_NAMED_LOCAL_VARIABLE, "c"),
711 "31:32: " + getCheckMessage(MSG_UNUSED_NAMED_LOCAL_VARIABLE, "r"),
712 "46:35: " + getCheckMessage(MSG_UNUSED_NAMED_LOCAL_VARIABLE, "s"),
713 "57:14: " + getCheckMessage(MSG_UNUSED_NAMED_LOCAL_VARIABLE, "id"),
714 };
715 verifyWithInlineConfigParser(
716 getNonCompilablePath(
717 "InputUnusedLocalVariablePatternVariablesAllowUnnamed.java"),
718 expected);
719 }
720
721 @Test
722 public void testUnusedLocalVariablePatternVariablesUnnamedTry() throws Exception {
723 final String[] expected = {
724 "28:17: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "_"),
725 };
726 verifyWithInlineConfigParser(
727 getNonCompilablePath(
728 "InputUnusedLocalVariableUnnamedTryCatch.java"),
729 expected);
730 }
731
732 @Test
733 public void testUnusedLocalVariablePatternVariablesAllowUnnamedTry() throws Exception {
734 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
735 verifyWithInlineConfigParser(
736 getNonCompilablePath(
737 "InputUnusedLocalVariableAllowUnnamedTryCatch.java"),
738 expected);
739 }
740
741
742
743
744
745
746 @Test
747 public void testIsInsideLocalAnonInnerClass() throws Exception {
748 final DetailAST root = JavaParser.parseFile(
749 new File(getPath("InputUnusedLocalVariableLambdaAnonInner.java")),
750 JavaParser.Options.WITHOUT_COMMENTS);
751
752 final DetailAST fieldObj = TestUtil.findTokenInAstByPredicate(root,
753 ast -> {
754 return ast.getType() == TokenTypes.VARIABLE_DEF
755 && "fieldObj".equals(ast.findFirstToken(TokenTypes.IDENT)
756 .getText());
757 })
758 .orElseThrow();
759 final DetailAST literalNewField = fieldObj.findFirstToken(TokenTypes.ASSIGN)
760 .findFirstToken(TokenTypes.EXPR)
761 .findFirstToken(TokenTypes.LITERAL_NEW);
762
763 final boolean resultFalse = TestUtil.invokeStaticMethod(
764 UnusedLocalVariableCheck.class,
765 "isInsideLocalAnonInnerClass",
766 Boolean.class,
767 literalNewField);
768
769 assertWithMessage("Should be false for field initialization (no SLIST in ancestry)")
770 .that(resultFalse)
771 .isFalse();
772
773 final DetailAST localObj = TestUtil.findTokenInAstByPredicate(root,
774 ast -> {
775 return ast.getType() == TokenTypes.VARIABLE_DEF
776 && "localObj".equals(ast.findFirstToken(TokenTypes.IDENT)
777 .getText());
778 })
779 .orElseThrow();
780 final DetailAST literalNewLocal = localObj.findFirstToken(TokenTypes.ASSIGN)
781 .findFirstToken(TokenTypes.EXPR)
782 .findFirstToken(TokenTypes.LITERAL_NEW);
783
784 final boolean resultTrue = TestUtil.invokeStaticMethod(
785 UnusedLocalVariableCheck.class,
786 "isInsideLocalAnonInnerClass",
787 Boolean.class,
788 literalNewLocal);
789
790 assertWithMessage("Should be true for local variable initialization")
791 .that(resultTrue)
792 .isTrue();
793 }
794
795 }