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