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  // TODO - should check that this is not the first assignment.  e.g., this is OK:
16  // Object x;
17  // x = null;
18  public class NullAssignmentRule extends AbstractRule {
19  
20      public Object visit(ASTNullLiteral node, Object data) {
21          
22          if (node.getNthParent(5) instanceof ASTStatementExpression) {
23              ASTStatementExpression n = (ASTStatementExpression) node.getNthParent(5);
24  
25              if (isAssignmentToFinalField(n)) {
26                  return data;
27              }
28  
29              if (n.jjtGetNumChildren() > 2 && n.jjtGetChild(1) instanceof ASTAssignmentOperator) {
30                  addViolation(data, node);
31              }
32          } else if (node.getNthParent(4) instanceof ASTConditionalExpression) {
33              if (isBadTernary((ASTConditionalExpression)node.getNthParent(4))) {
34                  addViolation(data, node);
35              }
36          } else if (node.getNthParent(5) instanceof ASTConditionalExpression) {
37              if (isBadTernary((ASTConditionalExpression)node.getNthParent(5))) {
38                  addViolation(data, node);
39              }
40          }
41  
42          return data;
43      }
44  
45      private boolean isAssignmentToFinalField(ASTStatementExpression n) {
46          ASTName name = n.getFirstChildOfType(ASTName.class);
47          return name != null
48                  && name.getNameDeclaration() instanceof VariableNameDeclaration
49                  && ((VariableNameDeclaration) name.getNameDeclaration()).getAccessNodeParent().isFinal();
50      }
51  
52      private boolean isBadTernary(ASTConditionalExpression n) {
53          return n.isTernary() && !(n.jjtGetChild(0) instanceof ASTEqualityExpression);
54      }
55  }