// If the call threw an exception, just don't optimize
}
}
private void tryRemoveSwitch(JSwitchStatement x, Context ctx) {
JBlock body = x.getBody();
if (body.getStatements().size() == 0) {
// Empty switch; just run the switch condition.
ctx.replaceMe(x.getExpr().makeStatement());
} else if (body.getStatements().size() == 2) {
/*
* If there are only two statements, we know it's a case statement and
* something with an effect.
*
* TODO: make this more sophisticated; what we should really care about
* is how many case statements it contains, not how many statements:
*
* switch(i) { default: a(); b(); c(); }
*
* becomes { a(); b(); c(); }
*
* switch(i) { case 1: a(); b(); c(); }
*
* becomes if (i == 1) { a(); b(); c(); }
*
* switch(i) { case 1: a(); b(); break; default: c(); d(); }
*
* becomes if (i == 1) { a(); b(); } else { c(); d(); }
*/
JCaseStatement caseStatement = (JCaseStatement) body.getStatements().get(
0);
JStatement statement = body.getStatements().get(1);
FindBreakContinueStatementsVisitor visitor = new FindBreakContinueStatementsVisitor();
visitor.accept(statement);
if (visitor.hasBreakContinueStatements()) {
// Cannot optimize.
return;
}
if (caseStatement.getExpr() != null) {
// Create an if statement equivalent to the single-case switch.
JBinaryOperation compareOperation = new JBinaryOperation(x.getSourceInfo(),
program.getTypePrimitiveBoolean(), JBinaryOperator.EQ,
x.getExpr(), caseStatement.getExpr());
JBlock block = new JBlock(x.getSourceInfo());
block.addStmt(statement);
JIfStatement ifStatement = new JIfStatement(x.getSourceInfo(),
compareOperation, block, null);
ctx.replaceMe(ifStatement);
} else {
// All we have is a default case; convert to a JBlock.
JBlock block = new JBlock(x.getSourceInfo());
block.addStmt(x.getExpr().makeStatement());
block.addStmt(statement);
ctx.replaceMe(block);
}
}
}