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.RuleContext;
8   import net.sourceforge.pmd.ast.ASTAssignmentOperator;
9   import net.sourceforge.pmd.ast.ASTExpression;
10  import net.sourceforge.pmd.ast.ASTName;
11  import net.sourceforge.pmd.ast.ASTPrimaryExpression;
12  import net.sourceforge.pmd.ast.ASTPrimarySuffix;
13  import net.sourceforge.pmd.ast.ASTStatementExpression;
14  import net.sourceforge.pmd.ast.Node;
15  import net.sourceforge.pmd.ast.SimpleNode;
16  
17  public class IdempotentOperations extends AbstractRule {
18  
19      public Object visit(ASTStatementExpression node, Object data) {
20          if (node.jjtGetNumChildren() != 3
21                  || !(node.jjtGetChild(0) instanceof ASTPrimaryExpression)
22                  || !(node.jjtGetChild(1) instanceof ASTAssignmentOperator)
23                  || (((ASTAssignmentOperator) (node.jjtGetChild(1))).isCompound())
24                  || !(node.jjtGetChild(2) instanceof ASTExpression)
25                  || node.jjtGetChild(0).jjtGetChild(0).jjtGetNumChildren() == 0
26                  || node.jjtGetChild(2).jjtGetChild(0).jjtGetChild(0).jjtGetNumChildren() == 0
27          ) {
28              return super.visit(node, data);
29          }
30  
31          SimpleNode lhs = (SimpleNode) node.jjtGetChild(0).jjtGetChild(0).jjtGetChild(0);
32          if (!(lhs instanceof ASTName)) {
33              return super.visit(node, data);
34          }
35  
36          SimpleNode rhs = (SimpleNode) node.jjtGetChild(2).jjtGetChild(0).jjtGetChild(0).jjtGetChild(0);
37          if (!(rhs instanceof ASTName)) {
38              return super.visit(node, data);
39          }
40  
41          if (!lhs.getImage().equals(rhs.getImage())) {
42              return super.visit(node, data);
43          }
44  
45          if (lhs.jjtGetParent().jjtGetParent().jjtGetNumChildren() > 1) {
46              Node n = lhs.jjtGetParent().jjtGetParent().jjtGetChild(1);
47              if (n instanceof ASTPrimarySuffix && ((ASTPrimarySuffix) n).isArrayDeference()) {
48                  return super.visit(node, data);
49              }
50          }
51  
52          if (rhs.jjtGetParent().jjtGetParent().jjtGetNumChildren() > 1) {
53              Node n = rhs.jjtGetParent().jjtGetParent().jjtGetChild(1);
54              if (n instanceof ASTPrimarySuffix && ((ASTPrimarySuffix) n).isArguments() || ((ASTPrimarySuffix) n).isArrayDeference()) {
55                  return super.visit(node, data);
56              }
57          }
58  
59          ((RuleContext) data).getReport().addRuleViolation(createRuleViolation((RuleContext) data, node, "Avoid idempotent operations"));
60          return super.visit(node, data);
61      }
62  }