Class 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
  • Field Details

  • Constructor Details

  • Method Details

    • getRequiredTokens

      public int[] getRequiredTokens()
      Description copied from class: AbstractCheck
      The tokens that this check must be registered for.
      Specified by:
      getRequiredTokens in class AbstractCheck
      Returns:
      the token set this must be registered for.
      See Also:
    • 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 class AbstractCheck
      Returns:
      the default tokens
      See Also:
    • 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 class AbstractCheck
      Returns:
      the token set this check is designed for.
      See Also:
    • visitToken

      public void visitToken(DetailAST ast)
      Description copied from class: AbstractCheck
      Called to process a token.
      Overrides:
      visitToken in class AbstractCheck
      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

      private static List<DetailAST> getStatementsInExtendedScope(DetailAST conditionalStatement)
      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

      @Nullable private static DetailAST shiftToNextTraversedBranch(DetailAST ast, DetailAST boundAst)
      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

      @Nullable private static DetailAST getMatchedAssignToken(DetailAST preAssignBranch)
      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

      private static DetailAST getNeededAssignIdent(DetailAST assignToken)
      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 variable
      reassignedVariableIdents - list of AST idents that represent reassigned variables
    • findReassignmentScopeRoot

      @Nullable private static DetailAST findReassignmentScopeRoot(DetailAST ast)
      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 null if none is found
    • expandReassignmentScopes

      private static List<DetailAST> expandReassignmentScopes(DetailAST scopeRoot)
      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 / else statements, 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

      private static void addBodyBranch(Collection<DetailAST> branches, DetailAST scopeRoot)
      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 to
      scopeRoot - the if/else AST node