View Javadoc

    1   package net.sourceforge.pmd.lang.java.rule;
    2
    3   import java.util.List;
    4
    5   import net.sourceforge.pmd.lang.ast.Node;
    6   import net.sourceforge.pmd.lang.java.ast.ASTEqualityExpression;
    7   import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
    8   import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType;
    9   import net.sourceforge.pmd.lang.java.ast.ASTRelationalExpression;
    10  import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
    11  import net.sourceforge.pmd.lang.java.symboltable.NameOccurrence;
    12
    13  /**
    14   * This is an abstract rule for patterns which compare a method invocation to 0.
    15   * It could be further abstracted to find code that compares something to
    16   * another definable pattern
    17   *
    18   * @author acaplan
    19   */
    20  public abstract class AbstractInefficientZeroCheck extends AbstractJavaRule {
    21
    22      public abstract boolean appliesToClassName(String name);
    23
    24      public abstract boolean isTargetMethod(NameOccurrence occ);
    25
    26      public Object visit(ASTVariableDeclaratorId node, Object data) {
    27  	Node nameNode = node.getTypeNameNode();
    28          if (nameNode instanceof ASTPrimitiveType) {
    29              return data;
    30          }
    31          if (!appliesToClassName(node.getNameDeclaration().getTypeImage())) {
    32              return data;
    33          }
    34
    35          List<NameOccurrence> declars = node.getUsages();
    36          for (NameOccurrence occ: declars) {
    37              if (!isTargetMethod(occ)) {
    38                  continue;
    39              }
    40              Node expr = occ.getLocation().jjtGetParent().jjtGetParent().jjtGetParent();
    41              if ((expr instanceof ASTEqualityExpression ||
    42                      (expr instanceof ASTRelationalExpression && ">".equals(expr.getImage())))
    43                  && isCompareZero(expr)) {
    44                  addViolation(data, occ.getLocation());
    45              }
    46          }
    47          return data;
    48      }
    49
    50      /**
    51       * We only need to report if this is comparing against 0
    52       *
    53       * @param equality
    54       * @return true if this is comparing to 0 else false
    55       */
    56      private boolean isCompareZero(Node equality) {
    57          return checkComparison(equality, 0) || checkComparison(equality, 1);
    58
    59      }
    60
    61      /**
    62       * Checks if the equality expression passed in is of comparing against the
    63       * value passed in as i
    64       *
    65       * @param equality
    66       * @param i
    67       *            The ordinal in the equality expression to check
    68       * @return true if the value in position i is 0, else false
    69       */
    70      private boolean checkComparison(Node equality, int i) {
    71  	Node target = equality.jjtGetChild(i).jjtGetChild(0);
    72          if (target.jjtGetNumChildren() == 0) {
    73              return false;
    74          }
    75          target = target.jjtGetChild(0);
    76          return target instanceof ASTLiteral && "0".equals(target.getImage());
    77      }
    78
    79  }