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

Print this page




1383     }
1384 //where
1385         JCExpression loadFreevar(DiagnosticPosition pos, VarSymbol v) {
1386             return access(v, make.at(pos).Ident(v), null, false);
1387         }
1388 
1389     /** Construct a tree simulating the expression <C.this>.
1390      *  @param pos           The source code position to be used for the tree.
1391      *  @param c             The qualifier class.
1392      */
1393     JCExpression makeThis(DiagnosticPosition pos, TypeSymbol c) {
1394         if (currentClass == c) {
1395             // in this case, `this' works fine
1396             return make.at(pos).This(c.erasure(types));
1397         } else {
1398             // need to go via this$n
1399             return makeOuterThis(pos, c);
1400         }
1401     }
1402 



















































































































1403     /** Construct a tree that represents the outer instance
1404      *  <C.this>. Never pick the current `this'.
1405      *  @param pos           The source code position to be used for the tree.
1406      *  @param c             The qualifier class.
1407      */
1408     JCExpression makeOuterThis(DiagnosticPosition pos, TypeSymbol c) {
1409         List<VarSymbol> ots = outerThisStack;
1410         if (ots.isEmpty()) {
1411             log.error(pos, "no.encl.instance.of.type.in.scope", c);
1412             assert false;
1413             return makeNull();
1414         }
1415         VarSymbol ot = ots.head;
1416         JCExpression tree = access(make.at(pos).Ident(ot));
1417         TypeSymbol otc = ot.type.tsym;
1418         while (otc != c) {
1419             do {
1420                 ots = ots.tail;
1421                 if (ots.isEmpty()) {
1422                     log.error(pos,


3388         if (tree.name == names._class)
3389             result = classOf(tree.selected);
3390         else if (tree.name == names._this || tree.name == names._super)
3391             result = makeThis(tree.pos(), tree.selected.type.tsym);
3392         else
3393             result = access(tree.sym, tree, enclOp, qualifiedSuperAccess);
3394     }
3395 
3396     public void visitLetExpr(LetExpr tree) {
3397         tree.defs = translateVarDefs(tree.defs);
3398         tree.expr = translate(tree.expr, tree.type);
3399         result = tree;
3400     }
3401 
3402     // There ought to be nothing to rewrite here;
3403     // we don't generate code.
3404     public void visitAnnotation(JCAnnotation tree) {
3405         result = tree;
3406     }
3407 









3408 /**************************************************************************
3409  * main method
3410  *************************************************************************/
3411 
3412     /** Translate a toplevel class and return a list consisting of
3413      *  the translated class and translated versions of all inner classes.
3414      *  @param env   The attribution environment current at the class definition.
3415      *               We need this for resolving some additional symbols.
3416      *  @param cdef  The tree representing the class definition.
3417      */
3418     public List<JCTree> translateTopLevelClass(Env<AttrContext> env, JCTree cdef, TreeMaker make) {
3419         ListBuffer<JCTree> translated = null;
3420         try {
3421             attrEnv = env;
3422             this.make = make;
3423             endPositions = env.toplevel.endPositions;
3424             currentClass = null;
3425             currentMethodDef = null;
3426             outermostClassDef = (cdef.getTag() == JCTree.CLASSDEF) ? (JCClassDecl)cdef : null;
3427             outermostMemberDef = null;




1383     }
1384 //where
1385         JCExpression loadFreevar(DiagnosticPosition pos, VarSymbol v) {
1386             return access(v, make.at(pos).Ident(v), null, false);
1387         }
1388 
1389     /** Construct a tree simulating the expression <C.this>.
1390      *  @param pos           The source code position to be used for the tree.
1391      *  @param c             The qualifier class.
1392      */
1393     JCExpression makeThis(DiagnosticPosition pos, TypeSymbol c) {
1394         if (currentClass == c) {
1395             // in this case, `this' works fine
1396             return make.at(pos).This(c.erasure(types));
1397         } else {
1398             // need to go via this$n
1399             return makeOuterThis(pos, c);
1400         }
1401     }
1402 
1403     /** Optionally replace a try statement with an automatic resource management
1404      *  (ARM) block.
1405      * @param tree  The try statement to inspect.
1406      * @return      An ARM block, or the original try block if there are no
1407      *              resources to manage.
1408      */
1409     JCTree makeArmTry(JCTry tree) {
1410         make_at(tree.pos());
1411         JCBlock armBlock = makeArmBlock(tree.resources, tree.body, 0);
1412         if (tree.catchers.isEmpty() && tree.finalizer == null)
1413             result = translate(armBlock);
1414         else
1415             result = translate(make.Try(armBlock, tree.catchers, tree.finalizer));
1416         return result;
1417     }
1418 
1419     private JCBlock makeArmBlock(List<JCTree> resources, JCBlock block, int depth) {
1420         if (resources.isEmpty())
1421             return block;
1422 
1423         // Add resource declaration or expression to block statements
1424         ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
1425         JCTree resource = resources.head;
1426         JCExpression expr = null;
1427         if (resource instanceof JCVariableDecl) {
1428             JCVariableDecl var = (JCVariableDecl) resource;
1429             expr = make.Ident(var.sym).setType(resource.type);
1430             stats.add(var);
1431         } else {
1432             assert resource instanceof JCExpression;
1433             VarSymbol syntheticArmVar =
1434             new VarSymbol(SYNTHETIC | FINAL,
1435                           names.fromString("armVar" +
1436                                            resource.pos +
1437                                            target.syntheticNameChar()),
1438                           (resource.type.tag == TypeTags.BOT) ?
1439                           syms.autoCloseableType : resource.type,
1440                           currentMethodSym);
1441             JCVariableDecl syntheticArmVarDecl =
1442                 make.VarDef(syntheticArmVar, (JCExpression)resource);
1443             expr = (JCExpression)make.Ident(syntheticArmVar);
1444             stats.add(syntheticArmVarDecl);
1445         }
1446 
1447         // Add primaryException declaration
1448         VarSymbol primaryException =
1449             new VarSymbol(SYNTHETIC,
1450                           names.fromString("primaryException" +
1451                                            resource.pos +
1452                                            target.syntheticNameChar()),
1453                           syms.throwableType,
1454                           currentMethodSym);
1455         JCVariableDecl primaryExceptionTreeDecl = make.VarDef(primaryException, makeNull());
1456         stats.add(primaryExceptionTreeDecl);
1457 
1458         // Create catch clause that saves exception and then rethrows it
1459         VarSymbol param =
1460             new VarSymbol(FINAL|SYNTHETIC,
1461                           names.fromString("t" +
1462                                            resource.pos +
1463                                            target.syntheticNameChar()),
1464                           syms.throwableType,
1465                           currentMethodSym);
1466         JCVariableDecl paramTree = make.VarDef(param, null);
1467         JCStatement assign = make.Assignment(primaryException, make.Ident(param));
1468         JCStatement rethrowStat = make.Throw(make.Ident(param));
1469         JCBlock catchBlock = make.Block(0L, List.<JCStatement>of(assign, rethrowStat));
1470         JCCatch catchClause = make.Catch(paramTree, catchBlock);
1471 
1472         int oldPos = make.pos;
1473         make.at(TreeInfo.endPos(block));
1474         JCBlock finallyClause = makeArmFinallyClause(primaryException, expr);
1475         make.at(oldPos);
1476         JCTry outerTry = make.Try(makeArmBlock(resources.tail, block, depth + 1),
1477                                   List.<JCCatch>of(catchClause),
1478                                   finallyClause);
1479         stats.add(outerTry);
1480         return make.Block(0L, stats.toList());
1481     }
1482    
1483     private JCBlock makeArmFinallyClause(Symbol primaryException, JCExpression resource) {
1484         // primaryException.addSuppressedException(catchException);
1485         VarSymbol catchException =
1486             new VarSymbol(0, make.paramName(2),
1487                           syms.throwableType,
1488                           currentMethodSym);
1489         JCStatement addSuppressionStatement =
1490             make.Exec(makeCall(make.Ident(primaryException),
1491                                names.fromString("addSuppressedException"),
1492                                List.<JCExpression>of(make.Ident(catchException))));
1493 
1494         // try { resource.close(); } catch (e) { primaryException.addSuppressedException(e); }
1495         JCBlock tryBlock =
1496             make.Block(0L, List.<JCStatement>of(makeResourceCloseInvocation(resource)));
1497         JCVariableDecl catchExceptionDecl = make.VarDef(catchException, null);
1498         JCBlock catchBlock = make.Block(0L, List.<JCStatement>of(addSuppressionStatement));
1499         List<JCCatch> catchClauses = List.<JCCatch>of(make.Catch(catchExceptionDecl, catchBlock));
1500         JCTry tryTree = make.Try(tryBlock, catchClauses, null);
1501 
1502         // if (resource != null) resourceClose;
1503         JCExpression nullCheck = makeBinary(JCTree.NE,
1504                                             make.Ident(primaryException),
1505                                             makeNull());
1506         JCIf closeIfStatement = make.If(nullCheck,
1507                                         tryTree,
1508                                         makeResourceCloseInvocation(resource));
1509         return make.Block(0L, List.<JCStatement>of(closeIfStatement));
1510     }
1511 
1512     private JCStatement makeResourceCloseInvocation(JCExpression resource) {
1513         // create resource.close() method invocation
1514         JCExpression resourceClose = makeCall(resource, names.close, List.<JCExpression>nil());
1515         return make.Exec(resourceClose);
1516     }
1517 
1518     /** Construct a tree that represents the outer instance
1519      *  <C.this>. Never pick the current `this'.
1520      *  @param pos           The source code position to be used for the tree.
1521      *  @param c             The qualifier class.
1522      */
1523     JCExpression makeOuterThis(DiagnosticPosition pos, TypeSymbol c) {
1524         List<VarSymbol> ots = outerThisStack;
1525         if (ots.isEmpty()) {
1526             log.error(pos, "no.encl.instance.of.type.in.scope", c);
1527             assert false;
1528             return makeNull();
1529         }
1530         VarSymbol ot = ots.head;
1531         JCExpression tree = access(make.at(pos).Ident(ot));
1532         TypeSymbol otc = ot.type.tsym;
1533         while (otc != c) {
1534             do {
1535                 ots = ots.tail;
1536                 if (ots.isEmpty()) {
1537                     log.error(pos,


3503         if (tree.name == names._class)
3504             result = classOf(tree.selected);
3505         else if (tree.name == names._this || tree.name == names._super)
3506             result = makeThis(tree.pos(), tree.selected.type.tsym);
3507         else
3508             result = access(tree.sym, tree, enclOp, qualifiedSuperAccess);
3509     }
3510 
3511     public void visitLetExpr(LetExpr tree) {
3512         tree.defs = translateVarDefs(tree.defs);
3513         tree.expr = translate(tree.expr, tree.type);
3514         result = tree;
3515     }
3516 
3517     // There ought to be nothing to rewrite here;
3518     // we don't generate code.
3519     public void visitAnnotation(JCAnnotation tree) {
3520         result = tree;
3521     }
3522 
3523     @Override
3524     public void visitTry(JCTry tree) {
3525         if (tree.resources.isEmpty()) {
3526             super.visitTry(tree);
3527         } else {
3528             result = makeArmTry(tree);
3529         }
3530     }
3531 
3532 /**************************************************************************
3533  * main method
3534  *************************************************************************/
3535 
3536     /** Translate a toplevel class and return a list consisting of
3537      *  the translated class and translated versions of all inner classes.
3538      *  @param env   The attribution environment current at the class definition.
3539      *               We need this for resolving some additional symbols.
3540      *  @param cdef  The tree representing the class definition.
3541      */
3542     public List<JCTree> translateTopLevelClass(Env<AttrContext> env, JCTree cdef, TreeMaker make) {
3543         ListBuffer<JCTree> translated = null;
3544         try {
3545             attrEnv = env;
3546             this.make = make;
3547             endPositions = env.toplevel.endPositions;
3548             currentClass = null;
3549             currentMethodDef = null;
3550             outermostClassDef = (cdef.getTag() == JCTree.CLASSDEF) ? (JCClassDecl)cdef : null;
3551             outermostMemberDef = null;