Class DescendantTokenCheck

  • All Implemented Interfaces:
    Configurable, Contextualizable

    public class DescendantTokenCheck
    extends AbstractCheck

    Checks for restricted tokens beneath other tokens.

    Examples of how to configure the check:

     <!-- String literal equality check -->
     <module name="DescendantToken">
         <property name="tokens" value="EQUAL,NOT_EQUAL"/>
         <property name="limitedTokens" value="STRING_LITERAL"/>
         <property name="maximumNumber" value="0"/>
         <property name="maximumDepth" value="1"/>
     </module>
    
     <!-- Switch with no default -->
     <module name="DescendantToken">
         <property name="tokens" value="LITERAL_SWITCH"/>
         <property name="maximumDepth" value="2"/>
         <property name="limitedTokens" value="LITERAL_DEFAULT"/>
         <property name="minimumNumber" value="1"/>
     </module>
    
     <!-- Assert statement may have side effects -->
     <module name="DescendantToken">
         <property name="tokens" value="LITERAL_ASSERT"/>
         <property name="limitedTokens" value="ASSIGN,DEC,INC,POST_DEC,
         POST_INC,PLUS_ASSIGN,MINUS_ASSIGN,STAR_ASSIGN,DIV_ASSIGN,MOD_ASSIGN,
         BSR_ASSIGN,SR_ASSIGN,SL_ASSIGN,BAND_ASSIGN,BXOR_ASSIGN,BOR_ASSIGN,
         METHOD_CALL"/>
         <property name="maximumNumber" value="0"/>
     </module>
    
     <!-- Initializer in for performs no setup - use while instead? -->
     <module name="DescendantToken">
         <property name="tokens" value="FOR_INIT"/>
         <property name="limitedTokens" value="EXPR"/>
         <property name="minimumNumber" value="1"/>
     </module>
    
     <!-- Condition in for performs no check -->
     <module name="DescendantToken">
         <property name="tokens" value="FOR_CONDITION"/>
         <property name="limitedTokens" value="EXPR"/>
         <property name="minimumNumber" value="1"/>
     </module>
    
     <!-- Switch within switch -->
     <module name="DescendantToken">
         <property name="tokens" value="LITERAL_SWITCH"/>
         <property name="limitedTokens" value="LITERAL_SWITCH"/>
         <property name="maximumNumber" value="0"/>
         <property name="minimumDepth" value="1"/>
     </module>
    
     <!-- Return from within a catch or finally block -->
     <module name="DescendantToken">
         <property name="tokens" value="LITERAL_FINALLY,LITERAL_CATCH"/>
         <property name="limitedTokens" value="LITERAL_RETURN"/>
         <property name="maximumNumber" value="0"/>
     </module>
    
     <!-- Try within catch or finally block -->
     <module name="DescendantToken">
         <property name="tokens" value="LITERAL_CATCH,LITERAL_FINALLY"/>
         <property name="limitedTokens" value="LITERAL_TRY"/>
         <property name="maximumNumber" value="0"/>
     </module>
    
     <!-- Too many cases within a switch -->
     <module name="DescendantToken">
         <property name="tokens" value="LITERAL_SWITCH"/>
         <property name="limitedTokens" value="LITERAL_CASE"/>
         <property name="maximumDepth" value="2"/>
         <property name="maximumNumber" value="10"/>
     </module>
    
     <!-- Too many local variables within a method -->
     <module name="DescendantToken">
         <property name="tokens" value="METHOD_DEF"/>
         <property name="limitedTokens" value="VARIABLE_DEF"/>
         <property name="maximumDepth" value="2"/>
         <property name="maximumNumber" value="10"/>
     </module>
    
     <!-- Too many returns from within a method -->
     <module name="DescendantToken">
         <property name="tokens" value="METHOD_DEF"/>
         <property name="limitedTokens" value="LITERAL_RETURN"/>
         <property name="maximumNumber" value="3"/>
     </module>
    
     <!-- Too many fields within an interface -->
     <module name="DescendantToken">
         <property name="tokens" value="INTERFACE_DEF"/>
         <property name="limitedTokens" value="VARIABLE_DEF"/>
         <property name="maximumDepth" value="2"/>
         <property name="maximumNumber" value="0"/>
     </module>
    
     <!-- Limit the number of exceptions a method can throw -->
     <module name="DescendantToken">
         <property name="tokens" value="LITERAL_THROWS"/>
         <property name="limitedTokens" value="IDENT"/>
         <property name="maximumNumber" value="1"/>
     </module>
    
     <!-- Limit the number of expressions in a method -->
     <module name="DescendantToken">
         <property name="tokens" value="METHOD_DEF"/>
         <property name="limitedTokens" value="EXPR"/>
         <property name="maximumNumber" value="200"/>
     </module>
    
     <!-- Disallow empty statements -->
     <module name="DescendantToken">
         <property name="tokens" value="EMPTY_STAT"/>
         <property name="limitedTokens" value="EMPTY_STAT"/>
         <property name="maximumNumber" value="0"/>
         <property name="maximumDepth" value="0"/>
         <property name="maximumMessage"
             value="Empty statement is not allowed."/>
     </module>
    
     <!-- Too many fields within a class -->
     <module name="DescendantToken">
         <property name="tokens" value="CLASS_DEF"/>
         <property name="limitedTokens" value="VARIABLE_DEF"/>
         <property name="maximumDepth" value="2"/>
         <property name="maximumNumber" value="10"/>
     </module>
     
    • Field Detail

      • MSG_KEY_MIN

        public static final java.lang.String MSG_KEY_MIN
        A key is pointing to the warning message text in "messages.properties" file.
        See Also:
        Constant Field Values
      • MSG_KEY_MAX

        public static final java.lang.String MSG_KEY_MAX
        A key is pointing to the warning message text in "messages.properties" file.
        See Also:
        Constant Field Values
      • MSG_KEY_SUM_MIN

        public static final java.lang.String MSG_KEY_SUM_MIN
        A key is pointing to the warning message text in "messages.properties" file.
        See Also:
        Constant Field Values
      • MSG_KEY_SUM_MAX

        public static final java.lang.String MSG_KEY_SUM_MAX
        A key is pointing to the warning message text in "messages.properties" file.
        See Also:
        Constant Field Values
      • minimumDepth

        private int minimumDepth
        Minimum depth.
      • maximumDepth

        private int maximumDepth
        Maximum depth.
      • minimumNumber

        private int minimumNumber
        Minimum number.
      • maximumNumber

        private int maximumNumber
        Maximum number.
      • sumTokenCounts

        private boolean sumTokenCounts
        Whether to sum the number of tokens found.
      • limitedTokens

        private int[] limitedTokens
        Limited tokens.
      • minimumMessage

        private java.lang.String minimumMessage
        Error message when minimum count not reached.
      • maximumMessage

        private java.lang.String maximumMessage
        Error message when maximum count exceeded.
      • counts

        private int[] counts
        Counts of descendant tokens. Indexed by (token ID - 1) for performance.
    • Constructor Detail

      • DescendantTokenCheck

        public DescendantTokenCheck()
    • Method Detail

      • 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:
        TokenTypes
      • 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:
        TokenTypes
      • logAsSeparated

        private void logAsSeparated​(DetailAST ast)
        Log violations for each Token.
        Parameters:
        ast - token
      • logAsTotal

        private void logAsTotal​(DetailAST ast)
        Log validation as one violation.
        Parameters:
        ast - current token
      • countTokens

        private void countTokens​(antlr.collections.AST ast,
                                 int depth)
        Counts the number of occurrences of descendant tokens.
        Parameters:
        ast - the root token for descendants.
        depth - the maximum depth of the counted descendants.
      • 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:
        TokenTypes
      • setLimitedTokens

        public void setLimitedTokens​(java.lang.String... limitedTokensParam)
        Sets the tokens which occurrence as descendant is limited.
        Parameters:
        limitedTokensParam - - list of tokens to ignore.
      • setMinimumDepth

        public void setMinimumDepth​(int minimumDepth)
        Sets the minimum depth for descendant counts.
        Parameters:
        minimumDepth - the minimum depth for descendant counts.
      • setMaximumDepth

        public void setMaximumDepth​(int maximumDepth)
        Sets the maximum depth for descendant counts.
        Parameters:
        maximumDepth - the maximum depth for descendant counts.
      • setMinimumNumber

        public void setMinimumNumber​(int minimumNumber)
        Sets a minimum count for descendants.
        Parameters:
        minimumNumber - the minimum count for descendants.
      • setMaximumNumber

        public void setMaximumNumber​(int maximumNumber)
        Sets a maximum count for descendants.
        Parameters:
        maximumNumber - the maximum count for descendants.
      • setMinimumMessage

        public void setMinimumMessage​(java.lang.String message)
        Sets the error message for minimum count not reached.
        Parameters:
        message - the error message for minimum count not reached. Used as a MessageFormat pattern with arguments
        • {0} - token count
        • {1} - minimum number
        • {2} - name of token
        • {3} - name of limited token
      • setMaximumMessage

        public void setMaximumMessage​(java.lang.String message)
        Sets the error message for maximum count exceeded.
        Parameters:
        message - the error message for maximum count exceeded. Used as a MessageFormat pattern with arguments
        • {0} - token count
        • {1} - maximum number
        • {2} - name of token
        • {3} - name of limited token
      • setSumTokenCounts

        public void setSumTokenCounts​(boolean sum)
        Sets whether to use the sum of the tokens found, rather than the individual counts.
        Parameters:
        sum - whether to use the sum.