use of org.codehaus.groovy.ast.stmt.TryCatchStatement in project groovy by apache.
the class FinalVariableAnalyzer method visitTryCatchFinally.
@Override
public void visitTryCatchFinally(final TryCatchStatement statement) {
visitStatement(statement);
Map<Variable, VariableState> beforeTryCatch = new HashMap<Variable, VariableState>(getState());
statement.getTryStatement().visit(this);
for (CatchStatement catchStatement : statement.getCatchStatements()) {
catchStatement.visit(this);
}
Statement finallyStatement = statement.getFinallyStatement();
// we need to recall which final variables are unassigned so cloning the current state
Map<Variable, VariableState> afterTryCatchState = new HashMap<Variable, VariableState>(getState());
if (finallyStatement instanceof EmptyStatement) {
// dispatching to EmptyStatement will not call back visitor,
// must call our visitEmptyStatement explicitly
visitEmptyStatement((EmptyStatement) finallyStatement);
} else {
finallyStatement.visit(this);
}
// and now we must reset to uninitialized state variables which were only initialized during try/catch
Map<Variable, VariableState> afterFinally = new HashMap<Variable, VariableState>(getState());
for (Map.Entry<Variable, VariableState> entry : afterFinally.entrySet()) {
Variable var = entry.getKey();
VariableState afterFinallyState = entry.getValue();
VariableState beforeTryCatchState = beforeTryCatch.get(var);
if (afterFinallyState == VariableState.is_final && beforeTryCatchState != VariableState.is_final && afterTryCatchState.get(var) != beforeTryCatchState) {
getState().put(var, beforeTryCatchState == null ? VariableState.is_uninitialized : beforeTryCatchState);
}
}
}
use of org.codehaus.groovy.ast.stmt.TryCatchStatement in project groovy by apache.
the class AntlrParserPlugin method tryStatement.
protected Statement tryStatement(AST tryStatementNode) {
AST tryNode = tryStatementNode.getFirstChild();
Statement tryStatement = statement(tryNode);
Statement finallyStatement = EmptyStatement.INSTANCE;
AST node = tryNode.getNextSibling();
// let's do the catch nodes
List<CatchStatement> catches = new ArrayList<CatchStatement>();
for (; node != null && isType(LITERAL_catch, node); node = node.getNextSibling()) {
final List<CatchStatement> catchStatements = catchStatement(node);
catches.addAll(catchStatements);
}
if (isType(LITERAL_finally, node)) {
finallyStatement = statement(node);
node = node.getNextSibling();
}
if (finallyStatement instanceof EmptyStatement && catches.isEmpty()) {
throw new ASTRuntimeException(tryStatementNode, "A try statement must have at least one catch or finally block.");
}
TryCatchStatement tryCatchStatement = new TryCatchStatement(tryStatement, finallyStatement);
configureAST(tryCatchStatement, tryStatementNode);
for (CatchStatement statement : catches) {
tryCatchStatement.addCatch(statement);
}
return tryCatchStatement;
}
use of org.codehaus.groovy.ast.stmt.TryCatchStatement in project groovy by apache.
the class StaticTypeCheckingVisitor method visitTryCatchFinally.
@Override
public void visitTryCatchFinally(final TryCatchStatement statement) {
final List<CatchStatement> catchStatements = statement.getCatchStatements();
for (CatchStatement catchStatement : catchStatements) {
ClassNode exceptionType = catchStatement.getExceptionType();
typeCheckingContext.controlStructureVariables.put(catchStatement.getVariable(), exceptionType);
}
try {
super.visitTryCatchFinally(statement);
} finally {
for (CatchStatement catchStatement : catchStatements) {
typeCheckingContext.controlStructureVariables.remove(catchStatement.getVariable());
}
}
}
use of org.codehaus.groovy.ast.stmt.TryCatchStatement in project groovy-core by groovy.
the class FinalVariableAnalyzer method visitTryCatchFinally.
@Override
public void visitTryCatchFinally(final TryCatchStatement statement) {
visitStatement(statement);
Map<Variable, VariableState> beforeTryCatch = new HashMap<Variable, VariableState>(getState());
statement.getTryStatement().visit(this);
for (CatchStatement catchStatement : statement.getCatchStatements()) {
catchStatement.visit(this);
}
Statement finallyStatement = statement.getFinallyStatement();
// we need to recall which final variables are unassigned so cloning the current state
Map<Variable, VariableState> afterTryCatchState = new HashMap<Variable, VariableState>(getState());
if (finallyStatement instanceof EmptyStatement) {
// dispatching to EmptyStatement will not call back visitor,
// must call our visitEmptyStatement explicitly
visitEmptyStatement((EmptyStatement) finallyStatement);
} else {
finallyStatement.visit(this);
}
// and now we must reset to uninitialized state variables which were only initialized during try/catch
Map<Variable, VariableState> afterFinally = new HashMap<Variable, VariableState>(getState());
for (Map.Entry<Variable, VariableState> entry : afterFinally.entrySet()) {
Variable var = entry.getKey();
VariableState afterFinallyState = entry.getValue();
VariableState beforeTryCatchState = beforeTryCatch.get(var);
if (afterFinallyState == VariableState.is_final && beforeTryCatchState != VariableState.is_final && afterTryCatchState.get(var) != beforeTryCatchState) {
getState().put(var, beforeTryCatchState == null ? VariableState.is_uninitialized : beforeTryCatchState);
}
}
}
use of org.codehaus.groovy.ast.stmt.TryCatchStatement in project groovy-core by groovy.
the class StatementWriter method writeTryCatchFinally.
public void writeTryCatchFinally(TryCatchStatement statement) {
controller.getAcg().onLineNumber(statement, "visitTryCatchFinally");
writeStatementLabel(statement);
MethodVisitor mv = controller.getMethodVisitor();
CompileStack compileStack = controller.getCompileStack();
OperandStack operandStack = controller.getOperandStack();
Statement tryStatement = statement.getTryStatement();
final Statement finallyStatement = statement.getFinallyStatement();
// start try block, label needed for exception table
Label tryStart = new Label();
mv.visitLabel(tryStart);
BlockRecorder tryBlock = makeBlockRecorder(finallyStatement);
tryBlock.startRange(tryStart);
tryStatement.visit(controller.getAcg());
// goto finally part
Label finallyStart = new Label();
mv.visitJumpInsn(GOTO, finallyStart);
Label tryEnd = new Label();
mv.visitLabel(tryEnd);
tryBlock.closeRange(tryEnd);
// pop for "makeBlockRecorder(finallyStatement)"
controller.getCompileStack().pop();
BlockRecorder catches = makeBlockRecorder(finallyStatement);
for (CatchStatement catchStatement : statement.getCatchStatements()) {
ClassNode exceptionType = catchStatement.getExceptionType();
String exceptionTypeInternalName = BytecodeHelper.getClassInternalName(exceptionType);
// start catch block, label needed for exception table
Label catchStart = new Label();
mv.visitLabel(catchStart);
catches.startRange(catchStart);
// create exception variable and store the exception
Parameter exceptionVariable = catchStatement.getVariable();
compileStack.pushState();
compileStack.defineVariable(exceptionVariable, true);
// handle catch body
catchStatement.visit(controller.getAcg());
// place holder to avoid problems with empty catch blocks
mv.visitInsn(NOP);
// pop for the variable
controller.getCompileStack().pop();
// end of catch
Label catchEnd = new Label();
mv.visitLabel(catchEnd);
catches.closeRange(catchEnd);
// goto finally start
mv.visitJumpInsn(GOTO, finallyStart);
compileStack.writeExceptionTable(tryBlock, catchStart, exceptionTypeInternalName);
}
// Label used to handle exceptions in catches and regularly
// visited finals.
Label catchAny = new Label();
// add "catch any" block to exception table for try part we do this
// after the exception blocks, because else this one would supersede
// any of those otherwise
compileStack.writeExceptionTable(tryBlock, catchAny, null);
// same for the catch parts
compileStack.writeExceptionTable(catches, catchAny, null);
// pop for "makeBlockRecorder(catches)"
compileStack.pop();
// start finally
mv.visitLabel(finallyStart);
finallyStatement.visit(controller.getAcg());
//**
mv.visitInsn(NOP);
// goto after all-catching block
Label skipCatchAll = new Label();
mv.visitJumpInsn(GOTO, skipCatchAll);
// start a block catching any Exception
mv.visitLabel(catchAny);
//store exception
//TODO: maybe define a Throwable and use it here instead of Object
operandStack.push(ClassHelper.OBJECT_TYPE);
int anyExceptionIndex = compileStack.defineTemporaryVariable("exception", true);
finallyStatement.visit(controller.getAcg());
// load the exception and rethrow it
mv.visitVarInsn(ALOAD, anyExceptionIndex);
mv.visitInsn(ATHROW);
mv.visitLabel(skipCatchAll);
}
Aggregations