Class PatternVariableAssignmentCheck
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.PatternVariableAssignmentCheck
- All Implemented Interfaces:
Configurable,Contextualizable
Checks for assignment of pattern variables.
Pattern variable assignment is considered bad programming practice. The pattern variable is meant to be a direct reference to the object being matched. Reassigning it can break this connection and mislead readers.
- Since:
- 10.26.0
-
Nested Class Summary
Nested classes/interfaces inherited from class com.puppycrawl.tools.checkstyle.AbstractAutomaticBean
AbstractAutomaticBean.OutputStreamOptions -
Field Summary
FieldsModifier and TypeFieldDescriptionThe set of all valid types of ASSIGN token for this check.static final StringA key is pointing to the warning message in "messages.properties" file. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprivate static voidaddBodyBranch(Collection<DetailAST> branches, DetailAST scopeRoot) Adds the body branch of a conditional (if/else) to the list.private voidcheckForReassignment(DetailAST patternVariableIdent, Iterable<DetailAST> reassignedVariableIdents) Checks whether a pattern variable is reassigned and logs a violation if so.expandReassignmentScopes(DetailAST scopeRoot) Expands the reassignment scope root into concrete AST branches that may contain reassigned pattern variables.private static DetailASTFinds the nearest AST node that defines the scope in which reassignment of a pattern variable may occur.int[]The configurable token set.int[]Returns the default token a check is interested in.private static DetailASTgetMatchedAssignToken(DetailAST preAssignBranch) Gets the type of ASSIGN tokens that particularly matches with what follows the preceding branch.private static DetailASTgetNeededAssignIdent(DetailAST assignToken) Gets the needed AST Ident of reassigned variable for check to compare.Gets the list of all pattern variable idents in instanceof expression.Gets the list of AST branches of reassigned variable identifiers.int[]The tokens that this check must be registered for.getStatementsInExtendedScope(DetailAST conditionalStatement) Gets statements that follow the conditional where pattern variable scope extends.private static DetailASTshiftToNextTraversedBranch(DetailAST ast, DetailAST boundAst) Shifts once to the next possible branch within traverse trajectory.private static DetailASTtraverseUntilNeededBranchType(DetailAST startingBranch, DetailAST bound, int neededTokenType) Traverses along the AST tree to locate the first branch of certain token type.voidvisitToken(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, setTokensMethods inherited from class com.puppycrawl.tools.checkstyle.api.AbstractViolationReporter
finishLocalSetup, getCustomMessages, getId, getMessageBundle, getSeverity, getSeverityLevel, setId, setSeverityMethods inherited from class com.puppycrawl.tools.checkstyle.AbstractAutomaticBean
configure, contextualize, getConfiguration, setupChild
-
Field Details
-
MSG_KEY
A key is pointing to the warning message in "messages.properties" file.- See Also:
-
ASSIGN_TOKEN_TYPES
The set of all valid types of ASSIGN token for this check.
-
-
Constructor Details
-
PatternVariableAssignmentCheck
public PatternVariableAssignmentCheck()
-
-
Method Details
-
getRequiredTokens
Description copied from class:AbstractCheckThe tokens that this check must be registered for.- Specified by:
getRequiredTokensin classAbstractCheck- Returns:
- the token set this must be registered for.
- See Also:
-
getDefaultTokens
Description copied from class:AbstractCheckReturns the default token a check is interested in. Only used if the configuration for a check does not define the tokens.- Specified by:
getDefaultTokensin classAbstractCheck- Returns:
- the default tokens
- See Also:
-
getAcceptableTokens
Description copied from class:AbstractCheckThe 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:
getAcceptableTokensin classAbstractCheck- Returns:
- the token set this check is designed for.
- See Also:
-
visitToken
Description copied from class:AbstractCheckCalled to process a token.- Overrides:
visitTokenin classAbstractCheck- Parameters:
ast- the token to process
-
getPatternVariableIdents
Gets the list of all pattern variable idents in instanceof expression.- Parameters:
ast- ast tree of instanceof to get the list from.- Returns:
- list of pattern variables.
-
getReassignedVariableIdents
Gets the list of AST branches of reassigned variable identifiers.- Parameters:
ast- ast tree of checked instanceof statement- Returns:
- list of AST identifiers that represent reassigned variables
-
getStatementsInExtendedScope
Gets statements that follow the conditional where pattern variable scope extends. Only returns top-level statements that are siblings of the conditional, excluding statements nested in control structures like while loops.- Parameters:
conditionalStatement- The if statement.- Returns:
- List of statement nodes in the extended scope.
-
traverseUntilNeededBranchType
@Nullable private static DetailAST traverseUntilNeededBranchType(DetailAST startingBranch, DetailAST bound, int neededTokenType) Traverses along the AST tree to locate the first branch of certain token type.- Parameters:
startingBranch- AST branch to start the traverse from, but not check.bound- AST Branch that the traverse cannot further extend to.neededTokenType- Token type whose first encountered branch is to look for.- Returns:
- the AST tree of first encountered branch of needed token type.
-
shiftToNextTraversedBranch
Shifts once to the next possible branch within traverse trajectory.- Parameters:
ast- AST branch to shift from.boundAst- AST Branch that the traverse cannot further extend to.- Returns:
- the AST tree of next possible branch within traverse trajectory.
-
getMatchedAssignToken
Gets the type of ASSIGN tokens that particularly matches with what follows the preceding branch.- Parameters:
preAssignBranch- branch that precedes the branch of ASSIGN token types.- Returns:
- type of ASSIGN token.
-
getNeededAssignIdent
Gets the needed AST Ident of reassigned variable for check to compare.- Parameters:
assignToken- The AST branch of reassigned variable's ASSIGN token.- Returns:
- needed AST Ident.
-
checkForReassignment
private void checkForReassignment(DetailAST patternVariableIdent, Iterable<DetailAST> reassignedVariableIdents) Checks whether a pattern variable is reassigned and logs a violation if so.- Parameters:
patternVariableIdent- AST ident of the pattern variablereassignedVariableIdents- list of AST idents that represent reassigned variables
-
findReassignmentScopeRoot
Finds the nearest AST node that defines the scope in which reassignment of a pattern variable may occur.The scope is determined by locating the closest enclosing conditional structure such as
if,else, or ternary operator.- Parameters:
ast- the AST node to start searching from- Returns:
- the AST node representing the reassignment scope root,
or
nullif none is found
-
expandReassignmentScopes
Expands the reassignment scope root into concrete AST branches that may contain reassigned pattern variables.For ternary expressions, the conditional expression itself is treated as the reassignment scope. For
if/elsestatements, the method includes the statement list and any subsequent statements where the pattern variable remains in scope.- Parameters:
scopeRoot- the root AST node of the reassignment scope- Returns:
- list of AST branches that may contain reassignments
-
addBodyBranch
Adds the body branch of a conditional (if/else) to the list. For braced blocks, adds the SLIST. For unbraced statements, adds the single statement directly.- Parameters:
branches- collection to add the body branch toscopeRoot- the if/else AST node
-