01: package org.acm.seguin.pmd.rules;
02:
03: import org.acm.seguin.pmd.AbstractRule;
04: import org.acm.seguin.pmd.RuleContext;
05: import net.sourceforge.jrefactory.ast.ASTAssignmentOperator;
06: import net.sourceforge.jrefactory.ast.ASTExpression;
07: import net.sourceforge.jrefactory.ast.ASTName;
08: import net.sourceforge.jrefactory.ast.ASTPrimaryExpression;
09: import net.sourceforge.jrefactory.ast.ASTStatementExpression;
10: import net.sourceforge.jrefactory.ast.SimpleNode;
11:
12: public class IdempotentOperationsRule extends AbstractRule {
13:
14: public Object visit(ASTStatementExpression node, Object data) {
15: if (node.jjtGetNumChildren() != 3
16: || !(node.jjtGetFirstChild() instanceof ASTPrimaryExpression)
17: || !(node.jjtGetChild(1) instanceof ASTAssignmentOperator)
18: || !(node.jjtGetChild(2) instanceof ASTExpression)) {
19: return super .visit(node, data);
20: }
21:
22: SimpleNode lhs = (SimpleNode) node.jjtGetFirstChild()
23: .jjtGetFirstChild().jjtGetFirstChild();
24: if (!(lhs instanceof ASTName)) {
25: return super .visit(node, data);
26: }
27:
28: SimpleNode rhs = (SimpleNode) node.jjtGetChild(2);
29: java.util.List rhsName = rhs.findChildrenOfType(ASTName.class);
30: //if (!(rhs instanceof ASTName)) {
31: if (rhsName.size() != 1) {
32: return super .visit(node, data);
33: }
34:
35: String rhsImage = ((ASTName) rhsName.get(0)).getImage();
36: if (!lhs.getImage().equals(rhsImage)) {
37: return super .visit(node, data);
38: }
39:
40: RuleContext ctx = (RuleContext) data;
41: ctx.getReport().addRuleViolation(
42: createRuleViolation(ctx, node.getBeginLine(),
43: "Avoid idempotent operations"));
44: return data;
45: }
46: }
|