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(0) instanceof ASTPrimaryPrefix
42 && primaryExpression.jjtGetChild(0).jjtGetNumChildren() == 1
43 && primaryExpression.jjtGetChild(0).jjtGetChild(0) instanceof 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 }
|