IdempotentOperationsRule.java
01 /**
02  * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
03  */
04 package net.sourceforge.pmd.lang.java.rule.design;
05 
06 import net.sourceforge.pmd.lang.ast.Node;
07 import net.sourceforge.pmd.lang.java.ast.ASTAssignmentOperator;
08 import net.sourceforge.pmd.lang.java.ast.ASTExpression;
09 import net.sourceforge.pmd.lang.java.ast.ASTName;
10 import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
11 import net.sourceforge.pmd.lang.java.ast.ASTPrimarySuffix;
12 import net.sourceforge.pmd.lang.java.ast.ASTStatementExpression;
13 import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
14 
15 public class IdempotentOperationsRule extends AbstractJavaRule {
16 
17     @Override
18     public Object visit(ASTStatementExpression node, Object data) {
19         if (node.jjtGetNumChildren() != 3
20                 || !(node.jjtGetChild(0instanceof ASTPrimaryExpression)
21                 || !(node.jjtGetChild(1instanceof ASTAssignmentOperator)
22                 || ((ASTAssignmentOperatornode.jjtGetChild(1)).isCompound()
23                 || !(node.jjtGetChild(2instanceof 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         Node lhs = node.jjtGetChild(0).jjtGetChild(0).jjtGetChild(0);
31         if (!(lhs instanceof ASTName)) {
32             return super.visit(node, data);
33         }
34 
35         Node rhs = 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 (instanceof ASTPrimarySuffix && ((ASTPrimarySuffixn).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 (instanceof ASTPrimarySuffix && ((ASTPrimarySuffixn).isArguments() || ((ASTPrimarySuffixn).isArrayDereference()) {
54                 return super.visit(node, data);
55             }
56         }
57 
58         if (lhs.findDescendantsOfType(ASTPrimarySuffix.class).size() != rhs.findDescendantsOfType(ASTPrimarySuffix.class).size()) {
59             return super.visit(node, data);
60         }
61 
62         addViolation(data, node);
63         return super.visit(node, data);
64     }
65 }