JBlock newCatchBlock = new JBlock(catchInfo);
{
// $e = Exceptions.wrap($e)
JMethodCall call = new JMethodCall(catchInfo, null, wrapMethod);
call.addArg(new JLocalRef(catchInfo, exceptionVariable));
newCatchBlock.addStmt(JProgram.createAssignmentStmt(catchInfo, new JLocalRef(catchInfo,
exceptionVariable), call));
}
/*
* Build up a series of if, else if statements to test the type of the
* exception object against the types of the user's catch block. Each catch block might have
* multiple types in Java 7.
*
* Go backwards so we can nest the else statements in the correct order!
*/
// rethrow the current exception if no one caught it.
JStatement cur = new JThrowStatement(catchInfo, new JLocalRef(catchInfo, exceptionVariable));
for (int i = x.getCatchClauses().size() - 1; i >= 0; i--) {
JTryStatement.CatchClause clause = x.getCatchClauses().get(i);
JBlock block = clause.getBlock();
JLocalRef arg = clause.getArg();
List<JType> exceptionsTypes = clause.getTypes();
catchInfo = block.getSourceInfo();
// if ($e instanceof ArgType1 or $e instanceof ArgType2 ...) {
// var userVar = $e; <user code>
// }
// Handle the first Exception type.
JExpression ifTest = new JInstanceOf(catchInfo, (JReferenceType) exceptionsTypes.get(0),
new JLocalRef(catchInfo, exceptionVariable));
// Handle the rest of the Exception types if any.
for (int j = 1; j < exceptionsTypes.size(); j++) {
JExpression orExp = new JInstanceOf(catchInfo, (JReferenceType) exceptionsTypes.get(j),
new JLocalRef(catchInfo, exceptionVariable));
ifTest = new JBinaryOperation(catchInfo, JPrimitiveType.BOOLEAN, JBinaryOperator.OR,
ifTest, orExp);
}
JDeclarationStatement declaration =
new JDeclarationStatement(catchInfo, arg, new JLocalRef(catchInfo, exceptionVariable));
block.addStmt(0, declaration);
// nest the previous as an else for me
cur = new JIfStatement(catchInfo, ifTest, block, cur);
}
newCatchBlock.addStmt(cur);
// Replace with a single catch block.
x.getCatchClauses().clear();
List<JType> newCatchTypes = new ArrayList<JType>(1);
newCatchTypes.add(exceptionVariable.getType());
x.getCatchClauses().add(new JTryStatement.CatchClause(newCatchTypes,
new JLocalRef(newCatchBlock.getSourceInfo(), exceptionVariable), newCatchBlock));
}