public class FinalLocalVariableCheck extends AbstractCheck
Ensures that local variables that never get their values changed, must be declared final.
An example of how to configure the check to validate variable definition is:
<module name="FinalLocalVariable"> <property name="tokens" value="VARIABLE_DEF"/> </module>
By default, this Check skip final validation on Enhanced For-Loop
Option 'validateEnhancedForLoopVariable' could be used to make Check to validate even variable from Enhanced For Loop.
An example of how to configure the check so that it also validates enhanced For Loop Variable is:
<module name="FinalLocalVariable"> <property name="tokens" value="VARIABLE_DEF"/> <property name="validateEnhancedForLoopVariable" value="true"/> </module>
Example:
for (int number : myNumbers) { // violation
System.out.println(number);
}
Modifier and Type | Class and Description |
---|---|
private static class |
FinalLocalVariableCheck.FinalVariableCandidate
Represents information about final local variable candidate.
|
private static class |
FinalLocalVariableCheck.ScopeData
Holder for the scope data.
|
Modifier and Type | Field and Description |
---|---|
private static int[] |
ASSIGN_OPERATOR_TYPES
Assign operator types.
|
private java.util.Deque<java.util.Deque<DetailAST>> |
currentScopeAssignedVariables
Assigned variables of current scope.
|
private static int[] |
LOOP_TYPES
Loop types.
|
static java.lang.String |
MSG_KEY
A key is pointing to the warning message text in "messages.properties"
file.
|
private java.util.Deque<java.util.Deque<DetailAST>> |
prevScopeUninitializedVariables
Uninitialized variables of previous scope.
|
private java.util.Deque<FinalLocalVariableCheck.ScopeData> |
scopeStack
Scope Deque.
|
private boolean |
validateEnhancedForLoopVariable
Controls whether to check enhanced for-loop variable.
|
Constructor and Description |
---|
FinalLocalVariableCheck() |
Modifier and Type | Method and Description |
---|---|
private static void |
determineAssignmentConditions(DetailAST ident,
FinalLocalVariableCheck.FinalVariableCandidate candidate)
Determines identifier assignment conditions (assigned or already assigned).
|
private static DetailAST |
findFirstUpperNamedBlock(DetailAST ast)
Find the Class, Constructor, Enum, Method, or Field in which it is defined.
|
private static DetailAST |
findLastChildWhichContainsSpecifiedToken(DetailAST ast,
int childType,
int containType)
Returns the last child token that makes a specified type and contains containType in
its branch.
|
int[] |
getAcceptableTokens()
The configurable token set.
|
int[] |
getDefaultTokens()
Returns the default token a check is interested in.
|
private java.util.Optional<FinalLocalVariableCheck.FinalVariableCandidate> |
getFinalCandidate(DetailAST ast)
Gets final variable candidate for ast.
|
int[] |
getRequiredTokens()
The tokens that this check must be registered for.
|
private void |
insertParameter(DetailAST ast)
Insert a parameter at the topmost scope stack.
|
private void |
insertVariable(DetailAST ast)
Insert a variable at the topmost scope stack.
|
private static boolean |
isAssignOperator(int parentType)
Is Arithmetic operator.
|
private static boolean |
isCaseTokenWithAnotherCaseFollowing(DetailAST ast)
If token is CASE_GROUP and there is another
case following. |
private static boolean |
isFirstChild(DetailAST ast)
Whether the ast is the first child of its parent.
|
private static boolean |
isIfTokenWithAnElseFollowing(DetailAST ast)
If token is LITERAL_IF and there is an
else following. |
private static boolean |
isInAbstractOrNativeMethod(DetailAST ast)
Determines whether an AST is a descendant of an abstract or native method.
|
private static boolean |
isInitialized(DetailAST ast)
Check if VARIABLE_DEF is initialized or not.
|
private static boolean |
isInLambda(DetailAST paramDef)
Check if current param is lambda's param.
|
private static boolean |
isInSpecificCodeBlock(DetailAST node,
int blockType)
Checks whether the scope of a node is restricted to a specific code block.
|
private static boolean |
isInTheSameLoop(DetailAST ast1,
DetailAST ast2)
Check if both the variables are in the same loop.
|
private static boolean |
isLoopAst(int ast)
Checks whether the ast is a loop.
|
private boolean |
isMultipleTypeCatch(DetailAST parameterDefAst)
Check if given parameter definition is a multiple type catch.
|
private static boolean |
isSameVariables(DetailAST ast1,
DetailAST ast2)
Check if both the Variables are same.
|
private static boolean |
isUseOfExternalVariableInsideLoop(DetailAST variable)
Checks whether a variable which is declared outside loop is used inside loop.
|
private static boolean |
isVariableInForInit(DetailAST variableDef)
Checks if current variable is defined in
for-loop init , e.g.: |
void |
leaveToken(DetailAST ast)
Called after all the child nodes have been process.
|
private void |
removeFinalVariableCandidateFromStack(DetailAST ast)
Removes the final variable candidate from the Stack.
|
void |
setValidateEnhancedForLoopVariable(boolean validateEnhancedForLoopVariable)
Whether to check enhanced for-loop variable or not.
|
private boolean |
shouldCheckEnhancedForLoopVariable(DetailAST ast)
Determines whether enhanced for-loop variable should be checked or not.
|
private static boolean |
shouldRemoveFinalVariableCandidate(FinalLocalVariableCheck.ScopeData scopeData,
DetailAST ast)
Whether the final variable candidate should be removed from the list of final local variable
candidates.
|
private static boolean |
shouldUpdateUninitializedVariables(DetailAST ast)
If token is LITERAL_IF and there is an
else following or token is CASE_GROUP and
there is another case following, then update the uninitialized variables. |
private void |
storePrevScopeUninitializedVariableData()
Store un-initialized variables in a temporary stack for future use.
|
private void |
updateAllUninitializedVariables(java.util.Deque<DetailAST> prevScopeUnitializedVariableData)
Update current scope data uninitialized variable according to the whole scope data.
|
private void |
updateCurrentScopeAssignedVariables()
Update assigned variables in a temporary stack.
|
private void |
updateUninitializedVariables(java.util.Deque<DetailAST> scopeUnitializedVariableData)
Update current scope data uninitialized variable according to the specific scope data.
|
void |
visitToken(DetailAST ast)
Called to process a token.
|
beginTree, destroy, finishTree, getClassLoader, getFileContents, getLine, getLines, getTabWidth, getTokenNames, init, isCommentNodesRequired, log, log, setClassLoader, setFileContents, setMessages, setTabWidth, setTokens
getCustomMessages, getId, getMessageBundle, getSeverity, getSeverityLevel, log, setId, setSeverity
configure, contextualize, finishLocalSetup, getConfiguration, setupChild
public static final java.lang.String MSG_KEY
private static final int[] ASSIGN_OPERATOR_TYPES
private static final int[] LOOP_TYPES
private final java.util.Deque<FinalLocalVariableCheck.ScopeData> scopeStack
private final java.util.Deque<java.util.Deque<DetailAST>> prevScopeUninitializedVariables
private final java.util.Deque<java.util.Deque<DetailAST>> currentScopeAssignedVariables
private boolean validateEnhancedForLoopVariable
public final void setValidateEnhancedForLoopVariable(boolean validateEnhancedForLoopVariable)
validateEnhancedForLoopVariable
- whether to check for-loop variablepublic int[] getRequiredTokens()
AbstractCheck
getRequiredTokens
in class AbstractCheck
TokenTypes
public int[] getDefaultTokens()
AbstractCheck
getDefaultTokens
in class AbstractCheck
TokenTypes
public int[] getAcceptableTokens()
AbstractCheck
getAcceptableTokens
in class AbstractCheck
TokenTypes
public void visitToken(DetailAST ast)
AbstractCheck
visitToken
in class AbstractCheck
ast
- the token to processpublic void leaveToken(DetailAST ast)
AbstractCheck
leaveToken
in class AbstractCheck
ast
- the token leavingprivate void updateCurrentScopeAssignedVariables()
private static void determineAssignmentConditions(DetailAST ident, FinalLocalVariableCheck.FinalVariableCandidate candidate)
ident
- identifier.candidate
- final local variable candidate.private static boolean isInSpecificCodeBlock(DetailAST node, int blockType)
node
- node.blockType
- block type.private java.util.Optional<FinalLocalVariableCheck.FinalVariableCandidate> getFinalCandidate(DetailAST ast)
ast
- ast.FinalLocalVariableCheck.FinalVariableCandidate
for ast from scopeStack.private void storePrevScopeUninitializedVariableData()
private void updateAllUninitializedVariables(java.util.Deque<DetailAST> prevScopeUnitializedVariableData)
prevScopeUnitializedVariableData
- variable for previous stack of uninitialized
variablesprivate void updateUninitializedVariables(java.util.Deque<DetailAST> scopeUnitializedVariableData)
scopeUnitializedVariableData
- variable for specific stack of uninitialized variablesprivate static boolean shouldUpdateUninitializedVariables(DetailAST ast)
else
following or token is CASE_GROUP and
there is another case
following, then update the uninitialized variables.ast
- token to be checkedprivate static boolean isIfTokenWithAnElseFollowing(DetailAST ast)
else
following.ast
- token to be checkedelse
following, else falseprivate static boolean isCaseTokenWithAnotherCaseFollowing(DetailAST ast)
case
following.ast
- token to be checkedcase
following, else falseprivate static DetailAST findLastChildWhichContainsSpecifiedToken(DetailAST ast, int childType, int containType)
ast
- token to be testedchildType
- the token type to matchcontainType
- the token type which has to be present in the branchprivate boolean shouldCheckEnhancedForLoopVariable(DetailAST ast)
ast
- The ast to compare.private void insertParameter(DetailAST ast)
ast
- the variable to insert.private void insertVariable(DetailAST ast)
ast
- the variable to insert.private static boolean isInitialized(DetailAST ast)
ast
- VARIABLE_DEF to be checkedprivate static boolean isFirstChild(DetailAST ast)
ast
- the ast to check.private void removeFinalVariableCandidateFromStack(DetailAST ast)
ast
- variable to remove.private boolean isMultipleTypeCatch(DetailAST parameterDefAst)
parameterDefAst
- parameter definitionprivate static boolean shouldRemoveFinalVariableCandidate(FinalLocalVariableCheck.ScopeData scopeData, DetailAST ast)
scopeData
- the scope data of the variable.ast
- the variable ast.private static boolean isUseOfExternalVariableInsideLoop(DetailAST variable)
int x;
for (int i = 0, j = 0; i < j; i++) {
x = 5;
}
variable
- variable.private static boolean isAssignOperator(int parentType)
parentType
- token ASTprivate static boolean isVariableInForInit(DetailAST variableDef)
for-loop init
, e.g.:
for (int i = 0, j = 0; i < j; i++) { . . . }
i, j
are defined in for-loop init
variableDef
- variable definition node.for-loop init
private static boolean isInAbstractOrNativeMethod(DetailAST ast)
ast
- the AST to check.private static boolean isInLambda(DetailAST paramDef)
paramDef
- parameter def
.private static DetailAST findFirstUpperNamedBlock(DetailAST ast)
ast
- Variable for which we want to find the scope in which it is definedprivate static boolean isSameVariables(DetailAST ast1, DetailAST ast2)
ast1
- Variable to compareast2
- Variable to compareprivate static boolean isInTheSameLoop(DetailAST ast1, DetailAST ast2)
ast1
- variable to compare.ast2
- variable to compare.private static boolean isLoopAst(int ast)
ast
- the ast to check.