Class InnerAssignmentCheck
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.InnerAssignmentCheck
- All Implemented Interfaces:
Configurable
,Contextualizable
Checks for assignments in subexpressions, such as in
String s = Integer.toString(i = 2);
.
Rationale: Except for the loop idioms, all assignments should occur in their own top-level statement to increase readability. With inner assignments like the one given above, it is difficult to see all places where a variable is set.
Note: Check allows usage of the popular assignments in loops:
String line; while ((line = bufferedReader.readLine()) != null) { // OK // process the line } for (;(line = bufferedReader.readLine()) != null;) { // OK // process the line } do { // process the line } while ((line = bufferedReader.readLine()) != null); // OK
Assignment inside a condition is not a problem here, as the assignment is surrounded
by an extra pair of parentheses. The comparison is != null
and there is no chance that
intention was to write line == reader.readLine()
.
Parent is com.puppycrawl.tools.checkstyle.TreeWalker
Violation Message Keys:
-
assignment.inner.avoid
- Since:
- 3.0
-
Nested Class Summary
Nested classes/interfaces inherited from class com.puppycrawl.tools.checkstyle.AbstractAutomaticBean
AbstractAutomaticBean.OutputStreamOptions
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate static final int[][]
Allowed AST types from an assignment AST node towards the root.private static final int[][]
Allowed AST types from a comparison node (above an assignment) towards the root.private static final BitSet
The token types that identify comparison operators.private static final int[][]
Allowed AST types from an assignment AST node towards the root.private static final BitSet
The token types that are ignored while checking "loop-idiom".static final String
A key is pointing to the warning message text in "messages.properties" file. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionint[]
The configurable token set.int[]
Returns the default token a check is interested in.private static DetailAST
Get ast parent, ignoring token types fromskipTokens
.int[]
The tokens that this check must be registered for.private static boolean
isComparison
(DetailAST ast) Checks if an AST is a comparison operator.private static boolean
isInContext
(DetailAST ast, int[][] contextSet, BitSet skipTokens) Tests whether the provided AST is in one of the given contexts.private static boolean
isInLoopIdiom
(DetailAST ast) Tests whether the given AST is used in the "assignment in loop" idiom.private static boolean
Determines if ast is in the body of a flow control statement without braces.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, leaveToken, 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 Details
-
MSG_KEY
A key is pointing to the warning message text in "messages.properties" file.- See Also:
-
ALLOWED_ASSIGNMENT_CONTEXT
Allowed AST types from an assignment AST node towards the root. -
CONTROL_CONTEXT
Allowed AST types from an assignment AST node towards the root. -
ALLOWED_ASSIGNMENT_IN_COMPARISON_CONTEXT
Allowed AST types from a comparison node (above an assignment) towards the root. -
COMPARISON_TYPES
The token types that identify comparison operators. -
LOOP_IDIOM_IGNORED_PARENTS
The token types that are ignored while checking "loop-idiom".
-
-
Constructor Details
-
InnerAssignmentCheck
public InnerAssignmentCheck()
-
-
Method Details
-
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:
-
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:
-
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:
-
visitToken
Description copied from class:AbstractCheck
Called to process a token.- Overrides:
visitToken
in classAbstractCheck
- Parameters:
ast
- the token to process
-
isInNoBraceControlStatement
Determines if ast is in the body of a flow control statement without braces. An example of such a statement would beif (y < 0) x = y;
This leads to the following AST structure:
LITERAL_IF LPAREN EXPR // test RPAREN EXPR // body SEMI
We need to ensure that ast is in the body and not in the test.
- Parameters:
ast
- an assignment operator AST- Returns:
- whether ast is in the body of a flow control statement
-
isInLoopIdiom
Tests whether the given AST is used in the "assignment in loop" idiom.String line; while ((line = bufferedReader.readLine()) != null) { // process the line } for (;(line = bufferedReader.readLine()) != null;) { // process the line } do { // process the line } while ((line = bufferedReader.readLine()) != null);
Assignment inside a condition is not a problem here, as the assignment is surrounded by an extra pair of parentheses. The comparison is!= null
and there is no chance that intention was to writeline == reader.readLine()
.- Parameters:
ast
- assignment AST- Returns:
- whether the context of the assignment AST indicates the idiom
-
isComparison
Checks if an AST is a comparison operator.- Parameters:
ast
- the AST to check- Returns:
- true iff ast is a comparison operator.
-
isInContext
Tests whether the provided AST is in one of the given contexts.- Parameters:
ast
- the AST from which to start walking towards rootcontextSet
- the contexts to test against.skipTokens
- parent token types to ignore- Returns:
- whether the parents nodes of ast match one of the allowed type paths.
-
getParent
Get ast parent, ignoring token types fromskipTokens
.- Parameters:
ast
- token to get parentskipTokens
- token types to skip- Returns:
- first not ignored parent of ast
-