/** * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ package net.sourceforge.pmd.lang.java.rule.design; import java.util.List; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.java.ast.ASTAssignmentOperator; import net.sourceforge.pmd.lang.java.ast.ASTExpression; import net.sourceforge.pmd.lang.java.ast.ASTName; import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression; import net.sourceforge.pmd.lang.java.ast.ASTPrimarySuffix; import net.sourceforge.pmd.lang.java.ast.ASTStatementExpression; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule; public class IdempotentOperationsRule extends AbstractJavaRule { @Override public Object visit(ASTStatementExpression node, Object data) { if (node.jjtGetNumChildren() != 3 || !(node.jjtGetChild(0) instanceof ASTPrimaryExpression) || !(node.jjtGetChild(1) instanceof ASTAssignmentOperator) || ((ASTAssignmentOperator) node.jjtGetChild(1)).isCompound() || !(node.jjtGetChild(2) instanceof ASTExpression) || node.jjtGetChild(0).jjtGetChild(0).jjtGetNumChildren() == 0 || node.jjtGetChild(2).jjtGetChild(0).jjtGetChild(0).jjtGetNumChildren() == 0) { return super.visit(node, data); } Node lhs = node.jjtGetChild(0).jjtGetChild(0).jjtGetChild(0); if (!(lhs instanceof ASTName)) { return super.visit(node, data); } Node rhs = node.jjtGetChild(2).jjtGetChild(0).jjtGetChild(0).jjtGetChild(0); if (!(rhs instanceof ASTName)) { return super.visit(node, data); } if (!lhs.hasImageEqualTo(rhs.getImage())) { return super.visit(node, data); } if (lhs.jjtGetParent().jjtGetParent().jjtGetNumChildren() > 1) { Node n = lhs.jjtGetParent().jjtGetParent().jjtGetChild(1); if (n instanceof ASTPrimarySuffix && ((ASTPrimarySuffix) n).isArrayDereference()) { return super.visit(node, data); } } if (rhs.jjtGetParent().jjtGetParent().jjtGetNumChildren() > 1) { Node n = rhs.jjtGetParent().jjtGetParent().jjtGetChild(1); if (n instanceof ASTPrimarySuffix && ((ASTPrimarySuffix) n).isArguments() || ((ASTPrimarySuffix) n).isArrayDereference()) { return super.visit(node, data); } } if (lhs.findDescendantsOfType(ASTPrimarySuffix.class).size() != rhs .findDescendantsOfType(ASTPrimarySuffix.class).size()) { return super.visit(node, data); } List<ASTPrimarySuffix> lhsSuffixes = lhs.jjtGetParent().jjtGetParent() .findDescendantsOfType(ASTPrimarySuffix.class); List<ASTPrimarySuffix> rhsSuffixes = rhs.jjtGetParent().jjtGetParent() .findDescendantsOfType(ASTPrimarySuffix.class); if (lhsSuffixes.size() != rhsSuffixes.size()) { return super.visit(node, data); } for (int i = 0; i < lhsSuffixes.size(); i++) { ASTPrimarySuffix l = lhsSuffixes.get(i); ASTPrimarySuffix r = rhsSuffixes.get(i); if (!l.hasImageEqualTo(r.getImage())) { return super.visit(node, data); } } addViolation(data, node); return super.visit(node, data); } }