1 package net.sourceforge.pmd.rules;
2
3 import net.sourceforge.pmd.AbstractRule;
4 import net.sourceforge.pmd.RuleContext;
5 import net.sourceforge.pmd.ast.ASTBlock;
6 import net.sourceforge.pmd.ast.ASTBlockStatement;
7 import net.sourceforge.pmd.ast.ASTBooleanLiteral;
8 import net.sourceforge.pmd.ast.ASTIfStatement;
9 import net.sourceforge.pmd.ast.ASTReturnStatement;
10 import net.sourceforge.pmd.ast.ASTStatement;
11 import net.sourceforge.pmd.ast.SimpleNode;
12
13 public class SimplifyBooleanReturnsRule extends AbstractRule {
14
15 public Object visit(ASTIfStatement node, Object data) {
16 // only deal with if..then..else stmts
17 if (node.jjtGetNumChildren() != 3) {
18 return super.visit(node, data);
19 }
20
21 // don't bother if either the if or the else block is empty
22 if (node.jjtGetChild(1).jjtGetNumChildren() == 0 || node.jjtGetChild(2).jjtGetNumChildren() == 0) {
23 return super.visit(node, data);
24 }
25
26 // first case:
27 // If
28 // Expr
29 // Statement
30 // ReturnStatement
31 // Statement
32 // ReturnStatement
33 // i.e.,
34 // if (foo)
35 // return true;
36 // else
37 // return false;
38
39 // second case
40 // If
41 // Expr
42 // Statement
43 // Block
44 // BlockStatement
45 // Statement
46 // ReturnStatement
47 // Statement
48 // Block
49 // BlockStatement
50 // Statement
51 // ReturnStatement
52 // i.e.,
53 // if (foo) {
54 // return true;
55 // } else {
56 // return false;
57 // }
58 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))) {
59 RuleContext ctx = (RuleContext) data;
60 ctx.getReport().addRuleViolation(createRuleViolation(ctx, node.getBeginLine()));
61 } 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))) {
62 RuleContext ctx = (RuleContext) data;
63 ctx.getReport().addRuleViolation(createRuleViolation(ctx, node.getBeginLine()));
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 }
This page was automatically generated by Maven