1
2
3
4 package net.sourceforge.pmd.lang.java.rule.basic;
5
6 import net.sourceforge.pmd.lang.ast.Node;
7 import net.sourceforge.pmd.lang.java.ast.ASTExpression;
8 import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
9 import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix;
10 import net.sourceforge.pmd.lang.java.ast.ASTUnaryExpression;
11 import net.sourceforge.pmd.lang.java.ast.ASTUnaryExpressionNotPlusMinus;
12 import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
13
14 public class AvoidMultipleUnaryOperatorsRule extends AbstractJavaRule {
15
16 public AvoidMultipleUnaryOperatorsRule() {
17 super.addRuleChainVisit(ASTUnaryExpression.class);
18 super.addRuleChainVisit(ASTUnaryExpressionNotPlusMinus.class);
19 }
20
21 @Override
22 public Object visit(ASTUnaryExpression node, Object data) {
23 checkUnaryDescendent(node, data);
24 return data;
25 }
26
27 @Override
28 public Object visit(ASTUnaryExpressionNotPlusMinus node, Object data) {
29 checkUnaryDescendent(node, data);
30 return data;
31 }
32
33 private void checkUnaryDescendent(Node node, Object data) {
34 boolean match = false;
35 if (node.jjtGetNumChildren() == 1) {
36 Node child = node.jjtGetChild(0);
37 if (child instanceof ASTUnaryExpression || child instanceof ASTUnaryExpressionNotPlusMinus) {
38 match = true;
39 } else if (child instanceof ASTPrimaryExpression) {
40 Node primaryExpression = child;
41
42 while (true) {
43 if (primaryExpression.jjtGetNumChildren() == 1
44 && primaryExpression.jjtGetChild(0) instanceof ASTPrimaryPrefix
45 && primaryExpression.jjtGetChild(0).jjtGetNumChildren() == 1
46 && primaryExpression.jjtGetChild(0).jjtGetChild(0) instanceof ASTExpression
47 && primaryExpression.jjtGetChild(0).jjtGetChild(0).jjtGetNumChildren() == 1) {
48 Node candidate = primaryExpression.jjtGetChild(0).jjtGetChild(0).jjtGetChild(0);
49 if (candidate instanceof ASTUnaryExpression
50 || candidate instanceof ASTUnaryExpressionNotPlusMinus) {
51 match = true;
52 break;
53 } else if (candidate instanceof ASTPrimaryExpression) {
54 primaryExpression = candidate;
55 continue;
56 } else {
57 break;
58 }
59 } else {
60 break;
61 }
62 }
63 }
64 }
65
66 if (match) {
67 addViolation(data, node);
68 }
69 }
70 }