1
2
3
4 package net.sourceforge.pmd.lang.vm.rule.basic;
5
6 import net.sourceforge.pmd.lang.ast.Node;
7 import net.sourceforge.pmd.lang.vm.ast.ASTBlock;
8 import net.sourceforge.pmd.lang.vm.ast.ASTElseIfStatement;
9 import net.sourceforge.pmd.lang.vm.ast.ASTElseStatement;
10 import net.sourceforge.pmd.lang.vm.ast.ASTIfStatement;
11 import net.sourceforge.pmd.lang.vm.ast.ASTText;
12 import net.sourceforge.pmd.lang.vm.ast.AbstractVmNode;
13 import net.sourceforge.pmd.lang.vm.rule.AbstractVmRule;
14
15 import org.apache.commons.lang3.StringUtils;
16
17 public class CollapsibleIfStatementsRule extends AbstractVmRule {
18
19 @Override
20 public Object visit(final ASTIfStatement node, final Object data) {
21 handleIfElseIf(node, data);
22 return super.visit(node, data);
23 }
24
25 @Override
26 public Object visit(final ASTElseIfStatement node, final Object data) {
27
28 if (node.jjtGetParent().findChildrenOfType(ASTElseIfStatement.class).size() == 1) {
29 handleIfElseIf(node, data);
30 }
31 return super.visit(node, data);
32 }
33
34 private void handleIfElseIf(final AbstractVmNode node, final Object data) {
35 if (node.getFirstChildOfType(ASTElseStatement.class) == null
36 && node.getFirstChildOfType(ASTElseIfStatement.class) == null) {
37 final ASTBlock ifBlock = node.getFirstChildOfType(ASTBlock.class);
38 boolean violationFound = false;
39 int ifCounter = 0;
40 for (int i = 0; i < ifBlock.jjtGetNumChildren(); i++) {
41 final Node blockChild = ifBlock.jjtGetChild(i);
42 if (blockChild instanceof ASTText) {
43 if (StringUtils.isNotBlank(((ASTText) blockChild).getFirstToken().toString())) {
44 violationFound = false;
45 break;
46 }
47 }
48 else if (blockChild instanceof ASTIfStatement) {
49
50 violationFound = !hasElseOrElseIf(blockChild);
51 if (!violationFound) {
52 break;
53 }
54 ifCounter++;
55 }
56 else if (blockChild instanceof ASTElseIfStatement) {
57
58 violationFound = !hasElseOrElseIf(blockChild);
59 if (!violationFound) {
60 break;
61 }
62 ifCounter++;
63 }
64 else {
65
66 violationFound = false;
67 break;
68 }
69 }
70 if (violationFound && ifCounter == 1) {
71 addViolation(data, node);
72 }
73 }
74 }
75
76 private boolean hasElseOrElseIf(final Node parentIfNode) {
77 return parentIfNode.getFirstChildOfType(ASTElseStatement.class) != null
78 || parentIfNode.getFirstChildOfType(ASTElseIfStatement.class) != null;
79 }
80
81 }