View Javadoc

1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.rules;
5   
6   import net.sourceforge.pmd.AbstractRule;
7   import net.sourceforge.pmd.ast.ASTAssignmentOperator;
8   import net.sourceforge.pmd.ast.ASTExpression;
9   import net.sourceforge.pmd.ast.ASTName;
10  import net.sourceforge.pmd.ast.ASTPrimaryExpression;
11  import net.sourceforge.pmd.ast.ASTPrimarySuffix;
12  import net.sourceforge.pmd.ast.ASTStatementExpression;
13  import net.sourceforge.pmd.ast.Node;
14  import net.sourceforge.pmd.ast.SimpleNode;
15  
16  public class IdempotentOperations extends AbstractRule {
17  
18      public Object visit(ASTStatementExpression node, Object data) {
19          if (node.jjtGetNumChildren() != 3
20                  || !(node.jjtGetChild(0) instanceof ASTPrimaryExpression)
21                  || !(node.jjtGetChild(1) instanceof ASTAssignmentOperator)
22                  || (((ASTAssignmentOperator) (node.jjtGetChild(1))).isCompound())
23                  || !(node.jjtGetChild(2) instanceof ASTExpression)
24                  || node.jjtGetChild(0).jjtGetChild(0).jjtGetNumChildren() == 0
25                  || node.jjtGetChild(2).jjtGetChild(0).jjtGetChild(0).jjtGetNumChildren() == 0
26          ) {
27              return super.visit(node, data);
28          }
29  
30          SimpleNode lhs = (SimpleNode) node.jjtGetChild(0).jjtGetChild(0).jjtGetChild(0);
31          if (!(lhs instanceof ASTName)) {
32              return super.visit(node, data);
33          }
34  
35          SimpleNode rhs = (SimpleNode) node.jjtGetChild(2).jjtGetChild(0).jjtGetChild(0).jjtGetChild(0);
36          if (!(rhs instanceof ASTName)) {
37              return super.visit(node, data);
38          }
39  
40          if (!lhs.hasImageEqualTo(rhs.getImage())) {
41              return super.visit(node, data);
42          }
43  
44          if (lhs.jjtGetParent().jjtGetParent().jjtGetNumChildren() > 1) {
45              Node n = lhs.jjtGetParent().jjtGetParent().jjtGetChild(1);
46              if (n instanceof ASTPrimarySuffix && ((ASTPrimarySuffix) n).isArrayDereference()) {
47                  return super.visit(node, data);
48              }
49          }
50  
51          if (rhs.jjtGetParent().jjtGetParent().jjtGetNumChildren() > 1) {
52              Node n = rhs.jjtGetParent().jjtGetParent().jjtGetChild(1);
53              if (n instanceof ASTPrimarySuffix && ((ASTPrimarySuffix) n).isArguments() || ((ASTPrimarySuffix) n).isArrayDereference()) {
54                  return super.visit(node, data);
55              }
56          }
57  
58          if (lhs.findChildrenOfType(ASTPrimarySuffix.class).size() != rhs.findChildrenOfType(ASTPrimarySuffix.class).size()) {
59              return super.visit(node, data);
60          }
61  
62          addViolation(data, node);
63          return super.visit(node, data);
64      }
65  }