Class VariableDeclarationUsageDistanceCheck
- 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.VariableDeclarationUsageDistanceCheck
-
- All Implemented Interfaces:
Configurable
,Contextualizable
public class VariableDeclarationUsageDistanceCheck extends AbstractCheck
Checks the distance between declaration of variable and its first usage.
Example #1:int count; a = a + b; b = a + a; count = b; // DECLARATION OF VARIABLE 'count' // SHOULD BE HERE (distance = 3)
int count; { a = a + b; count = b; // DECLARATION OF VARIABLE 'count' // SHOULD BE HERE (distance = 2) }
Check can detect a block of initialization methods. If a variable is used in such a block and there is no other statements after this variable then distance=1.
Case #1:
int minutes = 5; Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(timeNow); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); cal.set(Calendar.HOUR_OF_DAY, hh); cal.set(Calendar.MINUTE, minutes); The distance for the variable minutes is 1 even though this variable is used in the fifth method's call.
Case #2:
int minutes = 5; Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(timeNow); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); System.out.println(cal); cal.set(Calendar.HOUR_OF_DAY, hh); cal.set(Calendar.MINUTE, minutes); The distance for the variable minutes is 6 because there is one more expression (except the initialization block) between the declaration of this variable and its usage.
There are several additional options to configure the check:
1. allowedDistance - allows to set a distance between declaration of variable and its first usage. 2. ignoreVariablePattern - allows to set a RegEx pattern for ignoring the distance calculation for variables listed in this pattern. 3. validateBetweenScopes - allows to calculate the distance between declaration of variable and its first usage in the different scopes. 4. ignoreFinal - allows to ignore variables with a 'final' modifier.
ATTENTION!! (Not supported cases)Case #1:
As distance by default is 1 the Check doesn't raise warning for variables 'a' and 'b' to move them into the block.{ int c; int a = 3; int b = 2; { a = a + b; c = b; } }
Distance for variable 'a' = 1; Distance for variable 'b' = 1; Distance for variable 'c' = 2.Case #2:
int sum = 0; for (int i = 0; i < 20; i++) { a++; b--; sum++; if (sum > 10) { res = true; } }
Distance for variable 'sum' = 3.As the distance is more then the default one, the Check raises warning for variable 'sum' to move it into the 'for(...)' block. But there is situation when variable 'sum' hasn't to be 0 within each iteration. So, to avoid such warnings you can use Suppression Filter, provided by Checkstyle, for the whole class.
An example how to configure this Check:
<module name="VariableDeclarationUsageDistance"/>
An example of how to configure this Check: - to set the allowed distance to 4; - to ignore variables with prefix '^temp'; - to force the validation between scopes; - to check the final variables;
<module name="VariableDeclarationUsageDistance"> <property name="allowedDistance" value="4"/> <property name="ignoreVariablePattern" value="^temp.*"/> <property name="validateBetweenScopes" value="true"/> <property name="ignoreFinal" value="false"/> </module>
-
-
Field Summary
Fields Modifier and Type Field Description private int
allowedDistance
Allowed distance between declaration of variable and its first usage.private static int
DEFAULT_DISTANCE
Default value of distance between declaration of variable and its first usage.private boolean
ignoreFinal
Allows to ignore variables with 'final' modifier.private java.util.regex.Pattern
ignoreVariablePattern
RegExp pattern to ignore distance calculation for variables listed in this pattern.static java.lang.String
MSG_KEY
Warning message key.static java.lang.String
MSG_KEY_EXT
Warning message key.private boolean
validateBetweenScopes
Allows to calculate distance between declaration of variable and its first usage in different scopes.
-
Constructor Summary
Constructors Constructor Description VariableDeclarationUsageDistanceCheck()
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description private static java.util.Map.Entry<DetailAST,java.lang.Integer>
calculateDistanceBetweenScopes(DetailAST ast, DetailAST variable)
Calculates distance between declaration of variable and its first usage in multiple scopes.private static java.util.Map.Entry<DetailAST,java.lang.Integer>
calculateDistanceInSingleScope(DetailAST semicolonAst, DetailAST variableIdentAst)
Calculates distance between declaration of variable and its first usage in single scope.int[]
getAcceptableTokens()
The configurable token set.int[]
getDefaultTokens()
Returns the default token a check is interested in.private static int
getDistToVariableUsageInChildNode(DetailAST childNode, DetailAST varIdent, int currentDistToVarUsage)
Returns the distance to variable usage for in the child node.private static DetailAST
getFirstNodeInsideForWhileDoWhileBlocks(DetailAST block, DetailAST variable)
Gets first Ast node inside FOR, WHILE or DO-WHILE blocks if variable usage is met only inside the block (not in its declaration!).private static DetailAST
getFirstNodeInsideIfBlock(DetailAST block, DetailAST variable)
Gets first Ast node inside IF block if variable usage is met only inside the block (not in its declaration!).private static DetailAST
getFirstNodeInsideSwitchBlock(DetailAST block, DetailAST variable)
Gets first Ast node inside SWITCH block if variable usage is met only inside the block (not in its declaration!).private static DetailAST
getFirstNodeInsideTryCatchFinallyBlocks(DetailAST block, DetailAST variable)
Gets first Ast node inside TRY-CATCH-FINALLY blocks if variable usage is met only inside the block (not in its declaration!).private static java.lang.String
getInstanceName(DetailAST methodCallAst)
Get name of instance whose method is called.int[]
getRequiredTokens()
The tokens that this check must be registered for.private static boolean
isChild(DetailAST parent, DetailAST ast)
Checks if Ast node contains given element.private static boolean
isInitializationSequence(DetailAST variableUsageAst, java.lang.String variableName)
Processes statements until usage of variable to detect sequence of initialization methods.private static boolean
isVariableInOperatorExpr(DetailAST operator, DetailAST variable)
Checks if variable is in operator declaration.private boolean
isVariableMatchesIgnorePattern(java.lang.String variable)
Checks if entrance variable is contained in ignored pattern.private static java.util.Map.Entry<java.util.List<DetailAST>,java.lang.Integer>
searchVariableUsageExpressions(DetailAST variableAst, DetailAST statementAst)
Searches variable usages starting from specified statement.void
setAllowedDistance(int allowedDistance)
Sets an allowed distance between declaration of variable and its first usage.void
setIgnoreFinal(boolean ignoreFinal)
Sets ignore option for variables with 'final' modifier.void
setIgnoreVariablePattern(java.util.regex.Pattern pattern)
Sets RegExp pattern to ignore distance calculation for variables listed in this pattern.void
setValidateBetweenScopes(boolean validateBetweenScopes)
Sets option which allows to calculate distance between declaration of variable and its first usage in different scopes.void
visitToken(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, leaveToken, 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
Warning message key.- See Also:
- Constant Field Values
-
MSG_KEY_EXT
public static final java.lang.String MSG_KEY_EXT
Warning message key.- See Also:
- Constant Field Values
-
DEFAULT_DISTANCE
private static final int DEFAULT_DISTANCE
Default value of distance between declaration of variable and its first usage.- See Also:
- Constant Field Values
-
allowedDistance
private int allowedDistance
Allowed distance between declaration of variable and its first usage.
-
ignoreVariablePattern
private java.util.regex.Pattern ignoreVariablePattern
RegExp pattern to ignore distance calculation for variables listed in this pattern.
-
validateBetweenScopes
private boolean validateBetweenScopes
Allows to calculate distance between declaration of variable and its first usage in different scopes.
-
ignoreFinal
private boolean ignoreFinal
Allows to ignore variables with 'final' modifier.
-
-
Method Detail
-
setAllowedDistance
public void setAllowedDistance(int allowedDistance)
Sets an allowed distance between declaration of variable and its first usage.- Parameters:
allowedDistance
- Allowed distance between declaration of variable and its first usage.
-
setIgnoreVariablePattern
public void setIgnoreVariablePattern(java.util.regex.Pattern pattern)
Sets RegExp pattern to ignore distance calculation for variables listed in this pattern.- Parameters:
pattern
- a pattern.
-
setValidateBetweenScopes
public void setValidateBetweenScopes(boolean validateBetweenScopes)
Sets option which allows to calculate distance between declaration of variable and its first usage in different scopes.- Parameters:
validateBetweenScopes
- Defines if allow to calculate distance between declaration of variable and its first usage in different scopes or not.
-
setIgnoreFinal
public void setIgnoreFinal(boolean ignoreFinal)
Sets ignore option for variables with 'final' modifier.- Parameters:
ignoreFinal
- Defines if ignore variables with 'final' modifier or not.
-
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
-
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
-
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
-
getInstanceName
private static java.lang.String getInstanceName(DetailAST methodCallAst)
Get name of instance whose method is called.- Parameters:
methodCallAst
- DetailAST of METHOD_CALL.- Returns:
- name of instance.
-
isInitializationSequence
private static boolean isInitializationSequence(DetailAST variableUsageAst, java.lang.String variableName)
Processes statements until usage of variable to detect sequence of initialization methods.- Parameters:
variableUsageAst
- DetailAST of expression that uses variable named variableName.variableName
- name of considered variable.- Returns:
- true if statements between declaration and usage of variable are initialization methods.
-
calculateDistanceInSingleScope
private static java.util.Map.Entry<DetailAST,java.lang.Integer> calculateDistanceInSingleScope(DetailAST semicolonAst, DetailAST variableIdentAst)
Calculates distance between declaration of variable and its first usage in single scope.- Parameters:
semicolonAst
- Regular node of Ast which is checked for content of checking variable.variableIdentAst
- Variable which distance is calculated for.- Returns:
- entry which contains expression with variable usage and distance.
-
getDistToVariableUsageInChildNode
private static int getDistToVariableUsageInChildNode(DetailAST childNode, DetailAST varIdent, int currentDistToVarUsage)
Returns the distance to variable usage for in the child node.- Parameters:
childNode
- child node.varIdent
- variable variable identifier.currentDistToVarUsage
- current distance to the variable usage.- Returns:
- the distance to variable usage for in the child node.
-
calculateDistanceBetweenScopes
private static java.util.Map.Entry<DetailAST,java.lang.Integer> calculateDistanceBetweenScopes(DetailAST ast, DetailAST variable)
Calculates distance between declaration of variable and its first usage in multiple scopes.- Parameters:
ast
- Regular node of Ast which is checked for content of checking variable.variable
- Variable which distance is calculated for.- Returns:
- entry which contains expression with variable usage and distance.
-
searchVariableUsageExpressions
private static java.util.Map.Entry<java.util.List<DetailAST>,java.lang.Integer> searchVariableUsageExpressions(DetailAST variableAst, DetailAST statementAst)
Searches variable usages starting from specified statement.- Parameters:
variableAst
- Variable that is used.statementAst
- DetailAST to start searching from.- Returns:
- entry which contains list with found expressions that use the variable and distance from specified statement to first found expression.
-
getFirstNodeInsideForWhileDoWhileBlocks
private static DetailAST getFirstNodeInsideForWhileDoWhileBlocks(DetailAST block, DetailAST variable)
Gets first Ast node inside FOR, WHILE or DO-WHILE blocks if variable usage is met only inside the block (not in its declaration!).- Parameters:
block
- Ast node represents FOR, WHILE or DO-WHILE block.variable
- Variable which is checked for content in block.- Returns:
- If variable usage is met only inside the block (not in its declaration!) than return the first Ast node of this block, otherwise - null.
-
getFirstNodeInsideIfBlock
private static DetailAST getFirstNodeInsideIfBlock(DetailAST block, DetailAST variable)
Gets first Ast node inside IF block if variable usage is met only inside the block (not in its declaration!).- Parameters:
block
- Ast node represents IF block.variable
- Variable which is checked for content in block.- Returns:
- If variable usage is met only inside the block (not in its declaration!) than return the first Ast node of this block, otherwise - null.
-
getFirstNodeInsideSwitchBlock
private static DetailAST getFirstNodeInsideSwitchBlock(DetailAST block, DetailAST variable)
Gets first Ast node inside SWITCH block if variable usage is met only inside the block (not in its declaration!).- Parameters:
block
- Ast node represents SWITCH block.variable
- Variable which is checked for content in block.- Returns:
- If variable usage is met only inside the block (not in its declaration!) than return the first Ast node of this block, otherwise - null.
-
getFirstNodeInsideTryCatchFinallyBlocks
private static DetailAST getFirstNodeInsideTryCatchFinallyBlocks(DetailAST block, DetailAST variable)
Gets first Ast node inside TRY-CATCH-FINALLY blocks if variable usage is met only inside the block (not in its declaration!).- Parameters:
block
- Ast node represents TRY-CATCH-FINALLY block.variable
- Variable which is checked for content in block.- Returns:
- If variable usage is met only inside the block (not in its declaration!) than return the first Ast node of this block, otherwise - null.
-
isVariableInOperatorExpr
private static boolean isVariableInOperatorExpr(DetailAST operator, DetailAST variable)
Checks if variable is in operator declaration. For instance:boolean b = true; if (b) {...}
Variable 'b' is in declaration of operator IF.- Parameters:
operator
- Ast node which represents operator.variable
- Variable which is checked for content in operator.- Returns:
- true if operator contains variable in its declaration, otherwise - false.
-
isChild
private static boolean isChild(DetailAST parent, DetailAST ast)
Checks if Ast node contains given element.- Parameters:
parent
- Node of AST.ast
- Ast element which is checked for content in Ast node.- Returns:
- true if Ast element was found in Ast node, otherwise - false.
-
isVariableMatchesIgnorePattern
private boolean isVariableMatchesIgnorePattern(java.lang.String variable)
Checks if entrance variable is contained in ignored pattern.- Parameters:
variable
- Variable which is checked for content in ignored pattern.- Returns:
- true if variable was found, otherwise - false.
-
-