AvoidMultipleUnaryOperatorsRule.java
01 package net.sourceforge.pmd.lang.java.rule.basic;
02 
03 import net.sourceforge.pmd.lang.ast.Node;
04 import net.sourceforge.pmd.lang.java.ast.ASTExpression;
05 import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
06 import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix;
07 import net.sourceforge.pmd.lang.java.ast.ASTUnaryExpression;
08 import net.sourceforge.pmd.lang.java.ast.ASTUnaryExpressionNotPlusMinus;
09 import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
10 
11 public class AvoidMultipleUnaryOperatorsRule extends AbstractJavaRule {
12 
13   public AvoidMultipleUnaryOperatorsRule() {
14     super.addRuleChainVisit(ASTUnaryExpression.class);
15     super.addRuleChainVisit(ASTUnaryExpressionNotPlusMinus.class);
16   }
17 
18   @Override
19   public Object visit(ASTUnaryExpression node, Object data) {
20     checkUnaryDescendent(node, data);
21     return data;
22   }
23 
24   @Override
25   public Object visit(ASTUnaryExpressionNotPlusMinus node, Object data) {
26     checkUnaryDescendent(node, data);
27     return data;
28   }
29 
30   private void checkUnaryDescendent(Node node, Object data) {
31     boolean match = false;
32     if (node.jjtGetNumChildren() == 1) {
33       Node child = node.jjtGetChild(0);
34       if (child instanceof ASTUnaryExpression || child instanceof ASTUnaryExpressionNotPlusMinus) {
35         match = true;
36       else if (child instanceof ASTPrimaryExpression) {
37         Node primaryExpression = child;
38         // Skip down PrimaryExpression/PrimaryPrefix/Expression chains created by parentheses
39         while (true) {
40           if (primaryExpression.jjtGetNumChildren() == 1
41               && primaryExpression.jjtGetChild(0instanceof ASTPrimaryPrefix
42               && primaryExpression.jjtGetChild(0).jjtGetNumChildren() == 1
43               && primaryExpression.jjtGetChild(0).jjtGetChild(0instanceof ASTExpression
44               && primaryExpression.jjtGetChild(0).jjtGetChild(0).jjtGetNumChildren() == 1) {
45             Node candidate = primaryExpression.jjtGetChild(0).jjtGetChild(0).jjtGetChild(0);
46             if (candidate instanceof ASTUnaryExpression
47                 || candidate instanceof ASTUnaryExpressionNotPlusMinus) {
48               match = true;
49               break;
50             else if (candidate instanceof ASTPrimaryExpression) {
51               primaryExpression = candidate;
52               continue;
53             else {
54               break;
55             }
56           else {
57             break;
58           }
59         }
60       }
61     }
62 
63     if (match) {
64       addViolation(data, node);
65     }
66   }
67 }