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-core by groovy.
the class ReadWriteLockASTTransformation method visit.
public void visit(ASTNode[] nodes, SourceUnit source) {
init(nodes, source);
AnnotatedNode parent = (AnnotatedNode) nodes[1];
AnnotationNode node = (AnnotationNode) nodes[0];
final boolean isWriteLock;
if (READ_LOCK_TYPE.equals(node.getClassNode())) {
isWriteLock = false;
} else if (WRITE_LOCK_TYPE.equals(node.getClassNode())) {
isWriteLock = true;
} else {
throw new GroovyBugError("Internal error: expecting [" + READ_LOCK_TYPE.getName() + ", " + WRITE_LOCK_TYPE.getName() + "]" + " but got: " + node.getClassNode().getName());
}
String myTypeName = "@" + node.getClassNode().getNameWithoutPackage();
String value = getMemberStringValue(node, "value");
if (parent instanceof MethodNode) {
MethodNode mNode = (MethodNode) parent;
ClassNode cNode = mNode.getDeclaringClass();
String lockExpr = determineLock(value, cNode, mNode.isStatic(), myTypeName);
if (lockExpr == null)
return;
// get lock type
final Expression lockType;
if (isWriteLock) {
lockType = callX(varX(lockExpr, LOCK_TYPE), "writeLock");
} else {
lockType = callX(varX(lockExpr, LOCK_TYPE), "readLock");
}
Expression acquireLock = callX(lockType, "lock");
Expression releaseLock = callX(lockType, "unlock");
Statement originalCode = mNode.getCode();
mNode.setCode(block(stmt(acquireLock), new TryCatchStatement(originalCode, stmt(releaseLock))));
}
}
use of org.codehaus.groovy.ast.stmt.TryCatchStatement in project groovy by apache.
the class NotYetImplementedASTTransformation method tryCatchAssertionFailedError.
private TryCatchStatement tryCatchAssertionFailedError(AnnotationNode annotationNode, MethodNode methodNode, ArrayList<Statement> statements) {
TryCatchStatement tryCatchStatement = new TryCatchStatement(block(methodNode.getVariableScope(), statements), EmptyStatement.INSTANCE);
tryCatchStatement.addCatch(catchS(param(CATCHED_THROWABLE_TYPE, "ex"), ReturnStatement.RETURN_NULL_OR_VOID));
return tryCatchStatement;
}
use of org.codehaus.groovy.ast.stmt.TryCatchStatement in project groovy by apache.
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);
final 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);
compileStack.removeVar(anyExceptionIndex);
}
Aggregations