public final class ModifiedControlVariableCheck extends AbstractCheck
for (int i = 0; i < 1; i++) {
i++;//violation
}
Rationale: If the control variable is modified inside the loop
body, the program flow becomes more difficult to follow.Examples:
<module name="ModifiedControlVariable"> </module>
Such loop would be suppressed:
for(int i=0; i < 10;) {
i++;
}
By default, This Check validates Enhanced For-Loop.
Option 'skipEnhancedForLoopVariable' could be used to skip check of variable from Enhanced For Loop.
An example of how to configure the check so that it skips enhanced For Loop Variable is:
<module name="ModifiedControlVariable"> <property name="skipEnhancedForLoopVariable" value="true"/> </module>
Example:
for (String line: lines) {
line = line.trim(); // it will skip this violation
}
Modifier and Type | Field and Description |
---|---|
private static java.lang.String |
ILLEGAL_TYPE_OF_TOKEN
Message thrown with IllegalStateException.
|
static java.lang.String |
MSG_KEY
A key is pointing to the warning message text in "messages.properties"
file.
|
private static java.util.Set<java.lang.Integer> |
MUTATION_OPERATIONS
Operations which can change control variable in update part of the loop.
|
private boolean |
skipEnhancedForLoopVariable
Controls whether to skip enhanced for-loop variable.
|
private java.util.Deque<java.util.Deque<java.lang.String>> |
variableStack
Stack of block parameters.
|
Constructor and Description |
---|
ModifiedControlVariableCheck() |
Modifier and Type | Method and Description |
---|---|
void |
beginTree(DetailAST rootAST)
Called before the starting to process a tree.
|
private void |
checkIdent(DetailAST ast)
Check if ident is parameter.
|
private void |
enterBlock()
Enters an inner class, which requires a new variable set.
|
private void |
exitBlock()
Leave an inner class, so restore variable set.
|
private static java.util.List<DetailAST> |
findChildrenOfExpressionType(DetailAST ast)
Find all child of given AST of type TokenType.EXPR
|
int[] |
getAcceptableTokens()
The configurable token set.
|
private java.util.Deque<java.lang.String> |
getCurrentVariables()
Get current variable stack.
|
int[] |
getDefaultTokens()
Returns the default token a check is interested in.
|
private static java.util.Set<java.lang.String> |
getForInitVariables(DetailAST ast)
Get all variables initialized In init part of for loop.
|
private static java.util.Set<java.lang.String> |
getForIteratorVariables(DetailAST ast)
Get all variables which for loop iterating part change in every loop.
|
int[] |
getRequiredTokens()
The tokens that this check must be registered for.
|
private static java.util.Set<java.lang.String> |
getVariablesManagedByForLoop(DetailAST ast)
Determines which variable are specific to for loop and should not be
change by inner loop body.
|
private void |
leaveForDef(DetailAST ast)
Pops the variables from the stack.
|
private void |
leaveForEach(DetailAST paramDef)
Push current variables to the stack.
|
private void |
leaveForIter(DetailAST ast)
Push current variables to the stack.
|
void |
leaveToken(DetailAST ast)
Called after all the child nodes have been process.
|
private void |
popCurrentVariables(int count)
Pops given number of variables from currentVariables.
|
void |
setSkipEnhancedForLoopVariable(boolean skipEnhancedForLoopVariable)
Whether to skip enhanced for-loop variable or not.
|
void |
visitToken(DetailAST ast)
Called to process a token.
|
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 java.lang.String ILLEGAL_TYPE_OF_TOKEN
private static final java.util.Set<java.lang.Integer> MUTATION_OPERATIONS
private final java.util.Deque<java.util.Deque<java.lang.String>> variableStack
private boolean skipEnhancedForLoopVariable
public void setSkipEnhancedForLoopVariable(boolean skipEnhancedForLoopVariable)
skipEnhancedForLoopVariable
- whether to skip enhanced for-loop variablepublic int[] getDefaultTokens()
AbstractCheck
getDefaultTokens
in class AbstractCheck
TokenTypes
public int[] getRequiredTokens()
AbstractCheck
getRequiredTokens
in class AbstractCheck
TokenTypes
public int[] getAcceptableTokens()
AbstractCheck
getAcceptableTokens
in class AbstractCheck
TokenTypes
public void beginTree(DetailAST rootAST)
AbstractCheck
beginTree
in class AbstractCheck
rootAST
- the root of the treepublic 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 enterBlock()
private void exitBlock()
private java.util.Deque<java.lang.String> getCurrentVariables()
private void checkIdent(DetailAST ast)
ast
- ident to check.private void leaveForIter(DetailAST ast)
ast
- a for definition.private static java.util.Set<java.lang.String> getVariablesManagedByForLoop(DetailAST ast)
ast
- For Loopprivate void leaveForEach(DetailAST paramDef)
paramDef
- a for-each clause variableprivate void leaveForDef(DetailAST ast)
ast
- a for definition.private void popCurrentVariables(int count)
count
- Count of variables to be popped from currentVariablesprivate static java.util.Set<java.lang.String> getForInitVariables(DetailAST ast)
ast
- for loop tokenprivate static java.util.Set<java.lang.String> getForIteratorVariables(DetailAST ast)
ast
- for loop literal(TokenTypes.LITERAL_FOR)