public final class ModifiedControlVariableCheck extends AbstractCheck
Checks that for loop control variables are not modified inside the for block. An example is:
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. See FOR statement specification for more details.
Such loop would be suppressed:
for (int i = 0; i < 10;) {
i++;
}
NOTE:The check works with only primitive type variables. The check will not work for arrays used as control variable.An example is
for (int a[]={0};a[0] < 10;a[0]++) {
a[0]++; // it will skip this violation
}
skipEnhancedForLoopVariable - Control whether to check
enhanced for-loop variable.
Type is boolean.
Default value is false.
To configure the check:
<module name="ModifiedControlVariable"/>
Example:
for(int i=0;i < 8;i++) {
i++; // violation, control variable modified
}
String args1[]={"Coding", "block"};
for (String arg: args1) {
arg = arg.trim(); // violation, control variable modified
}
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(int i=0;i < 8;i++) {
i++; // violation, control variable modified
}
String args1[]={"Coding", "block"};
for (String arg: args1) {
arg = arg.trim(); // ok
}
Parent is com.puppycrawl.tools.checkstyle.TreeWalker
Violation Message Keys:
modified.control.variable
AutomaticBean.OutputStreamOptions| 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
Control whether to check
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)
Setter to control whether to check
enhanced for-loop variable.
|
void |
visitToken(DetailAST ast)
Called to process a token.
|
clearViolations, destroy, finishTree, getFileContents, getLine, getLineCodePoints, getLines, getTabWidth, getTokenNames, getViolations, init, isCommentNodesRequired, log, log, log, setFileContents, setTabWidth, setTokensfinishLocalSetup, getCustomMessages, getId, getMessageBundle, getSeverity, getSeverityLevel, setId, setSeverityconfigure, contextualize, getConfiguration, setupChildpublic 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 ModifiedControlVariableCheck()
public void setSkipEnhancedForLoopVariable(boolean skipEnhancedForLoopVariable)
skipEnhancedForLoopVariable - whether to skip enhanced for-loop variablepublic int[] getDefaultTokens()
AbstractCheckgetDefaultTokens in class AbstractCheckTokenTypespublic int[] getRequiredTokens()
AbstractCheckgetRequiredTokens in class AbstractCheckTokenTypespublic int[] getAcceptableTokens()
AbstractCheckgetAcceptableTokens in class AbstractCheckTokenTypespublic void beginTree(DetailAST rootAST)
AbstractCheckbeginTree in class AbstractCheckrootAST - the root of the treepublic void visitToken(DetailAST ast)
AbstractCheckvisitToken in class AbstractCheckast - the token to processpublic void leaveToken(DetailAST ast)
AbstractCheckleaveToken in class AbstractCheckast - 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)private static java.util.List<DetailAST> findChildrenOfExpressionType(DetailAST ast)
ast - parent of expressions to findCopyright © 2001-2022. All Rights Reserved.