Class FinalLocalVariableCheck
- java.lang.Object
-
- com.puppycrawl.tools.checkstyle.AbstractAutomaticBean
-
- 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
Checks that local variables that never have their values changed are declared final. The check can be configured to also check that unchanged parameters are declared final.When configured to check parameters, the check ignores parameters of interface methods and abstract methods.
-
Property
validateEnhancedForLoopVariable
- Control whether to check enhanced for-loop variable. Type isboolean
. Default value isfalse
. -
Property
validateUnnamedVariables
- Control whether to check unnamed variables. Type isboolean
. Default value isfalse
. -
Property
tokens
- tokens to check Type isjava.lang.String[]
. Validation type istokenSet
. Default value is: VARIABLE_DEF.
Parent is
com.puppycrawl.tools.checkstyle.TreeWalker
Violation Message Keys:
-
final.variable
- Since:
- 3.2
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private static class
FinalLocalVariableCheck.FinalVariableCandidate
Represents information about final local variable candidate.private static class
FinalLocalVariableCheck.ScopeData
Holder for the scope data.-
Nested classes/interfaces inherited from class com.puppycrawl.tools.checkstyle.AbstractAutomaticBean
AbstractAutomaticBean.OutputStreamOptions
-
-
Field Summary
Fields Modifier and Type Field Description private static BitSet
ASSIGN_OPERATOR_TYPES
Assign operator types.private Deque<Deque<DetailAST>>
currentScopeAssignedVariables
Assigned variables of current scope.private static BitSet
LOOP_TYPES
Loop types.static String
MSG_KEY
A key is pointing to the warning message text in "messages.properties" file.private Deque<FinalLocalVariableCheck.ScopeData>
scopeStack
Scope Deque.private boolean
validateEnhancedForLoopVariable
Control whether to check enhanced for-loop variable.private boolean
validateUnnamedVariables
Control whether to check unnamed variables.
-
Constructor Summary
Constructors Constructor Description FinalLocalVariableCheck()
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method 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
findLastCaseGroupWhichContainsSlist(DetailAST literalSwitchAst)
Returns the last token of typeTokenTypes.CASE_GROUP
which containsTokenTypes.SLIST
.int[]
getAcceptableTokens()
The configurable token set.int[]
getDefaultTokens()
Returns the default token a check is interested in.private Optional<FinalLocalVariableCheck.FinalVariableCandidate>
getFinalCandidate(DetailAST ast)
Gets final variable candidate for ast.private static DetailAST
getParentLoop(DetailAST ast)
Get the ast node of typeLOOP_TYPES
that is the ancestor of the current ast node, if there is no such node, null is returned.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 or SWITCH_RULE and there is anothercase
following.private static boolean
isFirstChild(DetailAST ast)
Whether the ast is the first child of its parent.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
isInSpecificCodeBlocks(DetailAST node, int... blockTypes)
Checks whether the scope of a node is restricted to a specific code blocks.private static boolean
isLoopAst(int ast)
Checks whether the ast is a loop.private static 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
isVariableInForInit(DetailAST variableDef)
Checks if current variable is defined infor-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)
Setter to control whether to check enhanced for-loop variable.void
setValidateUnnamedVariables(boolean validateUnnamedVariables)
Setter to control whether to check unnamed variables.private boolean
shouldCheckEnhancedForLoopVariable(DetailAST ast)
Determines whether enhanced for-loop variable should be checked or not.private boolean
shouldCheckUnnamedVariable(DetailAST ast)
Determines whether unnamed 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 there is anelse
following or token is CASE_GROUP or SWITCH_RULE and there is anothercase
following, then update the uninitialized variables.private void
storePrevScopeUninitializedVariableData()
Store un-initialized variables in a temporary stack for future use.private void
updateAllUninitializedVariables()
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(Deque<DetailAST> scopeUninitializedVariableData)
Update current scope data uninitialized variable according to the specific scope data.void
visitToken(DetailAST ast)
Called to process a token.-
Methods inherited from class com.puppycrawl.tools.checkstyle.api.AbstractCheck
beginTree, clearViolations, destroy, finishTree, getFileContents, getFilePath, getLine, getLineCodePoints, getLines, getTabWidth, getTokenNames, getViolations, init, isCommentNodesRequired, log, log, log, setFileContents, setTabWidth, setTokens
-
Methods inherited from class com.puppycrawl.tools.checkstyle.api.AbstractViolationReporter
finishLocalSetup, getCustomMessages, getId, getMessageBundle, getSeverity, getSeverityLevel, setId, setSeverity
-
Methods inherited from class com.puppycrawl.tools.checkstyle.AbstractAutomaticBean
configure, contextualize, getConfiguration, setupChild
-
-
-
-
Field Detail
-
MSG_KEY
public static final 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 BitSet ASSIGN_OPERATOR_TYPES
Assign operator types.
-
LOOP_TYPES
private static final BitSet LOOP_TYPES
Loop types.
-
scopeStack
private final Deque<FinalLocalVariableCheck.ScopeData> scopeStack
Scope Deque.
-
currentScopeAssignedVariables
private final Deque<Deque<DetailAST>> currentScopeAssignedVariables
Assigned variables of current scope.
-
validateEnhancedForLoopVariable
private boolean validateEnhancedForLoopVariable
Control whether to check enhanced for-loop variable.
-
validateUnnamedVariables
private boolean validateUnnamedVariables
Control whether to check unnamed variables.
-
-
Constructor Detail
-
FinalLocalVariableCheck
public FinalLocalVariableCheck()
-
-
Method Detail
-
setValidateEnhancedForLoopVariable
public final void setValidateEnhancedForLoopVariable(boolean validateEnhancedForLoopVariable)
Setter to control whether to check enhanced for-loop variable.- Parameters:
validateEnhancedForLoopVariable
- whether to check for-loop variable- Since:
- 6.5
-
setValidateUnnamedVariables
public final void setValidateUnnamedVariables(boolean validateUnnamedVariables)
Setter to control whether to check unnamed variables.- Parameters:
validateUnnamedVariables
- whether to check unnamed variables- Since:
- 10.18.0
-
getRequiredTokens
public int[] getRequiredTokens()
Description copied from class:AbstractCheck
The tokens that this check must be registered for.- Specified by:
getRequiredTokens
in classAbstractCheck
- Returns:
- the token set this must be registered for.
- See Also:
TokenTypes
-
getDefaultTokens
public int[] getDefaultTokens()
Description copied from class:AbstractCheck
Returns the default token a check is interested in. Only used if the configuration for a check does not define the tokens.- Specified by:
getDefaultTokens
in classAbstractCheck
- Returns:
- the default tokens
- See Also:
TokenTypes
-
getAcceptableTokens
public int[] getAcceptableTokens()
Description copied from class:AbstractCheck
The 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:
getAcceptableTokens
in classAbstractCheck
- Returns:
- the token set this check is designed for.
- See Also:
TokenTypes
-
visitToken
public void visitToken(DetailAST ast)
Description copied from class:AbstractCheck
Called to process a token.- Overrides:
visitToken
in classAbstractCheck
- Parameters:
ast
- the token to process
-
leaveToken
public void leaveToken(DetailAST ast)
Description copied from class:AbstractCheck
Called after all the child nodes have been process.- Overrides:
leaveToken
in 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.
-
isInSpecificCodeBlocks
private static boolean isInSpecificCodeBlocks(DetailAST node, int... blockTypes)
Checks whether the scope of a node is restricted to a specific code blocks.- Parameters:
node
- node.blockTypes
- int array of all block types to check.- Returns:
- true if the scope of a node is restricted to specific code block types.
-
getFinalCandidate
private Optional<FinalLocalVariableCheck.FinalVariableCandidate> getFinalCandidate(DetailAST ast)
Gets final variable candidate for ast.- Parameters:
ast
- ast.- Returns:
- Optional of
FinalLocalVariableCheck.FinalVariableCandidate
for ast from scopeStack.
-
storePrevScopeUninitializedVariableData
private void storePrevScopeUninitializedVariableData()
Store un-initialized variables in a temporary stack for future use.
-
updateAllUninitializedVariables
private void updateAllUninitializedVariables()
Update current scope data uninitialized variable according to the whole scope data.
-
updateUninitializedVariables
private void updateUninitializedVariables(Deque<DetailAST> scopeUninitializedVariableData)
Update current scope data uninitialized variable according to the specific scope data.- Parameters:
scopeUninitializedVariableData
- variable for specific stack of uninitialized variables
-
shouldUpdateUninitializedVariables
private static boolean shouldUpdateUninitializedVariables(DetailAST ast)
If there is anelse
following or token is CASE_GROUP or SWITCH_RULE and there is anothercase
following, then update the uninitialized variables.- Parameters:
ast
- token to be checked- Returns:
- true if should be updated, else false
-
isCaseTokenWithAnotherCaseFollowing
private static boolean isCaseTokenWithAnotherCaseFollowing(DetailAST ast)
If token is CASE_GROUP or SWITCH_RULE and there is anothercase
following.- Parameters:
ast
- token to be checked- Returns:
- true if token is CASE_GROUP or SWITCH_RULE and there is another
case
following, else false
-
findLastCaseGroupWhichContainsSlist
private static DetailAST findLastCaseGroupWhichContainsSlist(DetailAST literalSwitchAst)
Returns the last token of typeTokenTypes.CASE_GROUP
which containsTokenTypes.SLIST
.- Parameters:
literalSwitchAst
- ast node of typeTokenTypes.LITERAL_SWITCH
- 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.
-
shouldCheckUnnamedVariable
private boolean shouldCheckUnnamedVariable(DetailAST ast)
Determines whether unnamed variable should be checked or not.- Parameters:
ast
- The ast to compare.- Returns:
- true if unnamed 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 static 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.
-
getParentLoop
private static DetailAST getParentLoop(DetailAST ast)
Get the ast node of typeLOOP_TYPES
that is the ancestor of the current ast node, if there is no such node, null is returned.- Parameters:
ast
- ast node- Returns:
- ast node of type
LOOP_TYPES
that is the ancestor of the current ast node, null if no such node exists
-
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, j
are 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
-
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.
-
-