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 }