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 "27:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "sameName"),
119 "28:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "b"),
120 "31:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "testInLambdas"),
121 "33:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "coding"),
122 "34:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE,
123 "InputUnusedLocalVariable"),
124 "50:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "b"),
125 "54:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "c"),
126 "65:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "b"),
127 "67:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "c"),
128 "71:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "p"),
129 "81:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "f"),
130 "84:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "foo"),
131 "91: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 "17:14: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "i"),
141 "19:14: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "j"),
142 "30:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
143 "31:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "b"),
144 "39:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "b"),
145 "40:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "Test"),
146 "41:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "obj"),
147 "61:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
148 "76: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 "21: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 "14:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
169 "15:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "b"),
170 "17:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "obj"),
171 "22:17: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "obj"),
172 "32:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "obj2"),
173 "46:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "m"),
174 "47:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "l"),
175 "59:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "h"),
176 "62:17: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "v"),
177 };
178 verifyWithInlineConfigParser(
179 getPath("InputUnusedLocalVariableAnonInnerClasses.java"),
180 expected);
181 }
182
183 @Test
184 public void testUnusedLocalVarGenericAnonInnerClasses() throws Exception {
185 final String[] expected = {
186 "13:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "l"),
187 "14:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "obj"),
188 "33:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "l"),
189 "34:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "obj2"),
190 "47:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "s"),
191 "67:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "variable"),
192 "69:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "anotherVar"),
193 "78:47: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "obj2"),
194 };
195 verifyWithInlineConfigParser(
196 getPath("InputUnusedLocalVariableGenericAnonInnerClasses.java"),
197 expected);
198 }
199
200 @Test
201 public void testUnusedLocalVarDepthOfClasses() throws Exception {
202 final String[] expected = {
203 "28:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "r"),
204 "49:21: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
205 "64:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
206 "94:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "variable"),
207 };
208 verifyWithInlineConfigParser(
209 getPath("InputUnusedLocalVariableDepthOfClasses.java"),
210 expected);
211 }
212
213 @Test
214 public void testUnusedLocalVarNestedClasses() throws Exception {
215 final String[] expected = {
216 "21:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "V"),
217 "23:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "S"),
218 "24:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "Q"),
219 "36:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "variable"),
220 "44:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "anotherVariable"),
221 "67:21: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "s"),
222 "68:21: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "n"),
223 };
224 verifyWithInlineConfigParser(
225 getPath("InputUnusedLocalVariableNestedClasses.java"),
226 expected);
227 }
228
229 @Test
230 public void testUnusedLocalVarNestedClasses2() throws Exception {
231 final String[] expected = {
232 "29:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "q"),
233 "30:51: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "obj"),
234 "46:21: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "b"),
235 "57:21: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "b"),
236 "108:33: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "s"),
237 };
238 verifyWithInlineConfigParser(
239 getPath("InputUnusedLocalVariableNestedClasses2.java"),
240 expected);
241 }
242
243 @Test
244 public void testUnusedLocalVarNestedClasses3() throws Exception {
245 final String[] expected = {
246 "36:17: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "p2"),
247 "54:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "o"),
248 "93:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "b"),
249 "95:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
250 };
251
252 verifyWithInlineConfigParser(
253 getPath("InputUnusedLocalVariableNestedClasses3.java"),
254 expected);
255 }
256
257 @Test
258 public void testUnusedLocalVarNestedClasses4() throws Exception {
259 final String[] expected = {
260 "12:5: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
261 "13:5: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "ab"),
262 };
263
264 verifyWithInlineConfigParser(
265 getPath("InputUnusedLocalVariableNestedClasses4.java"),
266 expected);
267 }
268
269 @Test
270 public void testUnusedLocalVarNestedClasses5() throws Exception {
271 final String[] expected = {
272 "12:5: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
273 "13:5: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "ab"),
274 "19:11: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "abc"),
275 };
276
277 verifyWithInlineConfigParser(
278 getPath("InputUnusedLocalVariableNestedClasses5.java"),
279 expected);
280 }
281
282 @Test
283 public void testUnusedLocalVarNestedClasses6() throws Exception {
284 final String[] expected = {
285 "12:5: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
286 "13:5: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "ab"),
287 };
288
289 verifyWithInlineConfigParser(
290 getPath("InputUnusedLocalVariableNestedClasses6.java"),
291 expected);
292 }
293
294 @Test
295 public void testUnusedLocalVarNestedClasses7() throws Exception {
296 final String[] expected = {
297 "10:5: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
298 "11:5: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "ab"),
299 "16:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "ab"),
300 "23:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
301 "24:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "ab"),
302 "28:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
303 };
304
305 verifyWithInlineConfigParser(
306 getPath("InputUnusedLocalVariableNestedClasses7.java"),
307 expected);
308 }
309
310 @Test
311 public void testUnusedLocalVarTestWarningSeverity() throws Exception {
312 final String[] expected = {
313 "14:19: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "p2"),
314 };
315
316 verifyWithInlineConfigParser(
317 getPath("InputUnusedLocalVariableTestWarningSeverity.java"),
318 expected);
319 }
320
321 @Test
322 public void testUnusedLocalVarEnum() throws Exception {
323 final String[] expected = {
324 "22:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
325 "50:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
326 "77:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
327 "80:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "j"),
328 "92:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "d"),
329 };
330 verifyWithInlineConfigParser(
331 getPath("InputUnusedLocalVariableEnum.java"),
332 expected);
333 }
334
335 @Test
336 public void testUnusedLocalVarLambdas() throws Exception {
337 final String[] expected = {
338 "14:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "hoo"),
339 "19:17: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "j"),
340 "29:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "hoo2"),
341 "30:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "hoo3"),
342 "32:15: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "myComponent"),
343 "34:19: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "myComponent3"),
344 "40:25: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "j"),
345 "52:21: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "j"),
346 "65:17: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "ja"),
347 "73:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "k"),
348 };
349 verifyWithInlineConfigParser(
350 getPath("InputUnusedLocalVariableLambdaExpression.java"),
351 expected);
352 }
353
354 @Test
355 public void testUnusedLocalVariableLocalClasses() throws Exception {
356 final String[] expected = {
357 "14:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
358 "15:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "ab"),
359 };
360 verifyWithInlineConfigParser(
361 getPath("InputUnusedLocalVariableLocalClasses.java"),
362 expected);
363 }
364
365 @Test
366 public void testUnusedLocalVarRecords() throws Exception {
367 final String[] expected = {
368 "16:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "var1"),
369 "25:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "var1"),
370 "26:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "obj"),
371 "36:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "var2"),
372 };
373 verifyWithInlineConfigParser(
374 getPath("InputUnusedLocalVariableRecords.java"),
375 expected);
376 }
377
378 @Test
379 public void testUnusedLocalVarWithoutPackageStatement() throws Exception {
380 final String[] expected = {
381 "12:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
382 "24:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "var2"),
383 "45:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "var3"),
384 };
385 verifyWithInlineConfigParser(
386 getNonCompilablePath("InputUnusedLocalVariableWithoutPackageStatement.java"),
387 expected);
388 }
389
390 @Test
391 public void testCompactSourceFile() throws Exception {
392 final String[] expected = {
393 "12:5: " + getCheckMessage(MSG_UNUSED_NAMED_LOCAL_VARIABLE, "unused"),
394 };
395 verifyWithInlineConfigParser(
396 getNonCompilablePath("InputUnusedLocalVariableCompactSourceFile.java"),
397 expected);
398 }
399
400 @Test
401 public void testUnusedLocalVariableTernaryAndExpressions() throws Exception {
402 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
403 verifyWithInlineConfigParser(
404 getPath("InputUnusedLocalVariableTernaryAndExpressions.java"),
405 expected);
406 }
407
408 @Test
409 public void testUnusedLocalVariableSwitchStatement() throws Exception {
410 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
411 verifyWithInlineConfigParser(
412 getPath("InputUnusedLocalVariableSwitchStatement.java"),
413 expected);
414 }
415
416 @Test
417 public void testUnusedLocalVariableSwitchStatement2() throws Exception {
418 final String[] expected = {
419 "59:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "j"),
420 };
421 verifyWithInlineConfigParser(
422 getPath("InputUnusedLocalVariableSwitchStatement2.java"),
423 expected);
424 }
425
426 @Test
427 public void testUnusedLocalVariableSwitchExpression() throws Exception {
428 final String[] expected = {
429 "16:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "line2"),
430 };
431 verifyWithInlineConfigParser(
432 getPath("InputUnusedLocalVariableSwitchExpression.java"),
433 expected);
434 }
435
436 @Test
437 public void testUnusedLocalVariableWithAllowUnnamed() throws Exception {
438 final String[] expected = {
439 "20:13: " + getCheckMessage(MSG_UNUSED_NAMED_LOCAL_VARIABLE, "_x"),
440 "21:13: " + getCheckMessage(MSG_UNUSED_NAMED_LOCAL_VARIABLE, "__"),
441 "35:14: " + getCheckMessage(MSG_UNUSED_NAMED_LOCAL_VARIABLE, "__"),
442 "45:14: " + getCheckMessage(MSG_UNUSED_NAMED_LOCAL_VARIABLE, "__"),
443 };
444 verifyWithInlineConfigParser(
445 getNonCompilablePath("InputUnusedLocalVariableWithAllowUnnamed.java"),
446 expected);
447 }
448
449 @Test
450 public void testUnusedLocalVariableWithAllowUnnamedFalse() throws Exception {
451 final String[] expected = {
452 "20:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "_x"),
453 "21:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "__"),
454 "22:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "_"),
455 "32:14: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "_"),
456 "35:14: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "__"),
457 "43:14: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "_"),
458 "46:14: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "__"),
459 };
460 verifyWithInlineConfigParser(
461 getNonCompilablePath("InputUnusedLocalVariableWithAllowUnnamedFalse.java"),
462 expected);
463 }
464
465 @Test
466 public void testUnusedLocalVariablePatternVariablesCondition() throws Exception {
467 final String[] expected = {
468 "19:37: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "redBall"),
469 "21:46: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "greenBall"),
470 "40:39: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "redBall"),
471 "54:42: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "redBall"),
472 "60:40: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "redBall"),
473 "62:49: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "greenBall"),
474 "80:30: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "lr"),
475 };
476 verifyWithInlineConfigParser(
477 getPath("InputUnusedLocalVariablePatternVariablesCondition.java"),
478 expected);
479 }
480
481 @Test
482 public void testUnusedLocalVariablePatternVariablesCondition2() throws Exception {
483 final String[] expected = {
484 "23:68: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "lr"),
485 "43:33: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "s"),
486 "58:34: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "s1"),
487 };
488 verifyWithInlineConfigParser(
489 getPath("InputUnusedLocalVariablePatternVariablesCondition2.java"),
490 expected);
491 }
492
493 @Test
494 public void testClearStateVariables() throws Exception {
495 final UnusedLocalVariableCheck check = new UnusedLocalVariableCheck();
496 final Optional<DetailAST> methodDef = TestUtil.findTokenInAstByPredicate(
497 JavaParser.parseFile(
498 new File(getPath("InputUnusedLocalVariable.java")),
499 JavaParser.Options.WITHOUT_COMMENTS),
500 ast -> ast.getType() == TokenTypes.METHOD_DEF);
501 assertWithMessage("Ast should contain METHOD_DEF")
502 .that(methodDef.isPresent())
503 .isTrue();
504 final DetailAST variableDef = methodDef.orElseThrow().getLastChild()
505 .findFirstToken(TokenTypes.VARIABLE_DEF);
506 assertWithMessage("State is not cleared on beginTree")
507 .that(TestUtil.isStatefulFieldClearedDuringBeginTree(check, variableDef,
508 "variables",
509 variables -> {
510 return ((Collection<?>) variables).isEmpty();
511 }))
512 .isTrue();
513 }
514
515 @Test
516 public void testClearStateClasses() throws Exception {
517 final UnusedLocalVariableCheck check = new UnusedLocalVariableCheck();
518 final Optional<DetailAST> classDef = TestUtil.findTokenInAstByPredicate(
519 JavaParser.parseFile(
520 new File(getPath("InputUnusedLocalVariable.java")),
521 JavaParser.Options.WITHOUT_COMMENTS),
522 ast -> ast.getType() == TokenTypes.CLASS_DEF);
523 assertWithMessage("Ast should contain CLASS_DEF")
524 .that(classDef.isPresent())
525 .isTrue();
526 final DetailAST classDefToken = classDef.orElseThrow();
527 assertWithMessage("State is not cleared on beginTree")
528 .that(TestUtil.isStatefulFieldClearedDuringBeginTree(check, classDefToken,
529 "typeDeclarations",
530 typeDeclarations -> {
531 return ((Collection<?>) typeDeclarations).isEmpty();
532 }))
533 .isTrue();
534 assertWithMessage("State is not cleared on beginTree")
535 .that(TestUtil.isStatefulFieldClearedDuringBeginTree(check, classDefToken,
536 "typeDeclAstToTypeDeclDesc",
537 typeDeclAstToTypeDeclDesc -> {
538 return ((Map<?, ?>) typeDeclAstToTypeDeclDesc).isEmpty();
539 }))
540 .isTrue();
541 assertWithMessage("State is not cleared on beginTree")
542 .that(TestUtil.isStatefulFieldClearedDuringBeginTree(check, classDefToken,
543 "depth",
544 depth -> {
545 return (int) depth == 0;
546 }))
547 .isTrue();
548 }
549
550 @Test
551 public void testClearStateAnonInnerClass() throws Exception {
552 final UnusedLocalVariableCheck check = new UnusedLocalVariableCheck();
553 final DetailAST root = JavaParser.parseFile(
554 new File(getPath("InputUnusedLocalVariableAnonInnerClasses.java")),
555 JavaParser.Options.WITHOUT_COMMENTS);
556
557
558 final DetailAST classDefAst = root.findFirstToken(TokenTypes.CLASS_DEF);
559 final Optional<DetailAST> literalNew = TestUtil.findTokenInAstByPredicate(root,
560 ast -> ast.getType() == TokenTypes.LITERAL_NEW);
561 assertWithMessage("Ast should contain LITERAL_NEW")
562 .that(literalNew.isPresent())
563 .isTrue();
564 check.beginTree(root);
565 check.visitToken(classDefAst);
566 check.visitToken(literalNew.orElseThrow());
567 check.beginTree(null);
568 final Predicate<Object> isClear = anonInnerAstToTypeDesc -> {
569 return ((Map<?, ?>) anonInnerAstToTypeDesc).isEmpty();
570 };
571 assertWithMessage("State is not cleared on beginTree")
572 .that(isClear.test(TestUtil.getInternalState(
573 check, "anonInnerAstToTypeDeclDesc", Object.class)))
574 .isTrue();
575 final Predicate<Object> isQueueClear = anonInnerClassHolders -> {
576 return ((Collection<?>) anonInnerClassHolders).isEmpty();
577 };
578 assertWithMessage("State is not cleared on beginTree")
579 .that(isQueueClear.test(TestUtil.getInternalState(
580 check, "anonInnerClassHolders", Object.class)))
581 .isTrue();
582 }
583
584 @Test
585 public void testClearStatePackageDef() throws Exception {
586 final UnusedLocalVariableCheck check = new UnusedLocalVariableCheck();
587 final Optional<DetailAST> packageDef = TestUtil.findTokenInAstByPredicate(
588 JavaParser.parseFile(
589 new File(getPath("InputUnusedLocalVariable.java")),
590 JavaParser.Options.WITHOUT_COMMENTS),
591 ast -> ast.getType() == TokenTypes.PACKAGE_DEF);
592 assertWithMessage("Ast should contain PACKAGE_DEF")
593 .that(packageDef.isPresent())
594 .isTrue();
595 final DetailAST packageDefToken = packageDef.orElseThrow();
596 assertWithMessage("State is not cleared on beginTree")
597 .that(TestUtil.isStatefulFieldClearedDuringBeginTree(check, packageDefToken,
598 "packageName",
599 Objects::isNull))
600 .isTrue();
601 }
602
603 @Test
604 public void testUnusedLocalVarInAnonInnerClasses2() throws Exception {
605 final String[] expected = {
606 "20:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "s"),
607 };
608 verifyWithInlineConfigParser(
609 getPath("InputUnusedLocalVariableAnonInnerClasses2.java"),
610 expected);
611 }
612
613 @Test
614 public void testUnusedLocalVarInAnonInnerClasses3() throws Exception {
615 final String[] expected = {
616 "13:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "a"),
617 "20:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "obj"),
618 "32:13: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "s"),
619 };
620 verifyWithInlineConfigParser(
621 getPath("InputUnusedLocalVariableAnonInnerClasses3.java"),
622 expected);
623 }
624
625 @Test
626 public void testUnusedLocalVariablePatternVariables() throws Exception {
627 final String[] expected = {
628 "18:25: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "c"),
629 "19:28: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "r"),
630 "42:29: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "c"),
631 "43:32: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "r"),
632 };
633 verifyWithInlineConfigParser(
634 getPath(
635 "InputUnusedLocalVariablePatternVariables.java"),
636 expected);
637 }
638
639 @Test
640 public void testUnusedLocalVariablePatternVariables2() throws Exception {
641 final String[] expected = {
642 "13:26: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "i"),
643 "27:25: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "s"),
644 "46:35: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "s"),
645 };
646 verifyWithInlineConfigParser(
647 getPath(
648 "InputUnusedLocalVariablePatternVariables2.java"),
649 expected);
650 }
651
652 @Test
653 public void testUnusedLocalVariablePatternVariablesAllowUnnamed() throws Exception {
654 final String[] expected = {
655 "18:28: " + getCheckMessage(MSG_UNUSED_NAMED_LOCAL_VARIABLE, "c"),
656 "19:28: " + getCheckMessage(MSG_UNUSED_NAMED_LOCAL_VARIABLE, "r"),
657 "29:32: " + getCheckMessage(MSG_UNUSED_NAMED_LOCAL_VARIABLE, "c"),
658 "30:32: " + getCheckMessage(MSG_UNUSED_NAMED_LOCAL_VARIABLE, "r"),
659 "45:35: " + getCheckMessage(MSG_UNUSED_NAMED_LOCAL_VARIABLE, "s"),
660 };
661 verifyWithInlineConfigParser(
662 getPath(
663 "InputUnusedLocalVariablePatternVariablesAllowUnnamed.java"),
664 expected);
665 }
666
667
668
669
670
671
672 @Test
673 public void testIsInsideLocalAnonInnerClass() throws Exception {
674 final DetailAST root = JavaParser.parseFile(
675 new File(getPath("InputUnusedLocalVariableLambdaAnonInner.java")),
676 JavaParser.Options.WITHOUT_COMMENTS);
677
678 final DetailAST fieldObj = TestUtil.findTokenInAstByPredicate(root,
679 ast -> {
680 return ast.getType() == TokenTypes.VARIABLE_DEF
681 && "fieldObj".equals(ast.findFirstToken(TokenTypes.IDENT)
682 .getText());
683 })
684 .orElseThrow();
685 final DetailAST literalNewField = fieldObj.findFirstToken(TokenTypes.ASSIGN)
686 .findFirstToken(TokenTypes.EXPR)
687 .findFirstToken(TokenTypes.LITERAL_NEW);
688
689 final boolean resultFalse = TestUtil.invokeStaticMethod(
690 UnusedLocalVariableCheck.class,
691 "isInsideLocalAnonInnerClass",
692 Boolean.class,
693 literalNewField);
694
695 assertWithMessage("Should be false for field initialization (no SLIST in ancestry)")
696 .that(resultFalse)
697 .isFalse();
698
699 final DetailAST localObj = TestUtil.findTokenInAstByPredicate(root,
700 ast -> {
701 return ast.getType() == TokenTypes.VARIABLE_DEF
702 && "localObj".equals(ast.findFirstToken(TokenTypes.IDENT)
703 .getText());
704 })
705 .orElseThrow();
706 final DetailAST literalNewLocal = localObj.findFirstToken(TokenTypes.ASSIGN)
707 .findFirstToken(TokenTypes.EXPR)
708 .findFirstToken(TokenTypes.LITERAL_NEW);
709
710 final boolean resultTrue = TestUtil.invokeStaticMethod(
711 UnusedLocalVariableCheck.class,
712 "isInsideLocalAnonInnerClass",
713 Boolean.class,
714 literalNewLocal);
715
716 assertWithMessage("Should be true for local variable initialization")
717 .that(resultTrue)
718 .isTrue();
719 }
720 }