Class EqualsAvoidNullCheck

  • All Implemented Interfaces:
    Configurable, Contextualizable

    public class EqualsAvoidNullCheck
    extends AbstractCheck
    Checks that any combination of String literals is on the left side of an equals() comparison. Also checks for String literals assigned to some field (such as someString.equals(anotherString = "text")).

    Rationale: Calling the equals() method on String literals will avoid a potential NullPointerException. Also, it is pretty common to see null check right before equals comparisons which is not necessary in the below example.

    For example:

      
        String nullString = null;
        nullString.equals("My_Sweet_String");
      
     
    should be refactored to
      
        String nullString = null;
        "My_Sweet_String".equals(nullString);
      
     
    • Field Detail

      • MSG_EQUALS_AVOID_NULL

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

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

        private static final java.lang.String EQUALS
        Method name for comparison.
        See Also:
        Constant Field Values
      • STRING

        private static final java.lang.String STRING
        Type name for comparison.
        See Also:
        Constant Field Values
      • ignoreEqualsIgnoreCase

        private boolean ignoreEqualsIgnoreCase
        Whether to process equalsIgnoreCase() invocations.
    • Constructor Detail

      • EqualsAvoidNullCheck

        public EqualsAvoidNullCheck()
    • 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
      • 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
      • 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
      • setIgnoreEqualsIgnoreCase

        public void setIgnoreEqualsIgnoreCase​(boolean newValue)
        Whether to ignore checking String.equalsIgnoreCase(String).
        Parameters:
        newValue - whether to ignore checking String.equalsIgnoreCase(String).
      • beginTree

        public void beginTree​(DetailAST rootAST)
        Description copied from class: AbstractCheck
        Called before the starting to process a tree. Ideal place to initialize information that is to be collected whilst processing a tree.
        Overrides:
        beginTree in class AbstractCheck
        Parameters:
        rootAST - the root of the tree
      • leaveToken

        public void leaveToken​(DetailAST ast)
        Description copied from class: AbstractCheck
        Called after all the child nodes have been process.
        Overrides:
        leaveToken in class AbstractCheck
        Parameters:
        ast - the token leaving
      • finishTree

        public void finishTree​(DetailAST ast)
        Description copied from class: AbstractCheck
        Called after finished processing a tree. Ideal place to report on information collected whilst processing a tree.
        Overrides:
        finishTree in class AbstractCheck
        Parameters:
        ast - the root of the tree
      • processSlist

        private void processSlist​(DetailAST ast)
        Determine whether SLIST begins static or non-static block and add it as a frame in this case.
        Parameters:
        ast - SLIST ast.
      • leaveSlist

        private void leaveSlist​(DetailAST ast)
        Determine whether SLIST begins static or non-static block.
        Parameters:
        ast - SLIST ast.
      • processFrame

        private void processFrame​(DetailAST ast)
        Process CLASS_DEF, METHOD_DEF, LITERAL_IF, LITERAL_FOR, LITERAL_WHILE, LITERAL_DO, LITERAL_CATCH, LITERAL_TRY, CTOR_DEF, ENUM_DEF, ENUM_CONSTANT_DEF.
        Parameters:
        ast - processed ast.
      • processMethodCall

        private void processMethodCall​(DetailAST methodCall)
        Add the method call to the current frame if it should be processed.
        Parameters:
        methodCall - METHOD_CALL ast.
      • processLiteralNew

        private void processLiteralNew​(DetailAST ast)
        Determine whether LITERAL_NEW is an anonymous class definition and add it as a frame in this case.
        Parameters:
        ast - LITERAL_NEW ast.
      • traverseFieldFrameTree

        private void traverseFieldFrameTree​(EqualsAvoidNullCheck.FieldFrame frame)
        Traverse the tree of the field frames to check all equals method calls.
        Parameters:
        frame - to check method calls in.
      • checkMethodCall

        private void checkMethodCall​(DetailAST methodCall)
        Check whether the method call should be violated.
        Parameters:
        methodCall - method call to check.
      • isObjectValid

        private static boolean isObjectValid​(DetailAST objCalledOn)
        Check whether the object equals method is called on is not a String literal and not too complex.
        Parameters:
        objCalledOn - the object equals method is called on ast.
        Returns:
        true if the object is valid.
      • isStringLiteral

        private static boolean isStringLiteral​(DetailAST objCalledOn)
        Checks for calling equals on String literal and anon object which cannot be null.
        Parameters:
        objCalledOn - object AST
        Returns:
        if it is string literal
      • containsOneArgument

        private static boolean containsOneArgument​(DetailAST methodCall)
        Verify that method call has one argument.
        Parameters:
        methodCall - METHOD_CALL DetailAST
        Returns:
        true if method call has one argument.
      • containsAllSafeTokens

        private static boolean containsAllSafeTokens​(DetailAST expr)
        Looks for all "safe" Token combinations in the argument expression branch.
        Parameters:
        expr - the argument expression
        Returns:
        - true if any child matches the set of tokens, false if not
      • skipVariableAssign

        private static DetailAST skipVariableAssign​(DetailAST currentAST)
        Skips over an inner assign portion of an argument expression.
        Parameters:
        currentAST - current token in the argument expression
        Returns:
        the next relevant token
      • isCalledOnStringFieldOrVariable

        private boolean isCalledOnStringFieldOrVariable​(DetailAST objCalledOn)
        Determine, whether equals method is called on a field of String type.
        Parameters:
        objCalledOn - object ast.
        Returns:
        true if the object is of String type.
      • isStringFieldOrVariable

        private boolean isStringFieldOrVariable​(DetailAST objCalledOn)
        Whether the field or the variable is of String type.
        Parameters:
        objCalledOn - the field or the variable to check.
        Returns:
        true if the field or the variable is of String type.
      • isStringFieldOrVariableFromThisInstance

        private boolean isStringFieldOrVariableFromThisInstance​(DetailAST objCalledOn)
        Whether the field or the variable from THIS instance is of String type.
        Parameters:
        objCalledOn - the field or the variable from THIS instance to check.
        Returns:
        true if the field or the variable from THIS instance is of String type.
      • isStringFieldOrVariableFromClass

        private boolean isStringFieldOrVariableFromClass​(DetailAST objCalledOn,
                                                         java.lang.String className)
        Whether the field or the variable from the specified class is of String type.
        Parameters:
        objCalledOn - the field or the variable from the specified class to check.
        className - the name of the class to check in.
        Returns:
        true if the field or the variable from the specified class is of String type.
      • getObjectFrame

        private static EqualsAvoidNullCheck.FieldFrame getObjectFrame​(EqualsAvoidNullCheck.FieldFrame frame)
        Get the nearest parent frame which is CLASS_DEF, ENUM_DEF or ENUM_CONST_DEF.
        Parameters:
        frame - to start the search from.
        Returns:
        the nearest parent frame which is CLASS_DEF, ENUM_DEF or ENUM_CONST_DEF.
      • checkLineNo

        private static boolean checkLineNo​(DetailAST field,
                                           DetailAST objCalledOn)
        Check whether the field is declared before the method call in case of methods and initialization blocks.
        Parameters:
        field - field to check.
        objCalledOn - object equals method called on.
        Returns:
        true if the field is declared before the method call.
      • getFieldType

        private static java.lang.String getFieldType​(DetailAST field)
        Get field type.
        Parameters:
        field - to get the type from.
        Returns:
        type of the field.