/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.vm.rule.basic;
import org.apache.commons.lang3.StringUtils;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.vm.ast.ASTBlock;
import net.sourceforge.pmd.lang.vm.ast.ASTElseIfStatement;
import net.sourceforge.pmd.lang.vm.ast.ASTElseStatement;
import net.sourceforge.pmd.lang.vm.ast.ASTIfStatement;
import net.sourceforge.pmd.lang.vm.ast.ASTText;
import net.sourceforge.pmd.lang.vm.ast.AbstractVmNode;
import net.sourceforge.pmd.lang.vm.rule.AbstractVmRule;
public class CollapsibleIfStatementsRule extends AbstractVmRule {
@Override
public Object visit(final ASTIfStatement node, final Object data) {
handleIfElseIf(node, data);
return super.visit(node, data);
}
@Override
public Object visit(final ASTElseIfStatement node, final Object data) {
// verify that this elseif doesn't have any siblings
if (node.jjtGetParent().findChildrenOfType(ASTElseIfStatement.class).size() == 1) {
handleIfElseIf(node, data);
}
return super.visit(node, data);
}
private void handleIfElseIf(final AbstractVmNode node, final Object data) {
if (node.getFirstChildOfType(ASTElseStatement.class) == null
&& node.getFirstChildOfType(ASTElseIfStatement.class) == null) {
final ASTBlock ifBlock = node.getFirstChildOfType(ASTBlock.class);
boolean violationFound = false;
int ifCounter = 0;
for (int i = 0; i < ifBlock.jjtGetNumChildren(); i++) {
final Node blockChild = ifBlock.jjtGetChild(i);
if (blockChild instanceof ASTText) {
if (StringUtils.isNotBlank(((ASTText) blockChild).getFirstToken().toString())) {
violationFound = false;
break;
}
} else if (blockChild instanceof ASTIfStatement) {
// check if it has an ELSE of ELSEIF
violationFound = !hasElseOrElseIf(blockChild);
if (!violationFound) {
break;
}
ifCounter++;
} else if (blockChild instanceof ASTElseIfStatement) {
// check if it has an ELSE of ELSEIF
violationFound = !hasElseOrElseIf(blockChild);
if (!violationFound) {
break;
}
ifCounter++;
} else {
// any other node - not violation
violationFound = false;
break;
}
}
if (violationFound && ifCounter == 1) {
addViolation(data, node);
}
}
}
private boolean hasElseOrElseIf(final Node parentIfNode) {
return parentIfNode.getFirstChildOfType(ASTElseStatement.class) != null
|| parentIfNode.getFirstChildOfType(ASTElseIfStatement.class) != null;
}
}