View Javadoc

1   package net.sourceforge.pmd.rules.basic;
2   
3   import net.sourceforge.pmd.AbstractJavaRule;
4   import net.sourceforge.pmd.ast.ASTExpression;
5   import net.sourceforge.pmd.ast.ASTPrimaryExpression;
6   import net.sourceforge.pmd.ast.ASTPrimaryPrefix;
7   import net.sourceforge.pmd.ast.ASTUnaryExpression;
8   import net.sourceforge.pmd.ast.ASTUnaryExpressionNotPlusMinus;
9   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 || child instanceof ASTUnaryExpressionNotPlusMinus) {
36  				match = true;
37  			} else if (child instanceof ASTPrimaryExpression) {
38  				Node primaryExpression = child;
39  				// Skip down PrimaryExpression/PrimaryPrefix/Expression chains created by parentheses
40  				while (true) {
41  					if (primaryExpression.jjtGetNumChildren() == 1
42  							&& primaryExpression.jjtGetChild(0) instanceof ASTPrimaryPrefix
43  							&& primaryExpression.jjtGetChild(0).jjtGetNumChildren() == 1
44  							&& primaryExpression.jjtGetChild(0).jjtGetChild(0) instanceof ASTExpression
45  							&& primaryExpression.jjtGetChild(0).jjtGetChild(0).jjtGetNumChildren() == 1) {
46  						Node candidate = primaryExpression.jjtGetChild(0).jjtGetChild(0).jjtGetChild(0);
47  						if (candidate instanceof ASTUnaryExpression
48  								|| candidate instanceof ASTUnaryExpressionNotPlusMinus) {
49  							match = true;
50  							break;
51  						} else if (candidate instanceof ASTPrimaryExpression) {
52  							primaryExpression = candidate;
53  							continue;
54  						} else {
55  							break;
56  						}
57  					} else {
58  						break;
59  					}
60  				}
61  			}
62  		}
63  
64  		if (match) {
65  			addViolation(data, node);
66  		}
67  	}
68  }