src/share/classes/com/sun/tools/javac/comp/Lower.java

changeset 884
75e25df50873
parent 858
96d4226bdd60
child 901
02b699d97a55
equal deleted inserted replaced
883:51e643f41a3a 884:75e25df50873
1423 // need to go via this$n 1423 // need to go via this$n
1424 return makeOuterThis(pos, c); 1424 return makeOuterThis(pos, c);
1425 } 1425 }
1426 } 1426 }
1427 1427
1428 /** Optionally replace a try statement with an automatic resource 1428 /**
1429 * management (ARM) block. 1429 * Optionally replace a try statement with the desugaring of a
1430 * try-with-resources statement. The canonical desugaring of
1431 *
1432 * try ResourceSpecification
1433 * Block
1434 *
1435 * is
1436 *
1437 * {
1438 * final VariableModifiers_minus_final R #resource = Expression;
1439 * Throwable #primaryException = null;
1440 *
1441 * try ResourceSpecificationtail
1442 * Block
1443 * catch (Throwable #t) {
1444 * #primaryException = t;
1445 * throw #t;
1446 * } finally {
1447 * if (#resource != null) {
1448 * if (#primaryException != null) {
1449 * try {
1450 * #resource.close();
1451 * } catch(Throwable #suppressedException) {
1452 * #primaryException.addSuppressed(#suppressedException);
1453 * }
1454 * } else {
1455 * #resource.close();
1456 * }
1457 * }
1458 * }
1459 *
1430 * @param tree The try statement to inspect. 1460 * @param tree The try statement to inspect.
1431 * @return An ARM block, or the original try block if there are no 1461 * @return A a desugared try-with-resources tree, or the original
1432 * resources to manage. 1462 * try block if there are no resources to manage.
1433 */ 1463 */
1434 JCTree makeArmTry(JCTry tree) { 1464 JCTree makeTwrTry(JCTry tree) {
1435 make_at(tree.pos()); 1465 make_at(tree.pos());
1436 twrVars = twrVars.dup(); 1466 twrVars = twrVars.dup();
1437 JCBlock armBlock = makeArmBlock(tree.resources, tree.body, 0); 1467 JCBlock twrBlock = makeTwrBlock(tree.resources, tree.body, 0);
1438 if (tree.catchers.isEmpty() && tree.finalizer == null) 1468 if (tree.catchers.isEmpty() && tree.finalizer == null)
1439 result = translate(armBlock); 1469 result = translate(twrBlock);
1440 else 1470 else
1441 result = translate(make.Try(armBlock, tree.catchers, tree.finalizer)); 1471 result = translate(make.Try(twrBlock, tree.catchers, tree.finalizer));
1442 twrVars = twrVars.leave(); 1472 twrVars = twrVars.leave();
1443 return result; 1473 return result;
1444 } 1474 }
1445 1475
1446 private JCBlock makeArmBlock(List<JCTree> resources, JCBlock block, int depth) { 1476 private JCBlock makeTwrBlock(List<JCTree> resources, JCBlock block, int depth) {
1447 if (resources.isEmpty()) 1477 if (resources.isEmpty())
1448 return block; 1478 return block;
1449 1479
1450 // Add resource declaration or expression to block statements 1480 // Add resource declaration or expression to block statements
1451 ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>(); 1481 ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
1495 JCBlock catchBlock = make.Block(0L, List.<JCStatement>of(assign, rethrowStat)); 1525 JCBlock catchBlock = make.Block(0L, List.<JCStatement>of(assign, rethrowStat));
1496 JCCatch catchClause = make.Catch(paramTree, catchBlock); 1526 JCCatch catchClause = make.Catch(paramTree, catchBlock);
1497 1527
1498 int oldPos = make.pos; 1528 int oldPos = make.pos;
1499 make.at(TreeInfo.endPos(block)); 1529 make.at(TreeInfo.endPos(block));
1500 JCBlock finallyClause = makeArmFinallyClause(primaryException, expr); 1530 JCBlock finallyClause = makeTwrFinallyClause(primaryException, expr);
1501 make.at(oldPos); 1531 make.at(oldPos);
1502 JCTry outerTry = make.Try(makeArmBlock(resources.tail, block, depth + 1), 1532 JCTry outerTry = make.Try(makeTwrBlock(resources.tail, block, depth + 1),
1503 List.<JCCatch>of(catchClause), 1533 List.<JCCatch>of(catchClause),
1504 finallyClause); 1534 finallyClause);
1505 stats.add(outerTry); 1535 stats.add(outerTry);
1506 return make.Block(0L, stats.toList()); 1536 return make.Block(0L, stats.toList());
1507 } 1537 }
1508 1538
1509 private JCBlock makeArmFinallyClause(Symbol primaryException, JCExpression resource) { 1539 private JCBlock makeTwrFinallyClause(Symbol primaryException, JCExpression resource) {
1510 // primaryException.addSuppressed(catchException); 1540 // primaryException.addSuppressed(catchException);
1511 VarSymbol catchException = 1541 VarSymbol catchException =
1512 new VarSymbol(0, make.paramName(2), 1542 new VarSymbol(0, make.paramName(2),
1513 syms.throwableType, 1543 syms.throwableType,
1514 currentMethodSym); 1544 currentMethodSym);
1523 JCVariableDecl catchExceptionDecl = make.VarDef(catchException, null); 1553 JCVariableDecl catchExceptionDecl = make.VarDef(catchException, null);
1524 JCBlock catchBlock = make.Block(0L, List.<JCStatement>of(addSuppressionStatement)); 1554 JCBlock catchBlock = make.Block(0L, List.<JCStatement>of(addSuppressionStatement));
1525 List<JCCatch> catchClauses = List.<JCCatch>of(make.Catch(catchExceptionDecl, catchBlock)); 1555 List<JCCatch> catchClauses = List.<JCCatch>of(make.Catch(catchExceptionDecl, catchBlock));
1526 JCTry tryTree = make.Try(tryBlock, catchClauses, null); 1556 JCTry tryTree = make.Try(tryBlock, catchClauses, null);
1527 1557
1528 // if (resource != null) resourceClose; 1558 // if (primaryException != null) {try...} else resourceClose;
1529 JCExpression nullCheck = makeBinary(JCTree.NE, 1559 JCIf closeIfStatement = make.If(makeNonNullCheck(make.Ident(primaryException)),
1530 make.Ident(primaryException),
1531 makeNull());
1532 JCIf closeIfStatement = make.If(nullCheck,
1533 tryTree, 1560 tryTree,
1534 makeResourceCloseInvocation(resource)); 1561 makeResourceCloseInvocation(resource));
1535 return make.Block(0L, List.<JCStatement>of(closeIfStatement)); 1562
1563 // if (#resource != null) { if (primaryException ... }
1564 return make.Block(0L,
1565 List.<JCStatement>of(make.If(makeNonNullCheck(resource),
1566 closeIfStatement,
1567 null)));
1536 } 1568 }
1537 1569
1538 private JCStatement makeResourceCloseInvocation(JCExpression resource) { 1570 private JCStatement makeResourceCloseInvocation(JCExpression resource) {
1539 // create resource.close() method invocation 1571 // create resource.close() method invocation
1540 JCExpression resourceClose = makeCall(resource, names.close, List.<JCExpression>nil()); 1572 JCExpression resourceClose = makeCall(resource,
1573 names.close,
1574 List.<JCExpression>nil());
1541 return make.Exec(resourceClose); 1575 return make.Exec(resourceClose);
1576 }
1577
1578 private JCExpression makeNonNullCheck(JCExpression expression) {
1579 return makeBinary(JCTree.NE, expression, makeNull());
1542 } 1580 }
1543 1581
1544 /** Construct a tree that represents the outer instance 1582 /** Construct a tree that represents the outer instance
1545 * <C.this>. Never pick the current `this'. 1583 * <C.this>. Never pick the current `this'.
1546 * @param pos The source code position to be used for the tree. 1584 * @param pos The source code position to be used for the tree.
3571 @Override 3609 @Override
3572 public void visitTry(JCTry tree) { 3610 public void visitTry(JCTry tree) {
3573 if (tree.resources.isEmpty()) { 3611 if (tree.resources.isEmpty()) {
3574 super.visitTry(tree); 3612 super.visitTry(tree);
3575 } else { 3613 } else {
3576 result = makeArmTry(tree); 3614 result = makeTwrTry(tree);
3577 } 3615 }
3578 } 3616 }
3579 3617
3580 /************************************************************************** 3618 /**************************************************************************
3581 * main method 3619 * main method

mercurial