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(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 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 (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.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 }
|