1 /***
2 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3 */
4 package net.sourceforge.pmd.rules;
5
6 import net.sourceforge.pmd.AbstractRule;
7 import net.sourceforge.pmd.ast.ASTBlock;
8 import net.sourceforge.pmd.ast.ASTBlockStatement;
9 import net.sourceforge.pmd.ast.ASTBooleanLiteral;
10 import net.sourceforge.pmd.ast.ASTIfStatement;
11 import net.sourceforge.pmd.ast.ASTReturnStatement;
12 import net.sourceforge.pmd.ast.ASTStatement;
13 import net.sourceforge.pmd.ast.SimpleNode;
14
15 public class SimplifyBooleanReturns extends AbstractRule {
16
17 public Object visit(ASTIfStatement node, Object data) {
18
19 if (node.jjtGetNumChildren() != 3) {
20 return super.visit(node, data);
21 }
22
23
24 if (node.jjtGetChild(1).jjtGetNumChildren() == 0 || node.jjtGetChild(2).jjtGetNumChildren() == 0) {
25 return super.visit(node, data);
26 }
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 if (node.jjtGetChild(1).jjtGetChild(0) instanceof ASTReturnStatement && node.jjtGetChild(2).jjtGetChild(0) instanceof ASTReturnStatement && terminatesInBooleanLiteral((SimpleNode) node.jjtGetChild(1).jjtGetChild(0)) && terminatesInBooleanLiteral((SimpleNode) node.jjtGetChild(2).jjtGetChild(0))) {
61 addViolation(data, node);
62 } else if (hasOneBlockStmt((SimpleNode) node.jjtGetChild(1)) && hasOneBlockStmt((SimpleNode) node.jjtGetChild(2)) && terminatesInBooleanLiteral((SimpleNode) node.jjtGetChild(1).jjtGetChild(0)) && terminatesInBooleanLiteral((SimpleNode) node.jjtGetChild(2).jjtGetChild(0))) {
63 addViolation(data, node);
64 }
65
66 return super.visit(node, data);
67 }
68
69 private boolean hasOneBlockStmt(SimpleNode node) {
70 return node.jjtGetChild(0) instanceof ASTBlock && node.jjtGetChild(0).jjtGetNumChildren() == 1 && node.jjtGetChild(0).jjtGetChild(0) instanceof ASTBlockStatement && node.jjtGetChild(0).jjtGetChild(0).jjtGetChild(0) instanceof ASTStatement && node.jjtGetChild(0).jjtGetChild(0).jjtGetChild(0).jjtGetChild(0) instanceof ASTReturnStatement;
71 }
72
73 private boolean terminatesInBooleanLiteral(SimpleNode node) {
74 return eachNodeHasOneChild(node) && (getLastChild(node) instanceof ASTBooleanLiteral);
75 }
76
77 private boolean eachNodeHasOneChild(SimpleNode node) {
78 if (node.jjtGetNumChildren() > 1) {
79 return false;
80 }
81 if (node.jjtGetNumChildren() == 0) {
82 return true;
83 }
84 return eachNodeHasOneChild((SimpleNode) node.jjtGetChild(0));
85 }
86
87 private SimpleNode getLastChild(SimpleNode node) {
88 if (node.jjtGetNumChildren() == 0) {
89 return node;
90 }
91 return getLastChild((SimpleNode) node.jjtGetChild(0));
92 }
93 }