Class FinalLocalVariableCheck
- java.lang.Object
-
- com.puppycrawl.tools.checkstyle.api.AutomaticBean
-
- com.puppycrawl.tools.checkstyle.api.AbstractViolationReporter
-
- com.puppycrawl.tools.checkstyle.api.AbstractCheck
-
- com.puppycrawl.tools.checkstyle.checks.coding.FinalLocalVariableCheck
-
- All Implemented Interfaces:
Configurable,Contextualizable
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); }
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private static classFinalLocalVariableCheck.FinalVariableCandidateRepresents information about final local variable candidate.private static classFinalLocalVariableCheck.ScopeDataHolder for the scope data.
-
Field Summary
Fields Modifier and Type Field Description private static int[]ASSIGN_OPERATOR_TYPESAssign operator types.private java.util.Deque<java.util.Deque<DetailAST>>currentScopeAssignedVariablesAssigned variables of current scope.private static int[]LOOP_TYPESLoop types.static java.lang.StringMSG_KEYA key is pointing to the warning message text in "messages.properties" file.private java.util.Deque<java.util.Deque<DetailAST>>prevScopeUninitializedVariablesUninitialized variables of previous scope.private java.util.Deque<FinalLocalVariableCheck.ScopeData>scopeStackScope Deque.private booleanvalidateEnhancedForLoopVariableControls whether to check enhanced for-loop variable.
-
Constructor Summary
Constructors Constructor Description FinalLocalVariableCheck()
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description private static voiddetermineAssignmentConditions(DetailAST ident, FinalLocalVariableCheck.FinalVariableCandidate candidate)Determines identifier assignment conditions (assigned or already assigned).private static DetailASTfindFirstUpperNamedBlock(DetailAST ast)Find the Class, Constructor, Enum, Method, or Field in which it is defined.private static DetailASTfindLastChildWhichContainsSpecifiedToken(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 voidinsertParameter(DetailAST ast)Insert a parameter at the topmost scope stack.private voidinsertVariable(DetailAST ast)Insert a variable at the topmost scope stack.private static booleanisAssignOperator(int parentType)Is Arithmetic operator.private static booleanisCaseTokenWithAnotherCaseFollowing(DetailAST ast)If token is CASE_GROUP and there is anothercasefollowing.private static booleanisFirstChild(DetailAST ast)Whether the ast is the first child of its parent.private static booleanisIfTokenWithAnElseFollowing(DetailAST ast)If token is LITERAL_IF and there is anelsefollowing.private static booleanisInAbstractOrNativeMethod(DetailAST ast)Determines whether an AST is a descendant of an abstract or native method.private static booleanisInitialized(DetailAST ast)Check if VARIABLE_DEF is initialized or not.private static booleanisInLambda(DetailAST paramDef)Check if current param is lambda's param.private static booleanisInSpecificCodeBlock(DetailAST node, int blockType)Checks whether the scope of a node is restricted to a specific code block.private static booleanisInTheSameLoop(DetailAST ast1, DetailAST ast2)Check if both the variables are in the same loop.private static booleanisLoopAst(int ast)Checks whether the ast is a loop.private booleanisMultipleTypeCatch(DetailAST parameterDefAst)Check if given parameter definition is a multiple type catch.private static booleanisSameVariables(DetailAST ast1, DetailAST ast2)Check if both the Variables are same.private static booleanisUseOfExternalVariableInsideLoop(DetailAST variable)Checks whether a variable which is declared outside loop is used inside loop.private static booleanisVariableInForInit(DetailAST variableDef)Checks if current variable is defined infor-loop init, e.g.:voidleaveToken(DetailAST ast)Called after all the child nodes have been process.private voidremoveFinalVariableCandidateFromStack(DetailAST ast)Removes the final variable candidate from the Stack.voidsetValidateEnhancedForLoopVariable(boolean validateEnhancedForLoopVariable)Whether to check enhanced for-loop variable or not.private booleanshouldCheckEnhancedForLoopVariable(DetailAST ast)Determines whether enhanced for-loop variable should be checked or not.private static booleanshouldRemoveFinalVariableCandidate(FinalLocalVariableCheck.ScopeData scopeData, DetailAST ast)Whether the final variable candidate should be removed from the list of final local variable candidates.private static booleanshouldUpdateUninitializedVariables(DetailAST ast)If token is LITERAL_IF and there is anelsefollowing or token is CASE_GROUP and there is anothercasefollowing, then update the uninitialized variables.private voidstorePrevScopeUninitializedVariableData()Store un-initialized variables in a temporary stack for future use.private voidupdateAllUninitializedVariables(java.util.Deque<DetailAST> prevScopeUnitializedVariableData)Update current scope data uninitialized variable according to the whole scope data.private voidupdateCurrentScopeAssignedVariables()Update assigned variables in a temporary stack.private voidupdateUninitializedVariables(java.util.Deque<DetailAST> scopeUnitializedVariableData)Update current scope data uninitialized variable according to the specific scope data.voidvisitToken(DetailAST ast)Called to process a token.-
Methods inherited from class com.puppycrawl.tools.checkstyle.api.AbstractCheck
beginTree, destroy, finishTree, getClassLoader, getFileContents, getLine, getLines, getTabWidth, getTokenNames, init, isCommentNodesRequired, log, log, setClassLoader, setFileContents, setMessages, setTabWidth, setTokens
-
Methods inherited from class com.puppycrawl.tools.checkstyle.api.AbstractViolationReporter
getCustomMessages, getId, getMessageBundle, getSeverity, getSeverityLevel, log, setId, setSeverity
-
Methods inherited from class com.puppycrawl.tools.checkstyle.api.AutomaticBean
configure, contextualize, finishLocalSetup, getConfiguration, setupChild
-
-
-
-
Field Detail
-
MSG_KEY
public static final java.lang.String MSG_KEY
A key is pointing to the warning message text in "messages.properties" file.- See Also:
- Constant Field Values
-
ASSIGN_OPERATOR_TYPES
private static final int[] ASSIGN_OPERATOR_TYPES
Assign operator types.
-
LOOP_TYPES
private static final int[] LOOP_TYPES
Loop types.
-
scopeStack
private final java.util.Deque<FinalLocalVariableCheck.ScopeData> scopeStack
Scope Deque.
-
prevScopeUninitializedVariables
private final java.util.Deque<java.util.Deque<DetailAST>> prevScopeUninitializedVariables
Uninitialized variables of previous scope.
-
currentScopeAssignedVariables
private final java.util.Deque<java.util.Deque<DetailAST>> currentScopeAssignedVariables
Assigned variables of current scope.
-
validateEnhancedForLoopVariable
private boolean validateEnhancedForLoopVariable
Controls whether to check enhanced for-loop variable.
-
-
Method Detail
-
setValidateEnhancedForLoopVariable
public final void setValidateEnhancedForLoopVariable(boolean validateEnhancedForLoopVariable)
Whether to check enhanced for-loop variable or not.- Parameters:
validateEnhancedForLoopVariable- whether to check for-loop variable
-
getRequiredTokens
public int[] getRequiredTokens()
Description copied from class:AbstractCheckThe tokens that this check must be registered for.- Specified by:
getRequiredTokensin classAbstractCheck- Returns:
- the token set this must be registered for.
- See Also:
TokenTypes
-
getDefaultTokens
public int[] getDefaultTokens()
Description copied from class:AbstractCheckReturns the default token a check is interested in. Only used if the configuration for a check does not define the tokens.- Specified by:
getDefaultTokensin classAbstractCheck- Returns:
- the default tokens
- See Also:
TokenTypes
-
getAcceptableTokens
public int[] getAcceptableTokens()
Description copied from class:AbstractCheckThe configurable token set. Used to protect Checks against malicious users who specify an unacceptable token set in the configuration file. The default implementation returns the check's default tokens.- Specified by:
getAcceptableTokensin classAbstractCheck- Returns:
- the token set this check is designed for.
- See Also:
TokenTypes
-
visitToken
public void visitToken(DetailAST ast)
Description copied from class:AbstractCheckCalled to process a token.- Overrides:
visitTokenin classAbstractCheck- Parameters:
ast- the token to process
-
leaveToken
public void leaveToken(DetailAST ast)
Description copied from class:AbstractCheckCalled after all the child nodes have been process.- Overrides:
leaveTokenin classAbstractCheck- Parameters:
ast- the token leaving
-
updateCurrentScopeAssignedVariables
private void updateCurrentScopeAssignedVariables()
Update assigned variables in a temporary stack.
-
determineAssignmentConditions
private static void determineAssignmentConditions(DetailAST ident, FinalLocalVariableCheck.FinalVariableCandidate candidate)
Determines identifier assignment conditions (assigned or already assigned).- Parameters:
ident- identifier.candidate- final local variable candidate.
-
isInSpecificCodeBlock
private static boolean isInSpecificCodeBlock(DetailAST node, int blockType)
Checks whether the scope of a node is restricted to a specific code block.- Parameters:
node- node.blockType- block type.- Returns:
- true if the scope of a node is restricted to a specific code block.
-
getFinalCandidate
private java.util.Optional<FinalLocalVariableCheck.FinalVariableCandidate> getFinalCandidate(DetailAST ast)
Gets final variable candidate for ast.- Parameters:
ast- ast.- Returns:
- Optional of
FinalLocalVariableCheck.FinalVariableCandidatefor ast from scopeStack.
-
storePrevScopeUninitializedVariableData
private void storePrevScopeUninitializedVariableData()
Store un-initialized variables in a temporary stack for future use.
-
updateAllUninitializedVariables
private void updateAllUninitializedVariables(java.util.Deque<DetailAST> prevScopeUnitializedVariableData)
Update current scope data uninitialized variable according to the whole scope data.- Parameters:
prevScopeUnitializedVariableData- variable for previous stack of uninitialized variables
-
updateUninitializedVariables
private void updateUninitializedVariables(java.util.Deque<DetailAST> scopeUnitializedVariableData)
Update current scope data uninitialized variable according to the specific scope data.- Parameters:
scopeUnitializedVariableData- variable for specific stack of uninitialized variables
-
shouldUpdateUninitializedVariables
private static boolean shouldUpdateUninitializedVariables(DetailAST ast)
If token is LITERAL_IF and there is anelsefollowing or token is CASE_GROUP and there is anothercasefollowing, then update the uninitialized variables.- Parameters:
ast- token to be checked- Returns:
- true if should be updated, else false
-
isIfTokenWithAnElseFollowing
private static boolean isIfTokenWithAnElseFollowing(DetailAST ast)
If token is LITERAL_IF and there is anelsefollowing.- Parameters:
ast- token to be checked- Returns:
- true if token is LITERAL_IF and there is an
elsefollowing, else false
-
isCaseTokenWithAnotherCaseFollowing
private static boolean isCaseTokenWithAnotherCaseFollowing(DetailAST ast)
If token is CASE_GROUP and there is anothercasefollowing.- Parameters:
ast- token to be checked- Returns:
- true if token is CASE_GROUP and there is another
casefollowing, else false
-
findLastChildWhichContainsSpecifiedToken
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.- Parameters:
ast- token to be testedchildType- the token type to matchcontainType- the token type which has to be present in the branch- Returns:
- the matching token, or null if no match
-
shouldCheckEnhancedForLoopVariable
private boolean shouldCheckEnhancedForLoopVariable(DetailAST ast)
Determines whether enhanced for-loop variable should be checked or not.- Parameters:
ast- The ast to compare.- Returns:
- true if enhanced for-loop variable should be checked.
-
insertParameter
private void insertParameter(DetailAST ast)
Insert a parameter at the topmost scope stack.- Parameters:
ast- the variable to insert.
-
insertVariable
private void insertVariable(DetailAST ast)
Insert a variable at the topmost scope stack.- Parameters:
ast- the variable to insert.
-
isInitialized
private static boolean isInitialized(DetailAST ast)
Check if VARIABLE_DEF is initialized or not.- Parameters:
ast- VARIABLE_DEF to be checked- Returns:
- true if initialized
-
isFirstChild
private static boolean isFirstChild(DetailAST ast)
Whether the ast is the first child of its parent.- Parameters:
ast- the ast to check.- Returns:
- true if the ast is the first child of its parent.
-
removeFinalVariableCandidateFromStack
private void removeFinalVariableCandidateFromStack(DetailAST ast)
Removes the final variable candidate from the Stack.- Parameters:
ast- variable to remove.
-
isMultipleTypeCatch
private boolean isMultipleTypeCatch(DetailAST parameterDefAst)
Check if given parameter definition is a multiple type catch.- Parameters:
parameterDefAst- parameter definition- Returns:
- true if it is a multiple type catch, false otherwise
-
shouldRemoveFinalVariableCandidate
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.- Parameters:
scopeData- the scope data of the variable.ast- the variable ast.- Returns:
- true, if the variable should be removed.
-
isUseOfExternalVariableInsideLoop
private static boolean isUseOfExternalVariableInsideLoop(DetailAST variable)
Checks whether a variable which is declared outside loop is used inside loop. For example:int x; for (int i = 0, j = 0; i < j; i++) { x = 5; }- Parameters:
variable- variable.- Returns:
- true if a variable which is declared outside loop is used inside loop.
-
isAssignOperator
private static boolean isAssignOperator(int parentType)
Is Arithmetic operator.- Parameters:
parentType- token AST- Returns:
- true is token type is in arithmetic operator
-
isVariableInForInit
private static boolean isVariableInForInit(DetailAST variableDef)
Checks if current variable is defined infor-loop init, e.g.:for (int i = 0, j = 0; i < j; i++) { . . . }i, jare defined infor-loop init- Parameters:
variableDef- variable definition node.- Returns:
- true if variable is defined in
for-loop init
-
isInAbstractOrNativeMethod
private static boolean isInAbstractOrNativeMethod(DetailAST ast)
Determines whether an AST is a descendant of an abstract or native method.- Parameters:
ast- the AST to check.- Returns:
- true if ast is a descendant of an abstract or native method.
-
isInLambda
private static boolean isInLambda(DetailAST paramDef)
Check if current param is lambda's param.- Parameters:
paramDef-parameter def.- Returns:
- true if current param is lambda's param.
-
findFirstUpperNamedBlock
private static DetailAST findFirstUpperNamedBlock(DetailAST ast)
Find the Class, Constructor, Enum, Method, or Field in which it is defined.- Parameters:
ast- Variable for which we want to find the scope in which it is defined- Returns:
- ast The Class or Constructor or Method in which it is defined.
-
isSameVariables
private static boolean isSameVariables(DetailAST ast1, DetailAST ast2)
Check if both the Variables are same.- Parameters:
ast1- Variable to compareast2- Variable to compare- Returns:
- true if both the variables are same, otherwise false
-
isInTheSameLoop
private static boolean isInTheSameLoop(DetailAST ast1, DetailAST ast2)
Check if both the variables are in the same loop.- Parameters:
ast1- variable to compare.ast2- variable to compare.- Returns:
- true if both the variables are in the same loop.
-
isLoopAst
private static boolean isLoopAst(int ast)
Checks whether the ast is a loop.- Parameters:
ast- the ast to check.- Returns:
- true if the ast is a loop.
-
-