View Javadoc

    1   /**
    2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
    3    */
    4   package net.sourceforge.pmd.lang.java.rule.design;
    5
    6   import net.sourceforge.pmd.lang.ast.Node;
    7   import net.sourceforge.pmd.lang.java.ast.ASTAssignmentOperator;
    8   import net.sourceforge.pmd.lang.java.ast.ASTExpression;
    9   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  }