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