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  }