public class UnusedLocalVariableCheck extends AbstractCheck
Checks that a local variable is declared and/or assigned, but not used. Doesn't support pattern variables yet. Doesn't check array components as array components are classified as different kind of variables by JLS.
To configure the check:
<module name="UnusedLocalVariable"/>
Example:
class Test {
int a;
{
int k = 12; // violation, assigned and updated but never used
k++;
}
Test(int a) { // ok as 'a' is a constructor parameter not a local variable
this.a = 12;
}
void method(int b) {
int a = 10; // violation
int[] arr = {1, 2, 3}; // violation
int[] anotherArr = {1}; // ok
anotherArr[0] = 4;
}
String convertValue(String newValue) {
String s = newValue.toLowerCase(); // violation
return newValue.toLowerCase();
}
void read() throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String s; // violation
while ((s = reader.readLine()) != null) {
}
try (BufferedReader reader1 // ok as 'reader1' is a resource and resources are closed
// at the end of the statement
= new BufferedReader(new FileReader("abc.txt"))) {
}
try {
} catch (Exception e) { // ok as e is an exception parameter
}
}
void loops() {
int j = 12;
for (int i = 0; j < 11; i++) { // violation, unused local variable 'i'.
}
for (int p = 0; j < 11; p++) // ok
p /= 2;
}
void lambdas() {
Predicate<String> obj = (String str) -> { // ok as 'str' is a lambda parameter
return true;
};
obj.test("test");
}
}
Parent is com.puppycrawl.tools.checkstyle.TreeWalker
Violation Message Keys:
unused.local.var
| Modifier and Type | Class and Description |
|---|---|
private static class |
UnusedLocalVariableCheck.TypeDeclDesc
Maintains information about the type declaration.
|
private static class |
UnusedLocalVariableCheck.VariableDesc
Maintains information about the variable.
|
AutomaticBean.OutputStreamOptions| Modifier and Type | Field and Description |
|---|---|
private java.util.Map<DetailAST,UnusedLocalVariableCheck.TypeDeclDesc> |
anonInnerAstToTypeDeclDesc
Maps local anonymous inner class to the TypeDeclDesc object
containing it.
|
private java.util.Set<DetailAST> |
anonInnerClassHolders
Set of tokens of type
CONTAINERS_FOR_ANON_INNERS
and TokenTypes.LAMBDA in some cases. |
private static int[] |
CONTAINERS_FOR_ANON_INNERS
An array of blocks in which local anon inner classes can exist.
|
private int |
depth
Depth at which a type declaration is nested, 0 for top level type declarations.
|
private static int[] |
INCREMENT_AND_DECREMENT_TOKENS
An array of increment and decrement tokens.
|
static java.lang.String |
MSG_UNUSED_LOCAL_VARIABLE
A key is pointing to the warning message text in "messages.properties"
file.
|
private static java.lang.String |
PACKAGE_SEPARATOR
Package separator.
|
private java.lang.String |
packageName
Name of the package.
|
private static int[] |
SCOPES
An array of scope tokens.
|
private java.util.Deque<UnusedLocalVariableCheck.TypeDeclDesc> |
typeDeclarations
Keeps track of all the type declarations present in the file.
|
private java.util.Map<DetailAST,UnusedLocalVariableCheck.TypeDeclDesc> |
typeDeclAstToTypeDeclDesc
Maps type declaration ast to their respective TypeDeclDesc objects.
|
private static int[] |
UNACCEPTABLE_CHILD_OF_DOT
An array of unacceptable children of ast of type
TokenTypes.DOT. |
private static int[] |
UNACCEPTABLE_PARENT_OF_IDENT
An array of unacceptable parent of ast of type
TokenTypes.IDENT. |
private java.util.Deque<UnusedLocalVariableCheck.VariableDesc> |
variables
Keeps tracks of the variables declared in file.
|
| Constructor and Description |
|---|
UnusedLocalVariableCheck()
Creates a new
UnusedLocalVariableCheck instance. |
| Modifier and Type | Method and Description |
|---|---|
private void |
addInstanceOrClassVar(DetailAST varDefAst)
Add instance variables and class variables to the
UnusedLocalVariableCheck.TypeDeclDesc.instanceAndClassVarStack. |
private static void |
addLocalVariables(DetailAST varDefAst,
java.util.Deque<UnusedLocalVariableCheck.VariableDesc> variablesStack)
Add local variables to the
variablesStack stack. |
void |
beginTree(DetailAST root)
Called before the starting to process a tree.
|
private static void |
checkIdentifierAst(DetailAST identAst,
java.util.Deque<UnusedLocalVariableCheck.VariableDesc> variablesStack)
Checks the identifier ast.
|
private void |
customLeaveToken(DetailAST ast,
java.util.Deque<UnusedLocalVariableCheck.VariableDesc> variablesStack)
Leave all ast nodes under
anonInnerClassHolders once
again. |
private void |
customVisitToken(DetailAST ast,
java.util.Deque<UnusedLocalVariableCheck.VariableDesc> variablesStack)
Visit all ast nodes under
anonInnerClassHolders once
again. |
private static java.lang.String |
extractQualifiedName(DetailAST ast)
Get name of package and super class of anon inner class by concatenating
the identifier values under
TokenTypes.DOT. |
private static DetailAST |
findScopeOfVariable(DetailAST variableDef)
Find the scope of variable.
|
int[] |
getAcceptableTokens()
The configurable token set.
|
private static DetailAST |
getBlockContainingLocalAnonInnerClass(DetailAST literalNewAst)
Get the block containing local anon inner class.
|
int[] |
getDefaultTokens()
Returns the default token a check is interested in.
|
private java.lang.String |
getQualifiedTypeDeclarationName(DetailAST typeDeclAst)
Get qualified type declaration name from type ast.
|
private static java.lang.String |
getQualifiedTypeDeclarationName(java.lang.String packageName,
java.lang.String outerClassQualifiedName,
java.lang.String className)
Get the qualified name of type declaration by combining
packageName,
outerClassQualifiedName and className. |
int[] |
getRequiredTokens()
The tokens that this check must be registered for.
|
static java.lang.String |
getShortNameOfAnonInnerClass(DetailAST literalNewAst)
Get the short name of super class of anonymous inner class.
|
private UnusedLocalVariableCheck.TypeDeclDesc |
getSuperClassOfAnonInnerClass(DetailAST literalNewAst)
Get the
UnusedLocalVariableCheck.TypeDeclDesc of the super class of anonymous inner class. |
private static UnusedLocalVariableCheck.TypeDeclDesc |
getTheNearestClass(java.lang.String outerTypeDeclName,
java.util.List<UnusedLocalVariableCheck.TypeDeclDesc> typeDeclWithSameName)
For all type declarations with the same name as the superclass, gets the nearest type
declaration.
|
private boolean |
hasSameNameAsSuperClass(java.lang.String superClassName,
UnusedLocalVariableCheck.TypeDeclDesc typeDeclDesc)
Whether the qualified name of
typeDeclDesc matches the super class name. |
private static boolean |
isIncrementOrDecrementVariableUsed(DetailAST exprAst)
A variable with increment or decrement operator is considered used if it
is used as an argument or as an array index or for assigning value
to a variable.
|
private static boolean |
isInsideLocalAnonInnerClass(DetailAST literalNewAst)
Whether ast node of type
TokenTypes.LITERAL_NEW is a part of a local
anonymous inner class. |
private static boolean |
isLeftHandSideValue(DetailAST identAst)
Checks whether the ast of type
TokenTypes.IDENT is
used as left-hand side value. |
private static boolean |
isNonLocalTypeDeclaration(DetailAST typeDeclAst)
Whether a type declaration is non-local.
|
private static boolean |
isPrivateInstanceVariable(DetailAST varDefAst)
Whether instance variable or class variable have private access modifier.
|
private static boolean |
isStandAloneIncrementOrDecrement(DetailAST identAst)
Checks whether the ast of type
TokenTypes.IDENT is used as
an operand of a stand-alone increment or decrement. |
private void |
iterateOverBlockContainingLocalAnonInnerClass(DetailAST ast,
java.util.Deque<UnusedLocalVariableCheck.VariableDesc> variablesStack)
Iterate over all the ast nodes present under
ast. |
private void |
leaveCompilationUnit()
We process all the blocks containing local anonymous inner classes
separately after processing all the other nodes.
|
void |
leaveToken(DetailAST ast)
Called after all the child nodes have been process.
|
private void |
logViolations(DetailAST scopeAst,
java.util.Deque<UnusedLocalVariableCheck.VariableDesc> variablesStack)
Traverse
variablesStack stack and log the violations. |
private void |
modifyVariablesStack(UnusedLocalVariableCheck.TypeDeclDesc obtainedClass,
java.util.Deque<UnusedLocalVariableCheck.VariableDesc> variablesStack,
DetailAST literalNewAst)
Add non-private instance and class variables of the super class of the anonymous class
to the variables stack.
|
static boolean |
shouldCheckIdentTokenNestedUnderDot(DetailAST dotAst)
Whether to check identifier token nested under dotAst.
|
static boolean |
shouldCheckIdentWithMethodRefParent(DetailAST identAst)
Whether an ident with parent node of type
TokenTypes.METHOD_REF
should be checked or not. |
private static int |
typeDeclNameMatchingCount(java.lang.String patternClass,
java.lang.String classToBeMatched)
Calculates and returns the type declaration name matching count.
|
private java.util.List<UnusedLocalVariableCheck.TypeDeclDesc> |
typeDeclWithSameName(java.lang.String superClassName)
Checks if there is a type declaration with same name as the super class.
|
private static void |
visitDotToken(DetailAST dotAst,
java.util.Deque<UnusedLocalVariableCheck.VariableDesc> variablesStack)
Visit ast of type
TokenTypes.DOT. |
private static void |
visitIdentToken(DetailAST identAst,
java.util.Deque<UnusedLocalVariableCheck.VariableDesc> variablesStack)
Visit ast of type
TokenTypes.IDENT. |
private void |
visitLocalAnonInnerClass(DetailAST literalNewAst)
Visit the local anon inner class.
|
void |
visitToken(DetailAST ast)
Called to process a token.
|
private void |
visitTypeDeclarationToken(DetailAST typeDeclAst)
Visit the type declaration token.
|
private void |
visitVariableDefToken(DetailAST varDefAst)
Visit ast of type
TokenTypes.VARIABLE_DEF. |
clearViolations, destroy, finishTree, getFileContents, getLine, getLineCodePoints, getLines, getTabWidth, getTokenNames, getViolations, init, isCommentNodesRequired, log, log, log, setFileContents, setTabWidth, setTokensfinishLocalSetup, getCustomMessages, getId, getMessageBundle, getSeverity, getSeverityLevel, setId, setSeverityconfigure, contextualize, getConfiguration, setupChildpublic static final java.lang.String MSG_UNUSED_LOCAL_VARIABLE
private static final int[] INCREMENT_AND_DECREMENT_TOKENS
private static final int[] SCOPES
private static final int[] UNACCEPTABLE_CHILD_OF_DOT
TokenTypes.DOT.private static final int[] UNACCEPTABLE_PARENT_OF_IDENT
TokenTypes.IDENT.private static final int[] CONTAINERS_FOR_ANON_INNERS
private static final java.lang.String PACKAGE_SEPARATOR
private final java.util.Deque<UnusedLocalVariableCheck.VariableDesc> variables
private final java.util.Deque<UnusedLocalVariableCheck.TypeDeclDesc> typeDeclarations
private final java.util.Map<DetailAST,UnusedLocalVariableCheck.TypeDeclDesc> typeDeclAstToTypeDeclDesc
private final java.util.Map<DetailAST,UnusedLocalVariableCheck.TypeDeclDesc> anonInnerAstToTypeDeclDesc
private final java.util.Set<DetailAST> anonInnerClassHolders
CONTAINERS_FOR_ANON_INNERS
and TokenTypes.LAMBDA in some cases.private java.lang.String packageName
private int depth
public UnusedLocalVariableCheck()
UnusedLocalVariableCheck instance.public int[] getDefaultTokens()
AbstractCheckgetDefaultTokens in class AbstractCheckTokenTypespublic int[] getAcceptableTokens()
AbstractCheckgetAcceptableTokens in class AbstractCheckTokenTypespublic int[] getRequiredTokens()
AbstractCheckgetRequiredTokens in class AbstractCheckTokenTypespublic void beginTree(DetailAST root)
AbstractCheckbeginTree in class AbstractCheckroot - the root of the treepublic void visitToken(DetailAST ast)
AbstractCheckvisitToken in class AbstractCheckast - the token to processpublic void leaveToken(DetailAST ast)
AbstractCheckleaveToken in class AbstractCheckast - the token leavingprivate static void visitDotToken(DetailAST dotAst, java.util.Deque<UnusedLocalVariableCheck.VariableDesc> variablesStack)
TokenTypes.DOT.dotAst - dotAstvariablesStack - stack of all the relevant variables in the scopeprivate void visitVariableDefToken(DetailAST varDefAst)
TokenTypes.VARIABLE_DEF.varDefAst - varDefAstprivate static void visitIdentToken(DetailAST identAst, java.util.Deque<UnusedLocalVariableCheck.VariableDesc> variablesStack)
TokenTypes.IDENT.identAst - identAstvariablesStack - stack of all the relevant variables in the scopeprivate void visitTypeDeclarationToken(DetailAST typeDeclAst)
typeDeclAst - type declaration astprivate void visitLocalAnonInnerClass(DetailAST literalNewAst)
literalNewAst - literalNewAstprivate static java.lang.String extractQualifiedName(DetailAST ast)
TokenTypes.DOT.
Duplicated, until https://github.com/checkstyle/checkstyle/issues/11201ast - ast to extract superclass or package name fromprivate static boolean isInsideLocalAnonInnerClass(DetailAST literalNewAst)
TokenTypes.LITERAL_NEW is a part of a local
anonymous inner class.literalNewAst - ast node of type TokenTypes.LITERAL_NEWprivate void logViolations(DetailAST scopeAst, java.util.Deque<UnusedLocalVariableCheck.VariableDesc> variablesStack)
variablesStack stack and log the violations.scopeAst - ast node of type SCOPESvariablesStack - stack of all the relevant variables in the scopeprivate void leaveCompilationUnit()
private static boolean isNonLocalTypeDeclaration(DetailAST typeDeclAst)
typeDeclAst - type declaration astprivate static DetailAST getBlockContainingLocalAnonInnerClass(DetailAST literalNewAst)
literalNewAst - ast node of type TokenTypes.LITERAL_NEWprivate static void addLocalVariables(DetailAST varDefAst, java.util.Deque<UnusedLocalVariableCheck.VariableDesc> variablesStack)
variablesStack stack.
Also adds the instance variables defined in a local anonymous inner class.varDefAst - ast node of type TokenTypes.VARIABLE_DEFvariablesStack - stack of all the relevant variables in the scopeprivate void addInstanceOrClassVar(DetailAST varDefAst)
UnusedLocalVariableCheck.TypeDeclDesc.instanceAndClassVarStack.varDefAst - ast node of type TokenTypes.VARIABLE_DEFprivate static boolean isPrivateInstanceVariable(DetailAST varDefAst)
varDefAst - ast node of type TokenTypes.VARIABLE_DEFprivate UnusedLocalVariableCheck.TypeDeclDesc getSuperClassOfAnonInnerClass(DetailAST literalNewAst)
UnusedLocalVariableCheck.TypeDeclDesc of the super class of anonymous inner class.literalNewAst - ast node of type TokenTypes.LITERAL_NEWUnusedLocalVariableCheck.TypeDeclDesc of the super class of anonymous inner classpublic static java.lang.String getShortNameOfAnonInnerClass(DetailAST literalNewAst)
TestClass.NestedClass obj = new Test().new NestedClass() {};
// Short name will be Test.NestedClass
literalNewAst - ast node of type TokenTypes.LITERAL_NEWprivate void modifyVariablesStack(UnusedLocalVariableCheck.TypeDeclDesc obtainedClass, java.util.Deque<UnusedLocalVariableCheck.VariableDesc> variablesStack, DetailAST literalNewAst)
obtainedClass - super class of the anon inner classvariablesStack - stack of all the relevant variables in the scopeliteralNewAst - ast node of type TokenTypes.LITERAL_NEWprivate java.util.List<UnusedLocalVariableCheck.TypeDeclDesc> typeDeclWithSameName(java.lang.String superClassName)
superClassName - name of the super classprivate boolean hasSameNameAsSuperClass(java.lang.String superClassName, UnusedLocalVariableCheck.TypeDeclDesc typeDeclDesc)
typeDeclDesc matches the super class name.superClassName - name of the super classtypeDeclDesc - type declaration descriptiontrue if the qualified name of typeDeclDesc
matches the super class nameprivate static UnusedLocalVariableCheck.TypeDeclDesc getTheNearestClass(java.lang.String outerTypeDeclName, java.util.List<UnusedLocalVariableCheck.TypeDeclDesc> typeDeclWithSameName)
outerTypeDeclName - outer type declaration of anonymous inner classtypeDeclWithSameName - typeDeclarations which have the same name as the super classprivate static int typeDeclNameMatchingCount(java.lang.String patternClass, java.lang.String classToBeMatched)
Suppose our pattern class is foo.a.b and class to be matched is
foo.a.ball then type declaration name matching count would be calculated by
comparing every character, and updating main counter when we hit "." to prevent matching
"a.b" with "a.ball". In this case type declaration name matching count
would be equal to 6 and not 7 (b of ball is not counted).
patternClass - class against which the given class has to be matchedclassToBeMatched - class to be matchedprivate java.lang.String getQualifiedTypeDeclarationName(DetailAST typeDeclAst)
typeDeclAst - type declaration astprivate static java.lang.String getQualifiedTypeDeclarationName(java.lang.String packageName, java.lang.String outerClassQualifiedName, java.lang.String className)
packageName,
outerClassQualifiedName and className.
Duplicated, until https://github.com/checkstyle/checkstyle/issues/11201packageName - packageNameouterClassQualifiedName - outerClassQualifiedNameclassName - classNamepackageName,
outerClassQualifiedName and classNameprivate void iterateOverBlockContainingLocalAnonInnerClass(DetailAST ast, java.util.Deque<UnusedLocalVariableCheck.VariableDesc> variablesStack)
ast.ast - astvariablesStack - stack of all the relevant variables in the scopeprivate void customVisitToken(DetailAST ast, java.util.Deque<UnusedLocalVariableCheck.VariableDesc> variablesStack)
anonInnerClassHolders once
again.ast - astvariablesStack - stack of all the relevant variables in the scopeprivate void customLeaveToken(DetailAST ast, java.util.Deque<UnusedLocalVariableCheck.VariableDesc> variablesStack)
anonInnerClassHolders once
again.ast - astvariablesStack - stack of all the relevant variables in the scopepublic static boolean shouldCheckIdentWithMethodRefParent(DetailAST identAst)
TokenTypes.METHOD_REF
should be checked or not.identAst - identAstTokenTypes.METHOD_REF
should be checked or if the parent type is not TokenTypes.METHOD_REFpublic static boolean shouldCheckIdentTokenNestedUnderDot(DetailAST dotAst)
dotAst - dotAstprivate static void checkIdentifierAst(DetailAST identAst, java.util.Deque<UnusedLocalVariableCheck.VariableDesc> variablesStack)
identAst - ast of type TokenTypes.IDENTvariablesStack - stack of all the relevant variables in the scopeprivate static DetailAST findScopeOfVariable(DetailAST variableDef)
variableDef - ast of type TokenTypes.VARIABLE_DEFprivate static boolean isLeftHandSideValue(DetailAST identAst)
TokenTypes.IDENT is
used as left-hand side value. An identifier is being used as a left-hand side
value if it is used as the left operand of an assignment or as an
operand of a stand-alone increment or decrement.identAst - ast of type TokenTypes.IDENTprivate static boolean isStandAloneIncrementOrDecrement(DetailAST identAst)
TokenTypes.IDENT is used as
an operand of a stand-alone increment or decrement.identAst - ast of type TokenTypes.IDENTprivate static boolean isIncrementOrDecrementVariableUsed(DetailAST exprAst)
exprAst - ast of type TokenTypes.EXPRCopyright © 2001-2022. All Rights Reserved.