View Javadoc

    1   /**
    2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
    3    */
    4   package net.sourceforge.pmd.rules.design;
    5
    6   import net.sourceforge.pmd.AbstractRule;
    7   import net.sourceforge.pmd.ast.ASTAssignmentOperator;
    8   import net.sourceforge.pmd.ast.ASTConditionalExpression;
    9   import net.sourceforge.pmd.ast.ASTEqualityExpression;
    10  import net.sourceforge.pmd.ast.ASTExpression;
    11  import net.sourceforge.pmd.ast.ASTName;
    12  import net.sourceforge.pmd.ast.ASTNullLiteral;
    13  import net.sourceforge.pmd.ast.ASTStatementExpression;
    14  import net.sourceforge.pmd.symboltable.VariableNameDeclaration;
    15
    16  // TODO - should check that this is not the first assignment.  e.g., this is OK:
    17  // Object x;
    18  // x = null;
    19  public class NullAssignmentRule extends AbstractRule {
    20
    21      public Object visit(ASTNullLiteral node, Object data) {
    22
    23          if (node.getNthParent(5) instanceof ASTStatementExpression) {
    24              ASTStatementExpression n = (ASTStatementExpression) node.getNthParent(5);
    25
    26              if (isAssignmentToFinalField(n)) {
    27                  return data;
    28              }
    29
    30              if (n.jjtGetNumChildren() > 2 && n.jjtGetChild(1) instanceof ASTAssignmentOperator) {
    31                  addViolation(data, node);
    32              }
    33          } else if (node.getNthParent(4) instanceof ASTConditionalExpression) {
    34              // "false" expression of ternary
    35              if (isBadTernary((ASTConditionalExpression)node.getNthParent(4))) {
    36                  addViolation(data, node);
    37              }
    38          } else if (node.getNthParent(5) instanceof ASTConditionalExpression && node.getNthParent(4) instanceof ASTExpression) {
    39              // "true" expression of ternary
    40              if (isBadTernary((ASTConditionalExpression)node.getNthParent(5))) {
    41                  addViolation(data, node);
    42              }
    43          }
    44
    45          return data;
    46      }
    47
    48      private boolean isAssignmentToFinalField(ASTStatementExpression n) {
    49          ASTName name = n.getFirstChildOfType(ASTName.class);
    50          return name != null
    51                  && name.getNameDeclaration() instanceof VariableNameDeclaration
    52                  && ((VariableNameDeclaration) name.getNameDeclaration()).getAccessNodeParent().isFinal();
    53      }
    54
    55      private boolean isBadTernary(ASTConditionalExpression n) {
    56          return n.isTernary() && !(n.jjtGetChild(0) instanceof ASTEqualityExpression);
    57      }
    58  }