src/share/classes/com/sun/tools/javac/comp/Lower.java
Print this page
*** 1423,1451 ****
// need to go via this$n
return makeOuterThis(pos, c);
}
}
! /** Optionally replace a try statement with an automatic resource
! * management (ARM) block.
* @param tree The try statement to inspect.
! * @return An ARM block, or the original try block if there are no
! * resources to manage.
*/
! JCTree makeArmTry(JCTry tree) {
make_at(tree.pos());
twrVars = twrVars.dup();
! JCBlock armBlock = makeArmBlock(tree.resources, tree.body, 0);
if (tree.catchers.isEmpty() && tree.finalizer == null)
! result = translate(armBlock);
else
! result = translate(make.Try(armBlock, tree.catchers, tree.finalizer));
twrVars = twrVars.leave();
return result;
}
! private JCBlock makeArmBlock(List<JCTree> resources, JCBlock block, int depth) {
if (resources.isEmpty())
return block;
// Add resource declaration or expression to block statements
ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
--- 1423,1481 ----
// need to go via this$n
return makeOuterThis(pos, c);
}
}
! /**
! * Optionally replace a try statement with the desugaring of a
! * try-with-resources statement. The canonical desugaring of
! *
! * try ResourceSpecification
! * Block
! *
! * is
! *
! * {
! * final VariableModifiers_minus_final R #resource = Expression;
! * Throwable #primaryException = null;
! *
! * try ResourceSpecificationtail
! * Block
! * catch (Throwable #t) {
! * #primaryException = t;
! * throw #t;
! * } finally {
! * if (#resource != null) {
! * if (#primaryException != null) {
! * try {
! * #resource.close();
! * } catch(Throwable #suppressedException) {
! * #primaryException.addSuppressed(#suppressedException);
! * }
! * } else {
! * #resource.close();
! * }
! * }
! * }
! *
* @param tree The try statement to inspect.
! * @return A a desugared try-with-resources tree, or the original
! * try block if there are no resources to manage.
*/
! JCTree makeTwrTry(JCTry tree) {
make_at(tree.pos());
twrVars = twrVars.dup();
! JCBlock twrBlock = makeTwrBlock(tree.resources, tree.body, 0);
if (tree.catchers.isEmpty() && tree.finalizer == null)
! result = translate(twrBlock);
else
! result = translate(make.Try(twrBlock, tree.catchers, tree.finalizer));
twrVars = twrVars.leave();
return result;
}
! private JCBlock makeTwrBlock(List<JCTree> resources, JCBlock block, int depth) {
if (resources.isEmpty())
return block;
// Add resource declaration or expression to block statements
ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
*** 1495,1514 ****
JCBlock catchBlock = make.Block(0L, List.<JCStatement>of(assign, rethrowStat));
JCCatch catchClause = make.Catch(paramTree, catchBlock);
int oldPos = make.pos;
make.at(TreeInfo.endPos(block));
! JCBlock finallyClause = makeArmFinallyClause(primaryException, expr);
make.at(oldPos);
! JCTry outerTry = make.Try(makeArmBlock(resources.tail, block, depth + 1),
List.<JCCatch>of(catchClause),
finallyClause);
stats.add(outerTry);
return make.Block(0L, stats.toList());
}
! private JCBlock makeArmFinallyClause(Symbol primaryException, JCExpression resource) {
// primaryException.addSuppressed(catchException);
VarSymbol catchException =
new VarSymbol(0, make.paramName(2),
syms.throwableType,
currentMethodSym);
--- 1525,1544 ----
JCBlock catchBlock = make.Block(0L, List.<JCStatement>of(assign, rethrowStat));
JCCatch catchClause = make.Catch(paramTree, catchBlock);
int oldPos = make.pos;
make.at(TreeInfo.endPos(block));
! JCBlock finallyClause = makeTwrFinallyClause(primaryException, expr);
make.at(oldPos);
! JCTry outerTry = make.Try(makeTwrBlock(resources.tail, block, depth + 1),
List.<JCCatch>of(catchClause),
finallyClause);
stats.add(outerTry);
return make.Block(0L, stats.toList());
}
! private JCBlock makeTwrFinallyClause(Symbol primaryException, JCExpression resource) {
// primaryException.addSuppressed(catchException);
VarSymbol catchException =
new VarSymbol(0, make.paramName(2),
syms.throwableType,
currentMethodSym);
*** 1523,1548 ****
JCVariableDecl catchExceptionDecl = make.VarDef(catchException, null);
JCBlock catchBlock = make.Block(0L, List.<JCStatement>of(addSuppressionStatement));
List<JCCatch> catchClauses = List.<JCCatch>of(make.Catch(catchExceptionDecl, catchBlock));
JCTry tryTree = make.Try(tryBlock, catchClauses, null);
! // if (resource != null) resourceClose;
! JCExpression nullCheck = makeBinary(JCTree.NE,
! make.Ident(primaryException),
! makeNull());
! JCIf closeIfStatement = make.If(nullCheck,
tryTree,
makeResourceCloseInvocation(resource));
! return make.Block(0L, List.<JCStatement>of(closeIfStatement));
}
private JCStatement makeResourceCloseInvocation(JCExpression resource) {
// create resource.close() method invocation
! JCExpression resourceClose = makeCall(resource, names.close, List.<JCExpression>nil());
return make.Exec(resourceClose);
}
/** Construct a tree that represents the outer instance
* <C.this>. Never pick the current `this'.
* @param pos The source code position to be used for the tree.
* @param c The qualifier class.
*/
--- 1553,1586 ----
JCVariableDecl catchExceptionDecl = make.VarDef(catchException, null);
JCBlock catchBlock = make.Block(0L, List.<JCStatement>of(addSuppressionStatement));
List<JCCatch> catchClauses = List.<JCCatch>of(make.Catch(catchExceptionDecl, catchBlock));
JCTry tryTree = make.Try(tryBlock, catchClauses, null);
! // if (primaryException != null) {try...} else resourceClose;
! JCIf closeIfStatement = make.If(makeNonNullCheck(make.Ident(primaryException)),
tryTree,
makeResourceCloseInvocation(resource));
!
! // if (#resource != null) { if (primaryException ... }
! return make.Block(0L,
! List.<JCStatement>of(make.If(makeNonNullCheck(resource),
! closeIfStatement,
! null)));
}
private JCStatement makeResourceCloseInvocation(JCExpression resource) {
// create resource.close() method invocation
! JCExpression resourceClose = makeCall(resource,
! names.close,
! List.<JCExpression>nil());
return make.Exec(resourceClose);
}
+ private JCExpression makeNonNullCheck(JCExpression expression) {
+ return makeBinary(JCTree.NE, expression, makeNull());
+ }
+
/** Construct a tree that represents the outer instance
* <C.this>. Never pick the current `this'.
* @param pos The source code position to be used for the tree.
* @param c The qualifier class.
*/
*** 3571,3581 ****
@Override
public void visitTry(JCTry tree) {
if (tree.resources.isEmpty()) {
super.visitTry(tree);
} else {
! result = makeArmTry(tree);
}
}
/**************************************************************************
* main method
--- 3609,3619 ----
@Override
public void visitTry(JCTry tree) {
if (tree.resources.isEmpty()) {
super.visitTry(tree);
} else {
! result = makeTwrTry(tree);
}
}
/**************************************************************************
* main method