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.RuleContext;
8 import net.sourceforge.pmd.ast.ASTBlock;
9 import net.sourceforge.pmd.ast.ASTBlockStatement;
10 import net.sourceforge.pmd.ast.ASTBooleanLiteral;
11 import net.sourceforge.pmd.ast.ASTIfStatement;
12 import net.sourceforge.pmd.ast.ASTReturnStatement;
13 import net.sourceforge.pmd.ast.ASTStatement;
14 import net.sourceforge.pmd.ast.SimpleNode;
15
16 public class SimplifyBooleanReturnsRule extends AbstractRule {
17
18 public Object visit(ASTIfStatement node, Object data) {
19 // only deal with if..then..else stmts
20 if (node.jjtGetNumChildren() != 3) {
21 return super.visit(node, data);
22 }
23
24 // don't bother if either the if or the else block is empty
25 if (node.jjtGetChild(1).jjtGetNumChildren() == 0 || node.jjtGetChild(2).jjtGetNumChildren() == 0) {
26 return super.visit(node, data);
27 }
28
29 // first case:
30 // If
31 // Expr
32 // Statement
33 // ReturnStatement
34 // Statement
35 // ReturnStatement
36 // i.e.,
37 // if (foo)
38 // return true;
39 // else
40 // return false;
41
42 // second case
43 // If
44 // Expr
45 // Statement
46 // Block
47 // BlockStatement
48 // Statement
49 // ReturnStatement
50 // Statement
51 // Block
52 // BlockStatement
53 // Statement
54 // ReturnStatement
55 // i.e.,
56 // if (foo) {
57 // return true;
58 // } else {
59 // return false;
60 // }
61 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))) {
62 RuleContext ctx = (RuleContext) data;
63 ctx.getReport().addRuleViolation(createRuleViolation(ctx, node.getBeginLine()));
64 } 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))) {
65 RuleContext ctx = (RuleContext) data;
66 ctx.getReport().addRuleViolation(createRuleViolation(ctx, node.getBeginLine()));
67 }
68
69 return super.visit(node, data);
70 }
71
72 private boolean hasOneBlockStmt(SimpleNode node) {
73 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;
74 }
75
76 private boolean terminatesInBooleanLiteral(SimpleNode node) {
77 return eachNodeHasOneChild(node) && (getLastChild(node) instanceof ASTBooleanLiteral);
78 }
79
80 private boolean eachNodeHasOneChild(SimpleNode node) {
81 if (node.jjtGetNumChildren() > 1) {
82 return false;
83 }
84 if (node.jjtGetNumChildren() == 0) {
85 return true;
86 }
87 return eachNodeHasOneChild((SimpleNode) node.jjtGetChild(0));
88 }
89
90 private SimpleNode getLastChild(SimpleNode node) {
91 if (node.jjtGetNumChildren() == 0) {
92 return node;
93 }
94 return getLastChild((SimpleNode) node.jjtGetChild(0));
95 }
96 }
This page was automatically generated by Maven