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


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