Skip to content

Commit

Permalink
Issue #14506: False positive for UnusedLocalVariable
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin222004 authored and rnveach committed May 18, 2024
1 parent 40360c5 commit 6bb41a4
Show file tree
Hide file tree
Showing 5 changed files with 293 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,21 @@ public class UnusedLocalVariableCheck extends AbstractCheck {
TokenTypes.COMPACT_CTOR_DEF,
};

/**
* An array of token types that indicate a variable is being used within
* an expression involving increment or decrement operators, or within a switch statement.
* When a token of one of these types is the parent of an expression, it indicates that the
* variable associated with the increment or decrement operation is being used.
* Ex:- TokenTypes.LITERAL_SWITCH: Indicates a switch statement. Variables used within the
* switch expression are considered to be used
*/
private static final int[] INCREMENT_DECREMENT_VARIABLE_USAGE_TYPES = {
TokenTypes.ELIST,
TokenTypes.INDEX_OP,
TokenTypes.ASSIGN,
TokenTypes.LITERAL_SWITCH,
};

/** Package separator. */
private static final String PACKAGE_SEPARATOR = ".";

Expand Down Expand Up @@ -750,8 +765,7 @@ private static boolean isStandAloneIncrementOrDecrement(DetailAST identAst) {
* @return true if variable nested in exprAst is used
*/
private static boolean isIncrementOrDecrementVariableUsed(DetailAST exprAst) {
return TokenUtil.isOfType(exprAst.getParent(),
TokenTypes.ELIST, TokenTypes.INDEX_OP, TokenTypes.ASSIGN)
return TokenUtil.isOfType(exprAst.getParent(), INCREMENT_DECREMENT_VARIABLE_USAGE_TYPES)
&& exprAst.getParent().getParent().getType() != TokenTypes.FOR_ITERATOR;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,34 @@ public void testUnusedLocalVariableTernaryAndExpressions() throws Exception {
expected);
}

@Test
public void testUnusedLocalVariableSwitchStatement() throws Exception {
final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
verifyWithInlineConfigParser(
getPath("InputUnusedLocalVariableSwitchStatement.java"),
expected);
}

@Test
public void testUnusedLocalVariableSwitchStatement2() throws Exception {
final String[] expected = {
"58:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "j"),
};
verifyWithInlineConfigParser(
getPath("InputUnusedLocalVariableSwitchStatement2.java"),
expected);
}

@Test
public void testUnusedLocalVariableSwitchExpression() throws Exception {
final String[] expected = {
"15:9: " + getCheckMessage(MSG_UNUSED_LOCAL_VARIABLE, "line2"),
};
verifyWithInlineConfigParser(
getNonCompilablePath("InputUnusedLocalVariableSwitchExpression.java"),
expected);
}

@Test
public void testClearStateVariables() throws Exception {
final UnusedLocalVariableCheck check = new UnusedLocalVariableCheck();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
UnusedLocalVariable
*/

//non-compiled with javac: Compilable with Java14
package com.puppycrawl.tools.checkstyle.checks.coding.unusedlocalvariable;

public class InputUnusedLocalVariableSwitchExpression {

public int complexSwitch(int input) {
int check = 8;
int something = 0;
int line = 1;
int line2 = 9; // violation 'Unused local variable 'line2''
return switch (check++) {
case 0 -> {
int x = 2;
line2++;
yield switch (x) {
case 1 -> x++;
case 2 -> x--;
default -> 0;
};
}
case 1 -> {
int y = input * 2;
yield switch (++line) {
case 2, 4 -> y / 2;
case 6 -> y - 1;
default -> -1;
};
}
case 2 -> {
int checks = switch (something++) {
case 1 -> input/2;
default -> input;
};
yield checks;
}
default -> 0;
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
UnusedLocalVariable
*/

package com.puppycrawl.tools.checkstyle.checks.coding.unusedlocalvariable;

public class InputUnusedLocalVariableSwitchStatement {
public void testParameters0() {

int i = 0;
switch (i++) {
default:
case 0:
System.out.println("one: ");
break;
case 1:
System.out.println("two: " );
break;
}

}

public void testParameters01() {
int i = 0;
switch (++i) {
default:
case 0:
System.out.println("one: ");
break;
case 1:
System.out.println("two: " );
break;
}

}

public void testParameters() {
String[] tests = { "one", "two" };
int i = 0;
for (String test : tests) {
switch (i++) {
default:
case 0:
System.out.println("one: " + test);
break;
case 1:
System.out.println("two: " + test);
break;
}
}
}

public void testParameters2() {
String[] tests = { "one", "two" };
int i = 0;
for (String test : tests) {
switch (++i) {
default:
case 0:
System.out.println("one: " + test);
break;
case 1:
System.out.println("two: " + test);
break;
}
}
}

public void testParameters3() {
String[] tests = { "one", "two" };
int i = 0;
for (String test : tests) {
switch (--i) {
default:
case 0:
System.out.println("one: " + test);
break;
case 1:
System.out.println("two: " + test);
break;
}
}
}

public void testParameters4() {
String[] tests = { "one", "two" };
int i = 0;
for (String test : tests) {
switch (i--) {
default:
case 0:
System.out.println("one: " + test);
break;
case 1:
System.out.println("two: " + test);
break;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
UnusedLocalVariable
*/

package com.puppycrawl.tools.checkstyle.checks.coding.unusedlocalvariable;

public class InputUnusedLocalVariableSwitchStatement2 {
public void testParameters0() {

int i = 0;
switch (i+1) {
default:
case 0:
System.out.println("one: ");
break;
case 1:
System.out.println("two: " );
break;
}

}

public void testParameters01() {
int i = 0;
switch (1+i) {
default:
case 0:
System.out.println("one: ");
break;
case 1:
System.out.println("two: " );
break;
}

}

public void testParameters() {
String[] tests = { "one", "two" };
int i = 0;
for (String test : tests) {
switch (i+1) {
default:
case 0:
System.out.println("one: " + test);
break;
case 1:
System.out.println("two: " + test);
break;
}
}
}

public void testParameters2() {
String[] tests = { "one", "two" };
int i = 0;
i++;
int j = 0; // violation 'Unused local variable 'j''
for (String test : tests) {
switch (i) {
default:
case 0:
j++;
System.out.println("one: " + test);
break;
case 1:
System.out.println("two: " + test);
break;
}
}
}

public void testParameters4() {
int i = 2;
int j = 1;
switch (j) {
case 1:
System.out.println("j is 1");
break;
case 2:
System.out.println("j is 2");
System.out.println("i is: " + i);
break;
default:
System.out.println("j is something else");
}
}

public void testParameters5() {
int i = 2;
int j = 1;
switch (++j) {
case 1:
System.out.println("j is 1");
break;
case 2:
System.out.println("j is 2");
System.out.println("i is: " + ++i);
break;
default:
System.out.println("j is something else");
}
}
}

0 comments on commit 6bb41a4

Please sign in to comment.