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.ASTName;
    11  import net.sourceforge.pmd.ast.ASTNullLiteral;
    12  import net.sourceforge.pmd.ast.ASTStatementExpression;
    13  import net.sourceforge.pmd.symboltable.VariableNameDeclaration;
    14
    15  // Would this be simplified by using DFA somehow?
    16
    17  public class NullAssignmentRule extends AbstractRule {
    18
    19      public Object visit(ASTNullLiteral node, Object data) {
    20          if (node.getNthParent(5) instanceof ASTStatementExpression) {
    21              ASTStatementExpression n = (ASTStatementExpression) node.getNthParent(5);
    22
    23              if (isAssignmentToFinalField(n)) {
    24                  return data;
    25              }
    26
    27              if (n.jjtGetNumChildren() > 2 && n.jjtGetChild(1) instanceof ASTAssignmentOperator) {
    28                  addViolation(data, node);
    29              }
    30          } else if (node.getNthParent(4) instanceof ASTConditionalExpression) {
    31              checkTernary((ASTConditionalExpression) node.getNthParent(4), data, node);
    32          } else if (node.getNthParent(5) instanceof ASTConditionalExpression) {
    33              checkTernary((ASTConditionalExpression) node.getNthParent(5), data, node);
    34          }
    35
    36          return data;
    37      }
    38
    39      private boolean isAssignmentToFinalField(ASTStatementExpression n) {
    40          ASTName name = (ASTName) n.getFirstChildOfType(ASTName.class);
    41          return name != null
    42                  && name.getNameDeclaration() instanceof VariableNameDeclaration
    43                  && ((VariableNameDeclaration) name.getNameDeclaration()).getAccessNodeParent().isFinal();
    44      }
    45
    46      private void checkTernary(ASTConditionalExpression n, Object data, ASTNullLiteral node) {
    47          if (n.isTernary() && !(n.jjtGetChild(0) instanceof ASTEqualityExpression)) {
    48              addViolation(data, node);
    49          }
    50      }
    51  }