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             var.sym.flags_field |= FINAL;
1433             expr = make.Ident(var.sym);
1434             stats.add(var);
1435         } else {
1436             assert resource instanceof JCExpression;
1437             expr = (JCExpression)resource;
1438             stats.add(make.at(resource.pos()).Exec(expr));
1439         }
1440 
1441         // Add primaryException declaration
1442         VarSymbol primaryException =
1443             new VarSymbol(0, names.fromString("#primaryException" + depth),
1444                           syms.throwableType, currentMethodSym);
1445         JCVariableDecl primaryExceptionTreeDecl = make.VarDef(primaryException, makeNull());
1446         stats.add(primaryExceptionTreeDecl);
1447 
1448         // Create catch clause that saves exception and then rethrows it
1449         VarSymbol param =
1450             new VarSymbol(FINAL, names.fromString("t"), syms.throwableType, currentMethodSym);
1451         JCVariableDecl paramTree = make.VarDef(param, null);
1452         JCStatement assign = make.Assignment(primaryException, make.Ident(param));
1453         JCStatement rethrowStat = make.Throw(make.Ident(param));
1454         JCBlock catchBlock = make.Block(0L, List.<JCStatement>of(assign, rethrowStat));
1455         JCCatch catchClause = make.Catch(paramTree, catchBlock);
1456 
1457         int oldPos = make.pos;
1458         make.at(TreeInfo.endPos(block));
1459         JCBlock finallyClause = makeArmFinallyClause(primaryException, expr);
1460         make.at(oldPos);
1461         JCTry outerTry = make.Try(makeArmBlock(resources.tail, block, depth + 1),
1462                                   List.<JCCatch>of(catchClause),
1463                                   finallyClause);
1464         stats.add(outerTry);
1465         return make.Block(0L, stats.toList());
1466     }
1467    
1468     private JCBlock makeArmFinallyClause(Symbol primaryException, JCExpression resource) {
1469         // primaryException.addSuppressedException(catchException);
1470         VarSymbol catchException =
1471             new VarSymbol(0, make.paramName(2),
1472                           syms.throwableType,
1473                           currentMethodSym);
1474         JCStatement addSuppressionStatement =
1475                 make.Exec(makeCall(make.Ident(primaryException),
1476                                    names.fromString("addSuppressedException"),
1477                                    List.<JCExpression>of(make.Ident(catchException))));
1478 
1479         // try { resource.close(); } catch (e) { primaryException.addSuppressedException(e); }
1480         JCBlock tryBlock = make.Block(0L, List.<JCStatement>of(makeResourceCloseInvocation(resource)));
1481         JCVariableDecl catchExceptionDecl = make.VarDef(catchException, null);
1482         JCBlock catchBlock = make.Block(0L, List.<JCStatement>of(addSuppressionStatement));
1483         List<JCCatch> catchClauses = List.<JCCatch>of(make.Catch(catchExceptionDecl, catchBlock));
1484         JCTry tryTree = make.Try(tryBlock, catchClauses, null);
1485 
1486                 // if (resource != null) resourceClose;
1487                 JCExpression nullCheck = makeBinary(JCTree.NE, make.Ident(primaryException), makeNull());
1488                 JCIf closeIfStatement = make.If(nullCheck, tryTree, makeResourceCloseInvocation(resource));
1489         return make.Block(0L, List.<JCStatement>of(closeIfStatement));
1490     }
1491 
1492     private JCStatement makeResourceCloseInvocation(JCExpression resource) {
1493         // create resource.close() method invocation
1494         Type autoCloseableType = types.asSuper(resource.type, syms.autoCloseableType.tsym);
1495         Symbol closeMethod = autoCloseableType.tsym.members().lookup(names.close).sym;
1496         JCExpression closeInvocation = make.Select(resource, closeMethod);
1497         JCMethodInvocation resourceClose = make.Apply(List.<JCExpression>nil(),
1498                                                       closeInvocation,
1499                                                       List.<JCExpression>nil());
1500         resourceClose.type = closeMethod.type.getReturnType();
1501         return make.Exec(resourceClose);
1502         }
1503 
1504     /** Construct a tree that represents the outer instance
1505      *  <C.this>. Never pick the current `this'.
1506      *  @param pos           The source code position to be used for the tree.
1507      *  @param c             The qualifier class.
1508      */
1509     JCExpression makeOuterThis(DiagnosticPosition pos, TypeSymbol c) {
1510         List<VarSymbol> ots = outerThisStack;
1511         if (ots.isEmpty()) {
1512             log.error(pos, "no.encl.instance.of.type.in.scope", c);
1513             assert false;
1514             return makeNull();
1515         }
1516         VarSymbol ot = ots.head;
1517         JCExpression tree = access(make.at(pos).Ident(ot));
1518         TypeSymbol otc = ot.type.tsym;
1519         while (otc != c) {
1520             do {
1521                 ots = ots.tail;
1522                 if (ots.isEmpty()) {
1523                     log.error(pos,


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