Class ClassHeaderWrapOpenjdkCheck

All Implemented Interfaces:
Configurable, Contextualizable

Checks that a wrapped class, interface, enum, or record header is wrapped according to the OpenJDK Java Style Guide.

This check only applies when the type declaration header, from the declaration keyword through the end of its extends/implements clauses (or its name/type parameters/record components when neither clause is present), spans more than one line. A header whose content is entirely on one line is not in scope, even if its opening curly brace is pushed onto its own following line; that is a brace placement choice for other checks (such as LeftCurly) to enforce, not a wrapping concern this check is about.

The two rules enforced are:

  1. Each of the extends and implements clauses, when present, must stand out on its own new line once the header has started wrapping, or once that clause's own list of supertypes wraps across lines. Wrapping that happens only inside a single supertype's type arguments (the same way method arguments may wrap) does not require the clause keyword itself to move to a new line.
  2. Only checked when rule 1 above found nothing to report: the header should not have been wrapped in the first place if, joined back onto one line, it would still fit within 80 columns.
Since:
14.4.0
  • Field Details

  • Constructor Details

  • Method Details

    • 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:
    • 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:
    • 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
    • isClauseMisplaced

      private boolean isClauseMisplaced(@Nullable DetailAST clause)
      Checks the given clause's placement if it is present.
      Parameters:
      clause - the EXTENDS_CLAUSE or IMPLEMENTS_CLAUSE to check, or null if the type declaration has none
      Returns:
      true if a violation was logged for this clause
    • findHeaderStart

      private static DetailAST findHeaderStart(DetailAST ast)
      Finds the token that marks the true start of the header on the declaration's own line: the first modifier that already shares a line with the declaration keyword (class/interface/enum/record), skipping past any annotations placed on their own preceding line, or the declaration keyword itself if there is no such modifier.
      Parameters:
      ast - the class, interface, enum, or record declaration
      Returns:
      the token that starts the header
    • checkClausePlacement

      private boolean checkClausePlacement(DetailAST clause)
      Checks that the given extends/implements clause stands out on its own new line, if required. It is required once a preceding extends clause has already achieved its own new line (so implements must match it), or once this clause's own list of supertypes wraps across multiple lines. Wrapping in whatever precedes the clause for some other reason, such as a wrapped type parameter or record component list, does not by itself require the clause to move.
      Parameters:
      clause - the EXTENDS_CLAUSE or IMPLEMENTS_CLAUSE to check
      Returns:
      true if a violation was logged for this clause
    • isPrecededByWrappedClause

      private static boolean isPrecededByWrappedClause(DetailAST previous)
      Checks whether the given node is an EXTENDS_CLAUSE that already stands out on its own new line, meaning a following implements clause must match it.
      Parameters:
      previous - the node immediately preceding the clause under check
      Returns:
      true if previous is an EXTENDS_CLAUSE that does not share a line with whatever precedes it
    • checkNecessaryWrap

      private void checkNecessaryWrap(DetailAST headerStart, DetailAST lcurly)
      Checks whether the header, reconstructed as a single line, would still have fit within the maximum column limit, in which case wrapping it was unnecessary.
      Parameters:
      headerStart - the declaration keyword (class/interface/ enum/record) that starts the header
      lcurly - the opening brace of the type's body
    • findFromIndex

      private static int findFromIndex(DetailAST headerStart, int lineNo)
      Finds the index at which the given line's relevant content starts: the header's own starting column on the header's first line, or the start of the line otherwise.
      Parameters:
      headerStart - the token that starts the header
      lineNo - the 1-indexed line number currently being processed
      Returns:
      the index at which to start extracting content from this line
    • findToIndex

      private static int findToIndex(DetailAST lcurly, int lineNo, int lineLength)
      Finds the index at which the given line's relevant content ends: just past the opening curly brace on the line it occupies, or the end of the line otherwise.
      Parameters:
      lcurly - the opening brace of the type's body
      lineNo - the 1-indexed line number currently being processed
      lineLength - the length of the line currently being processed
      Returns:
      the index at which to stop extracting content from this line
    • isTopLevelWrapped

      private static boolean isTopLevelWrapped(DetailAST clause)
      Checks whether the given node's direct children span more than one source line, ignoring further wrapping nested inside any of those children (e.g. inside a supertype's own type arguments).
      Parameters:
      clause - the EXTENDS_CLAUSE or IMPLEMENTS_CLAUSE to inspect
      Returns:
      true if two direct children of clause start on different lines
    • getEndLineNo

      private static int getEndLineNo(DetailAST ast)
      Returns the line number of the last token in the given subtree.
      Parameters:
      ast - the root of the subtree to inspect
      Returns:
      the 1-indexed line number of the deepest last child of ast