< prev index next >

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

Print this page

 797 
 798     /** Look up a method in a given scope.
 799      */
 800     private MethodSymbol lookupMethod(DiagnosticPosition pos, Name name, Type qual, List<Type> args) {
 801         return rs.resolveInternalMethod(pos, attrEnv, qual, name, args, List.nil());
 802     }
 803 
 804     /** Anon inner classes are used as access constructor tags.
 805      * accessConstructorTag will use an existing anon class if one is available,
 806      * and synthesize a class (with makeEmptyClass) if one is not available.
 807      * However, there is a small possibility that an existing class will not
 808      * be generated as expected if it is inside a conditional with a constant
 809      * expression. If that is found to be the case, create an empty class tree here.
 810      */
 811     private void checkAccessConstructorTags() {
 812         for (List<ClassSymbol> l = accessConstrTags; l.nonEmpty(); l = l.tail) {
 813             ClassSymbol c = l.head;
 814             if (isTranslatedClassAvailable(c))
 815                 continue;
 816             // Create class definition tree.
 817             JCClassDecl cdec = makeEmptyClass(STATIC | SYNTHETIC,
 818                     c.outermostClass(), c.flatname, false);
 819             swapAccessConstructorTag(c, cdec.sym);
 820             translated.append(cdec);
 821         }
 822     }
 823     // where
 824     private boolean isTranslatedClassAvailable(ClassSymbol c) {
 825         for (JCTree tree: translated) {
 826             if (tree.hasTag(CLASSDEF)
 827                     && ((JCClassDecl) tree).sym == c) {
 828                 return true;
 829             }
 830         }
 831         return false;
 832     }
 833 
 834     void swapAccessConstructorTag(ClassSymbol oldCTag, ClassSymbol newCTag) {
 835         for (MethodSymbol methodSymbol : accessConstrs.values()) {
 836             Assert.check(methodSymbol.type.hasTag(METHOD));
 837             MethodType oldMethodType =

1123             sym.owner.enclClass() != currentClass) {
1124             // A constant is replaced by its constant value.
1125             Object cv = ((VarSymbol)sym).getConstValue();
1126             if (cv != null) {
1127                 make.at(tree.pos);
1128                 return makeLit(sym.type, cv);
1129             }
1130             if (lambdaTranslationMap != null && lambdaTranslationMap.get(sym) != null) {
1131                 return make.at(tree.pos).Ident(lambdaTranslationMap.get(sym));
1132             } else {
1133                 // Otherwise replace the variable by its proxy.
1134                 sym = proxies.get(sym);
1135                 Assert.check(sym != null && (sym.flags_field & FINAL) != 0);
1136                 tree = make.at(tree.pos).Ident(sym);
1137             }
1138         }
1139         JCExpression base = (tree.hasTag(SELECT)) ? ((JCFieldAccess) tree).selected : null;
1140         switch (sym.kind) {
1141         case TYP:
1142             if (sym.owner.kind != PCK) {



1143                 // Convert type idents to
1144                 // <flat name> or <package name> . <flat name>
1145                 Name flatname = Convert.shortName(sym.flatName());
1146                 while (base != null &&
1147                        TreeInfo.symbol(base) != null &&
1148                        TreeInfo.symbol(base).kind != PCK) {
1149                     base = (base.hasTag(SELECT))
1150                         ? ((JCFieldAccess) base).selected
1151                         : null;
1152                 }
1153                 if (tree.hasTag(IDENT)) {
1154                     ((JCIdent) tree).name = flatname;
1155                 } else if (base == null) {
1156                     tree = make.at(tree.pos).Ident(sym);
1157                     ((JCIdent) tree).name = flatname;



1158                 } else {
1159                     ((JCFieldAccess) tree).selected = base;
1160                     ((JCFieldAccess) tree).name = flatname;



1161                 }
1162             }
1163             break;
1164         case MTH: case VAR:
1165             if (sym.owner.kind == TYP) {
1166 
1167                 // Access methods are required for
1168                 //  - private members,
1169                 //  - protected members in a superclass of an
1170                 //    enclosing class contained in another package.
1171                 //  - all non-private members accessed via a qualified super.
1172                 boolean protAccess = refSuper && !needsPrivateAccess(sym)
1173                     || needsProtectedAccess(sym, tree);
1174                 boolean accReq = protAccess || needsPrivateAccess(sym);
1175 
1176                 // A base has to be supplied for
1177                 //  - simple identifiers accessing variables in outer classes.
1178                 boolean baseReq =
1179                     base == null &&
1180                     sym.owner != syms.predefClass &&

1269                 accessConstrs.put(constr, aconstr);
1270                 accessed.append(constr);
1271             }
1272             return aconstr;
1273         } else {
1274             return constr;
1275         }
1276     }
1277 
1278     /** Return an anonymous class nested in this toplevel class.
1279      */
1280     ClassSymbol accessConstructorTag() {
1281         ClassSymbol topClass = currentClass.outermostClass();
1282         ModuleSymbol topModle = topClass.packge().modle;
1283         for (int i = 1; ; i++) {
1284             Name flatname = names.fromString("" + topClass.getQualifiedName() +
1285                                             target.syntheticNameChar() +
1286                                             i);
1287             ClassSymbol ctag = chk.getCompiled(topModle, flatname);
1288             if (ctag == null)
1289                 ctag = makeEmptyClass(STATIC | SYNTHETIC, topClass).sym;
1290             else if (!ctag.isAnonymous())
1291                 continue;
1292             // keep a record of all tags, to verify that all are generated as required
1293             accessConstrTags = accessConstrTags.prepend(ctag);
1294             return ctag;
1295         }
1296     }
1297 
1298     /** Add all required access methods for a private symbol to enclosing class.
1299      *  @param sym       The symbol.
1300      */
1301     void makeAccessible(Symbol sym) {
1302         JCClassDecl cdef = classDef(sym.owner.enclClass());
1303         if (cdef == null) Assert.error("class def not found: " + sym + " in " + sym.owner);
1304         if (sym.name == names.init) {
1305             cdef.defs = cdef.defs.prepend(
1306                 accessConstructorDef(cdef.pos, sym, accessConstrs.get(sym)));
1307         } else {
1308             MethodSymbol[] accessors = accessSyms.get(sym);
1309             for (int i = 0; i < AccessCode.numberOfAccessCodes; i++) {

1445      *  @param pos        The source code position of the definition.
1446      *  @param freevars   The free variables.
1447      *  @param owner      The class in which the definitions go.
1448      */
1449     List<JCVariableDecl> freevarDefs(int pos, List<VarSymbol> freevars, Symbol owner) {
1450         return freevarDefs(pos, freevars, owner, 0);
1451     }
1452 
1453     List<JCVariableDecl> freevarDefs(int pos, List<VarSymbol> freevars, Symbol owner,
1454             long additionalFlags) {
1455         long flags = FINAL | SYNTHETIC | additionalFlags;
1456         List<JCVariableDecl> defs = List.nil();
1457         Set<Name> proxyNames = new HashSet<>();
1458         for (List<VarSymbol> l = freevars; l.nonEmpty(); l = l.tail) {
1459             VarSymbol v = l.head;
1460             int index = 0;
1461             Name proxyName;
1462             do {
1463                 proxyName = proxyName(v.name, index++);
1464             } while (!proxyNames.add(proxyName));

1465             VarSymbol proxy = new VarSymbol(
1466                 flags, proxyName, v.erasure(types), owner);
1467             proxies.put(v, proxy);
1468             JCVariableDecl vd = make.at(pos).VarDef(proxy, null);
1469             vd.vartype = access(vd.vartype);
1470             defs = defs.prepend(vd);
1471         }
1472         return defs;
1473     }
1474 
1475     /** The name of a this$n field
1476      *  @param type   The class referenced by the this$n field
1477      */
1478     Name outerThisName(Type type, Symbol owner) {
1479         Type t = type.getEnclosingType();
1480         int nestingLevel = 0;
1481         while (t.hasTag(CLASS)) {
1482             t = t.getEnclosingType();
1483             nestingLevel++;
1484         }
1485         Name result = names.fromString("this" + target.syntheticNameChar() + nestingLevel);
1486         while (owner.kind == TYP && ((ClassSymbol)owner).members().findFirst(result) != null)

1513     JCVariableDecl outerThisDef(int pos, MethodSymbol owner) {
1514         ClassSymbol c = owner.enclClass();
1515         boolean isMandated =
1516             // Anonymous constructors
1517             (owner.isConstructor() && owner.isAnonymous()) ||
1518             // Constructors of non-private inner member classes
1519             (owner.isConstructor() && c.isInner() &&
1520              !c.isPrivate() && !c.isStatic());
1521         long flags =
1522             FINAL | (isMandated ? MANDATED : SYNTHETIC) | PARAMETER;
1523         VarSymbol outerThis = makeOuterThisVarSymbol(owner, flags);
1524         owner.extraParams = owner.extraParams.prepend(outerThis);
1525         return makeOuterThisVarDecl(pos, outerThis);
1526     }
1527 
1528     /** Definition for this$n field.
1529      *  @param pos        The source code position of the definition.
1530      *  @param owner      The class in which the definition goes.
1531      */
1532     JCVariableDecl outerThisDef(int pos, ClassSymbol owner) {
1533         VarSymbol outerThis = makeOuterThisVarSymbol(owner, FINAL | SYNTHETIC);


1534         return makeOuterThisVarDecl(pos, outerThis);
1535     }
1536 
1537     /** Return a list of trees that load the free variables in given list,
1538      *  in reverse order.
1539      *  @param pos          The source code position to be used for the trees.
1540      *  @param freevars     The list of free variables.
1541      */
1542     List<JCExpression> loadFreevars(DiagnosticPosition pos, List<VarSymbol> freevars) {
1543         List<JCExpression> args = List.nil();
1544         for (List<VarSymbol> l = freevars; l.nonEmpty(); l = l.tail)
1545             args = args.prepend(loadFreevar(pos, l.head));
1546         return args;
1547     }
1548 //where
1549         JCExpression loadFreevar(DiagnosticPosition pos, VarSymbol v) {
1550             return access(v, make.at(pos).Ident(v), null, false);
1551         }
1552 
1553     /** Construct a tree simulating the expression {@code C.this}.

1696         }
1697 
1698         JCStatement exceptionalRethrow = make.Throw(make.Ident(primaryException));
1699         JCBlock exceptionalCloseBlock = make.Block(0L, List.of(exceptionalCloseStatement, exceptionalRethrow));
1700         JCCatch exceptionalCatchClause = make.Catch(primaryExceptionDecl, exceptionalCloseBlock);
1701 
1702         //create the main try statement with the close:
1703         JCTry outerTry = make.Try(makeTwrBlock(resources.tail, block, depth + 1),
1704                                   List.of(exceptionalCatchClause),
1705                                   finallyClause);
1706 
1707         outerTry.finallyCanCompleteNormally = true;
1708         stats.add(outerTry);
1709 
1710         JCBlock newBlock = make.Block(0L, stats.toList());
1711         return newBlock;
1712     }
1713 
1714     private JCStatement makeResourceCloseInvocation(JCExpression resource) {
1715         // convert to AutoCloseable if needed
1716         if (types.asSuper(resource.type, syms.autoCloseableType.tsym) == null) {
1717             resource = convert(resource, syms.autoCloseableType);
1718         }
1719 
1720         // create resource.close() method invocation
1721         JCExpression resourceClose = makeCall(resource,
1722                                               names.close,
1723                                               List.nil());
1724         return make.Exec(resourceClose);
1725     }
1726 
1727     private JCExpression makeNonNullCheck(JCExpression expression) {
1728         return makeBinary(NE, expression, makeNull());
1729     }
1730 
1731     /** Construct a tree that represents the outer instance
1732      *  {@code C.this}. Never pick the current `this'.
1733      *  @param pos           The source code position to be used for the tree.
1734      *  @param c             The qualifier class.
1735      */
1736     JCExpression makeOuterThis(DiagnosticPosition pos, TypeSymbol c) {

1848     }
1849 
1850 /**************************************************************************
1851  * Code for .class
1852  *************************************************************************/
1853 
1854     /** Return the symbol of a class to contain a cache of
1855      *  compiler-generated statics such as class$ and the
1856      *  $assertionsDisabled flag.  We create an anonymous nested class
1857      *  (unless one already exists) and return its symbol.  However,
1858      *  for backward compatibility in 1.4 and earlier we use the
1859      *  top-level class itself.
1860      */
1861     private ClassSymbol outerCacheClass() {
1862         ClassSymbol clazz = outermostClassDef.sym;
1863         Scope s = clazz.members();
1864         for (Symbol sym : s.getSymbols(NON_RECURSIVE))
1865             if (sym.kind == TYP &&
1866                 sym.name == names.empty &&
1867                 (sym.flags() & INTERFACE) == 0) return (ClassSymbol) sym;
1868         return makeEmptyClass(STATIC | SYNTHETIC, clazz).sym;
1869     }
1870 
1871     /** Create an attributed tree of the form left.name(). */
1872     private JCMethodInvocation makeCall(JCExpression left, Name name, List<JCExpression> args) {
1873         Assert.checkNonNull(left.type);
1874         Symbol funcsym = lookupMethod(make_pos, name, left.type,
1875                                       TreeInfo.types(args));
1876         return make.App(make.Select(left, funcsym), args);
1877     }
1878 
1879     /** The tree simulating a T.class expression.
1880      *  @param clazz      The tree identifying type T.
1881      */
1882     private JCExpression classOf(JCTree clazz) {
1883         return classOfType(clazz.type, clazz.pos());
1884     }
1885 
1886     private JCExpression classOfType(Type type, DiagnosticPosition pos) {
1887         switch (type.getTag()) {
1888         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:

1900                 VarSymbol sym = new VarSymbol(
1901                         STATIC | PUBLIC | FINAL, names._class,
1902                         syms.classType, type.tsym);
1903                 return make_at(pos).Select(make.Type(type), sym);
1904         default:
1905             throw new AssertionError();
1906         }
1907     }
1908 
1909 /**************************************************************************
1910  * Code for enabling/disabling assertions.
1911  *************************************************************************/
1912 
1913     private ClassSymbol assertionsDisabledClassCache;
1914 
1915     /**Used to create an auxiliary class to hold $assertionsDisabled for interfaces.
1916      */
1917     private ClassSymbol assertionsDisabledClass() {
1918         if (assertionsDisabledClassCache != null) return assertionsDisabledClassCache;
1919 
1920         assertionsDisabledClassCache = makeEmptyClass(STATIC | SYNTHETIC, outermostClassDef.sym).sym;
1921 
1922         return assertionsDisabledClassCache;
1923     }
1924 
1925     // This code is not particularly robust if the user has
1926     // previously declared a member named '$assertionsDisabled'.
1927     // The same faulty idiom also appears in the translation of
1928     // class literals above.  We should report an error if a
1929     // previous declaration is not synthetic.
1930 
1931     private JCExpression assertFlagTest(DiagnosticPosition pos) {
1932         // Outermost class may be either true class or an interface.
1933         ClassSymbol outermostClass = outermostClassDef.sym;
1934 
1935         //only classes can hold a non-public field, look for a usable one:
1936         ClassSymbol container = !currentClass.isInterface() ? currentClass :
1937                 assertionsDisabledClass();
1938 
1939         VarSymbol assertDisabledSym =
1940             (VarSymbol)lookupSynthetic(dollarAssertionsDisabled,

2080     /** Visitor method: Translate a single node.
2081      *  Attach the source position from the old tree to its replacement tree.
2082      */
2083     @Override
2084     public <T extends JCTree> T translate(T tree) {
2085         if (tree == null) {
2086             return null;
2087         } else {
2088             make_at(tree.pos());
2089             T result = super.translate(tree);
2090             if (endPosTable != null && result != tree) {
2091                 endPosTable.replaceTree(tree, result);
2092             }
2093             return result;
2094         }
2095     }
2096 
2097     /** Visitor method: Translate a single node, boxing or unboxing if needed.
2098      */
2099     public <T extends JCExpression> T translate(T tree, Type type) {
2100         return (tree == null) ? null : boxIfNeeded(translate(tree), type);

2101     }
2102 
2103     /** Visitor method: Translate tree.
2104      */
2105     public <T extends JCTree> T translate(T tree, JCExpression enclOp) {
2106         JCExpression prevEnclOp = this.enclOp;
2107         this.enclOp = enclOp;
2108         T res = translate(tree);
2109         this.enclOp = prevEnclOp;
2110         return res;
2111     }
2112 
2113     /** Visitor method: Translate list of trees.
2114      */
2115     public <T extends JCExpression> List<T> translate(List<T> trees, Type type) {
2116         if (trees == null) return null;
2117         for (List<T> l = trees; l.nonEmpty(); l = l.tail)
2118             l.head = translate(l.head, type);
2119         return trees;
2120     }

2219             encl.trans_local = encl.trans_local.prepend(currentClass);
2220         }
2221 
2222         // Recursively translate members, taking into account that new members
2223         // might be created during the translation and prepended to the member
2224         // list `tree.defs'.
2225         List<JCTree> seen = List.nil();
2226         while (tree.defs != seen) {
2227             List<JCTree> unseen = tree.defs;
2228             for (List<JCTree> l = unseen; l.nonEmpty() && l != seen; l = l.tail) {
2229                 JCTree outermostMemberDefPrev = outermostMemberDef;
2230                 if (outermostMemberDefPrev == null) outermostMemberDef = l.head;
2231                 l.head = translate(l.head);
2232                 outermostMemberDef = outermostMemberDefPrev;
2233             }
2234             seen = unseen;
2235         }
2236 
2237         // Convert a protected modifier to public, mask static modifier.
2238         if ((tree.mods.flags & PROTECTED) != 0) tree.mods.flags |= PUBLIC;
2239         tree.mods.flags &= ClassFlags;
2240 
2241         // Convert name to flat representation, replacing '.' by '$'.
2242         tree.name = Convert.shortName(currentClass.flatName());
2243 
2244         // Add free variables proxy definitions to class.
2245 
2246         for (List<JCVariableDecl> l = fvdefs; l.nonEmpty(); l = l.tail) {
2247             tree.defs = tree.defs.prepend(l.head);
2248             enterSynthetic(tree.pos(), l.head.sym, currentClass.members());
2249         }
2250         // If this$n was accessed, add the field definition and
2251         // update initial constructors to initialize it
2252         if (currentClass.hasOuterInstance() && shouldEmitOuterThis(currentClass)) {
2253             tree.defs = tree.defs.prepend(otdef);
2254             enterSynthetic(tree.pos(), otdef.sym, currentClass.members());
2255 
2256            for (JCTree def : tree.defs) {
2257                 if (TreeInfo.isInitialConstructor(def)) {
2258                   JCMethodDecl mdef = (JCMethodDecl) def;
2259                   mdef.body.stats = mdef.body.stats.prepend(

3099             while (args.nonEmpty()) {
3100                 JCExpression arg = translate(args.head, varargsElement);
3101                 elems.append(arg);
3102                 args = args.tail;
3103             }
3104             JCNewArray boxedArgs = make.NewArray(make.Type(varargsElement),
3105                                                List.nil(),
3106                                                elems.toList());
3107             boxedArgs.type = new ArrayType(varargsElement, syms.arrayClass);
3108             result.append(boxedArgs);
3109         } else {
3110             if (args.length() != 1) throw new AssertionError(args);
3111             JCExpression arg = translate(args.head, parameter);
3112             anyChanges |= (arg != args.head);
3113             result.append(arg);
3114             if (!anyChanges) return _args;
3115         }
3116         return result.toList();
3117     }
3118 














3119     /** Expand a boxing or unboxing conversion if needed. */
3120     @SuppressWarnings("unchecked") // XXX unchecked
3121     <T extends JCExpression> T boxIfNeeded(T tree, Type type) {
3122         boolean havePrimitive = tree.type.isPrimitive();
3123         if (havePrimitive == type.isPrimitive())
3124             return tree;
3125         if (havePrimitive) {
3126             Type unboxedTarget = types.unboxedType(type);
3127             if (!unboxedTarget.hasTag(NONE)) {
3128                 if (!types.isSubtype(tree.type, unboxedTarget)) //e.g. Character c = 89;
3129                     tree.type = unboxedTarget.constType(tree.type.constValue());
3130                 return (T)boxPrimitive(tree, types.erasure(type));
3131             } else {
3132                 tree = (T)boxPrimitive(tree);
3133             }
3134         } else {
3135             tree = (T)unbox(tree, type);
3136         }
3137         return tree;
3138     }

3497          * A statement of the form
3498          *
3499          * <pre>
3500          *     for ( T v : coll ) stmt ;
3501          * </pre>
3502          *
3503          * (where coll implements {@code Iterable<? extends T>}) gets translated to
3504          *
3505          * <pre>{@code
3506          *     for ( Iterator<? extends T> #i = coll.iterator(); #i.hasNext(); ) {
3507          *         T v = (T) #i.next();
3508          *         stmt;
3509          *     }
3510          * }</pre>
3511          *
3512          * where #i is a freshly named synthetic local variable.
3513          */
3514         private void visitIterableForeachLoop(JCEnhancedForLoop tree) {
3515             make_at(tree.expr.pos());
3516             Type iteratorTarget = syms.objectType;
3517             Type iterableType = types.asSuper(types.cvarUpperBound(tree.expr.type),
3518                                               syms.iterableType.tsym);
3519             if (iterableType.getTypeArguments().nonEmpty())
3520                 iteratorTarget = types.erasure(iterableType.getTypeArguments().head);
3521             Type eType = types.skipTypeVars(tree.expr.type, false);
3522             tree.expr.type = types.erasure(eType);
3523             if (eType.isCompound())
3524                 tree.expr = make.TypeCast(types.erasure(iterableType), tree.expr);
3525             Symbol iterator = lookupMethod(tree.expr.pos(),
3526                                            names.iterator,
3527                                            eType,
3528                                            List.nil());
3529             VarSymbol itvar = new VarSymbol(SYNTHETIC, names.fromString("i" + target.syntheticNameChar()),
3530                                             types.erasure(types.asSuper(iterator.type.getReturnType(), syms.iteratorType.tsym)),
3531                                             currentMethodSym);
3532 
3533              JCStatement init = make.
3534                 VarDef(itvar, make.App(make.Select(tree.expr, iterator)
3535                      .setType(types.erasure(iterator.type))));
3536 
3537             Symbol hasNext = lookupMethod(tree.expr.pos(),
3538                                           names.hasNext,
3539                                           itvar.type,
3540                                           List.nil());
3541             JCMethodInvocation cond = make.App(make.Select(make.Ident(itvar), hasNext));
3542             Symbol next = lookupMethod(tree.expr.pos(),
3543                                        names.next,
3544                                        itvar.type,
3545                                        List.nil());
3546             JCExpression vardefinit = make.App(make.Select(make.Ident(itvar), next));
3547             if (tree.var.type.isPrimitive())
3548                 vardefinit = make.TypeCast(types.cvarUpperBound(iteratorTarget), vardefinit);
3549             else
3550                 vardefinit = make.TypeCast(tree.var.type, vardefinit);

3587                 new MethodSymbol(tree.flags | BLOCK,
3588                                  names.empty, null,
3589                                  currentClass);
3590         }
3591         super.visitBlock(tree);
3592         currentMethodSym = oldMethodSym;
3593     }
3594 
3595     public void visitDoLoop(JCDoWhileLoop tree) {
3596         tree.body = translate(tree.body);
3597         tree.cond = translate(tree.cond, syms.booleanType);
3598         result = tree;
3599     }
3600 
3601     public void visitWhileLoop(JCWhileLoop tree) {
3602         tree.cond = translate(tree.cond, syms.booleanType);
3603         tree.body = translate(tree.body);
3604         result = tree;
3605     }
3606 

















3607     public void visitForLoop(JCForLoop tree) {
3608         tree.init = translate(tree.init);
3609         if (tree.cond != null)
3610             tree.cond = translate(tree.cond, syms.booleanType);
3611         tree.step = translate(tree.step);
3612         tree.body = translate(tree.body);
3613         result = tree;
3614     }
3615 
3616     public void visitReturn(JCReturn tree) {
3617         if (tree.expr != null)
3618             tree.expr = translate(tree.expr,
3619                                   types.erasure(currentMethodDef
3620                                                 .restype.type));
3621         result = tree;
3622     }
3623 
3624     public void visitSwitch(JCSwitch tree) {
3625         boolean matchException = tree.patternSwitch && !tree.wasEnumSelector;
3626         List<JCCase> cases = tree.patternSwitch ? addDefaultIfNeeded(matchException, tree.cases)

4077         tree.value = translate(tree.value, tree.target.type);
4078         result = tree;
4079     }
4080 
4081     public void visitNewArray(JCNewArray tree) {
4082         tree.elemtype = translate(tree.elemtype);
4083         for (List<JCExpression> t = tree.dims; t.tail != null; t = t.tail)
4084             if (t.head != null) t.head = translate(t.head, syms.intType);
4085         tree.elems = translate(tree.elems, types.elemtype(tree.type));
4086         result = tree;
4087     }
4088 
4089     public void visitSelect(JCFieldAccess tree) {
4090         // need to special case-access of the form C.super.x
4091         // these will always need an access method, unless C
4092         // is a default interface subclassed by the current class.
4093         boolean qualifiedSuperAccess =
4094             tree.selected.hasTag(SELECT) &&
4095             TreeInfo.name(tree.selected) == names._super &&
4096             !types.isDirectSuperInterface(((JCFieldAccess)tree.selected).selected.type.tsym, currentClass);





4097         tree.selected = translate(tree.selected);



4098         if (tree.name == names._class) {
4099             result = classOf(tree.selected);
4100         }
4101         else if (tree.name == names._super &&
4102                 types.isDirectSuperInterface(tree.selected.type.tsym, currentClass)) {
4103             //default super call!! Not a classic qualified super call
4104             TypeSymbol supSym = tree.selected.type.tsym;
4105             Assert.checkNonNull(types.asSuper(currentClass.type, supSym));
4106             result = tree;
4107         }
4108         else if (tree.name == names._this || tree.name == names._super) {
4109             result = makeThis(tree.pos(), tree.selected.type.tsym);
4110         }
4111         else
4112             result = access(tree.sym, tree, enclOp, qualifiedSuperAccess);
4113     }
4114 
4115     public void visitLetExpr(LetExpr tree) {
4116         tree.defs = translate(tree.defs);
4117         tree.expr = translate(tree.expr, tree.type);
4118         result = tree;
4119     }
4120 
4121     // There ought to be nothing to rewrite here;
4122     // we don't generate code.
4123     public void visitAnnotation(JCAnnotation tree) {
4124         result = tree;
4125     }

 797 
 798     /** Look up a method in a given scope.
 799      */
 800     private MethodSymbol lookupMethod(DiagnosticPosition pos, Name name, Type qual, List<Type> args) {
 801         return rs.resolveInternalMethod(pos, attrEnv, qual, name, args, List.nil());
 802     }
 803 
 804     /** Anon inner classes are used as access constructor tags.
 805      * accessConstructorTag will use an existing anon class if one is available,
 806      * and synthesize a class (with makeEmptyClass) if one is not available.
 807      * However, there is a small possibility that an existing class will not
 808      * be generated as expected if it is inside a conditional with a constant
 809      * expression. If that is found to be the case, create an empty class tree here.
 810      */
 811     private void checkAccessConstructorTags() {
 812         for (List<ClassSymbol> l = accessConstrTags; l.nonEmpty(); l = l.tail) {
 813             ClassSymbol c = l.head;
 814             if (isTranslatedClassAvailable(c))
 815                 continue;
 816             // Create class definition tree.
 817             JCClassDecl cdec = makeEmptyClass(STATIC | SYNTHETIC | IDENTITY_TYPE,
 818                     c.outermostClass(), c.flatname, false);
 819             swapAccessConstructorTag(c, cdec.sym);
 820             translated.append(cdec);
 821         }
 822     }
 823     // where
 824     private boolean isTranslatedClassAvailable(ClassSymbol c) {
 825         for (JCTree tree: translated) {
 826             if (tree.hasTag(CLASSDEF)
 827                     && ((JCClassDecl) tree).sym == c) {
 828                 return true;
 829             }
 830         }
 831         return false;
 832     }
 833 
 834     void swapAccessConstructorTag(ClassSymbol oldCTag, ClassSymbol newCTag) {
 835         for (MethodSymbol methodSymbol : accessConstrs.values()) {
 836             Assert.check(methodSymbol.type.hasTag(METHOD));
 837             MethodType oldMethodType =

1123             sym.owner.enclClass() != currentClass) {
1124             // A constant is replaced by its constant value.
1125             Object cv = ((VarSymbol)sym).getConstValue();
1126             if (cv != null) {
1127                 make.at(tree.pos);
1128                 return makeLit(sym.type, cv);
1129             }
1130             if (lambdaTranslationMap != null && lambdaTranslationMap.get(sym) != null) {
1131                 return make.at(tree.pos).Ident(lambdaTranslationMap.get(sym));
1132             } else {
1133                 // Otherwise replace the variable by its proxy.
1134                 sym = proxies.get(sym);
1135                 Assert.check(sym != null && (sym.flags_field & FINAL) != 0);
1136                 tree = make.at(tree.pos).Ident(sym);
1137             }
1138         }
1139         JCExpression base = (tree.hasTag(SELECT)) ? ((JCFieldAccess) tree).selected : null;
1140         switch (sym.kind) {
1141         case TYP:
1142             if (sym.owner.kind != PCK) {
1143                 // Make sure not to lose type fidelity due to symbol sharing between projections
1144                 boolean requireReferenceProjection =
1145                         tree.hasTag(SELECT) && ((JCFieldAccess) tree).name == names.ref && tree.type.isReferenceProjection();
1146                 // Convert type idents to
1147                 // <flat name> or <package name> . <flat name>
1148                 Name flatname = Convert.shortName(sym.flatName());
1149                 while (base != null &&
1150                        TreeInfo.symbol(base) != null &&
1151                        TreeInfo.symbol(base).kind != PCK) {
1152                     base = (base.hasTag(SELECT))
1153                         ? ((JCFieldAccess) base).selected
1154                         : null;
1155                 }
1156                 if (tree.hasTag(IDENT)) {
1157                     ((JCIdent) tree).name = flatname;
1158                 } else if (base == null) {
1159                     tree = make.at(tree.pos).Ident(sym);
1160                     ((JCIdent) tree).name = flatname;
1161                     if (requireReferenceProjection) {
1162                         tree.setType(tree.type.referenceProjection());
1163                     }
1164                 } else {
1165                     ((JCFieldAccess) tree).selected = base;
1166                     ((JCFieldAccess) tree).name = flatname;
1167                     if (requireReferenceProjection) {
1168                         tree.setType(tree.type.referenceProjection());
1169                     }
1170                 }
1171             }
1172             break;
1173         case MTH: case VAR:
1174             if (sym.owner.kind == TYP) {
1175 
1176                 // Access methods are required for
1177                 //  - private members,
1178                 //  - protected members in a superclass of an
1179                 //    enclosing class contained in another package.
1180                 //  - all non-private members accessed via a qualified super.
1181                 boolean protAccess = refSuper && !needsPrivateAccess(sym)
1182                     || needsProtectedAccess(sym, tree);
1183                 boolean accReq = protAccess || needsPrivateAccess(sym);
1184 
1185                 // A base has to be supplied for
1186                 //  - simple identifiers accessing variables in outer classes.
1187                 boolean baseReq =
1188                     base == null &&
1189                     sym.owner != syms.predefClass &&

1278                 accessConstrs.put(constr, aconstr);
1279                 accessed.append(constr);
1280             }
1281             return aconstr;
1282         } else {
1283             return constr;
1284         }
1285     }
1286 
1287     /** Return an anonymous class nested in this toplevel class.
1288      */
1289     ClassSymbol accessConstructorTag() {
1290         ClassSymbol topClass = currentClass.outermostClass();
1291         ModuleSymbol topModle = topClass.packge().modle;
1292         for (int i = 1; ; i++) {
1293             Name flatname = names.fromString("" + topClass.getQualifiedName() +
1294                                             target.syntheticNameChar() +
1295                                             i);
1296             ClassSymbol ctag = chk.getCompiled(topModle, flatname);
1297             if (ctag == null)
1298                 ctag = makeEmptyClass(STATIC | SYNTHETIC | IDENTITY_TYPE, topClass).sym;
1299             else if (!ctag.isAnonymous())
1300                 continue;
1301             // keep a record of all tags, to verify that all are generated as required
1302             accessConstrTags = accessConstrTags.prepend(ctag);
1303             return ctag;
1304         }
1305     }
1306 
1307     /** Add all required access methods for a private symbol to enclosing class.
1308      *  @param sym       The symbol.
1309      */
1310     void makeAccessible(Symbol sym) {
1311         JCClassDecl cdef = classDef(sym.owner.enclClass());
1312         if (cdef == null) Assert.error("class def not found: " + sym + " in " + sym.owner);
1313         if (sym.name == names.init) {
1314             cdef.defs = cdef.defs.prepend(
1315                 accessConstructorDef(cdef.pos, sym, accessConstrs.get(sym)));
1316         } else {
1317             MethodSymbol[] accessors = accessSyms.get(sym);
1318             for (int i = 0; i < AccessCode.numberOfAccessCodes; i++) {

1454      *  @param pos        The source code position of the definition.
1455      *  @param freevars   The free variables.
1456      *  @param owner      The class in which the definitions go.
1457      */
1458     List<JCVariableDecl> freevarDefs(int pos, List<VarSymbol> freevars, Symbol owner) {
1459         return freevarDefs(pos, freevars, owner, 0);
1460     }
1461 
1462     List<JCVariableDecl> freevarDefs(int pos, List<VarSymbol> freevars, Symbol owner,
1463             long additionalFlags) {
1464         long flags = FINAL | SYNTHETIC | additionalFlags;
1465         List<JCVariableDecl> defs = List.nil();
1466         Set<Name> proxyNames = new HashSet<>();
1467         for (List<VarSymbol> l = freevars; l.nonEmpty(); l = l.tail) {
1468             VarSymbol v = l.head;
1469             int index = 0;
1470             Name proxyName;
1471             do {
1472                 proxyName = proxyName(v.name, index++);
1473             } while (!proxyNames.add(proxyName));
1474             final Type type = v.erasure(types);
1475             VarSymbol proxy = new VarSymbol(
1476                 flags, proxyName, type, owner);
1477             proxies.put(v, proxy);
1478             JCVariableDecl vd = make.at(pos).VarDef(proxy, null);
1479             vd.vartype = access(vd.vartype);
1480             defs = defs.prepend(vd);
1481         }
1482         return defs;
1483     }
1484 
1485     /** The name of a this$n field
1486      *  @param type   The class referenced by the this$n field
1487      */
1488     Name outerThisName(Type type, Symbol owner) {
1489         Type t = type.getEnclosingType();
1490         int nestingLevel = 0;
1491         while (t.hasTag(CLASS)) {
1492             t = t.getEnclosingType();
1493             nestingLevel++;
1494         }
1495         Name result = names.fromString("this" + target.syntheticNameChar() + nestingLevel);
1496         while (owner.kind == TYP && ((ClassSymbol)owner).members().findFirst(result) != null)

1523     JCVariableDecl outerThisDef(int pos, MethodSymbol owner) {
1524         ClassSymbol c = owner.enclClass();
1525         boolean isMandated =
1526             // Anonymous constructors
1527             (owner.isConstructor() && owner.isAnonymous()) ||
1528             // Constructors of non-private inner member classes
1529             (owner.isConstructor() && c.isInner() &&
1530              !c.isPrivate() && !c.isStatic());
1531         long flags =
1532             FINAL | (isMandated ? MANDATED : SYNTHETIC) | PARAMETER;
1533         VarSymbol outerThis = makeOuterThisVarSymbol(owner, flags);
1534         owner.extraParams = owner.extraParams.prepend(outerThis);
1535         return makeOuterThisVarDecl(pos, outerThis);
1536     }
1537 
1538     /** Definition for this$n field.
1539      *  @param pos        The source code position of the definition.
1540      *  @param owner      The class in which the definition goes.
1541      */
1542     JCVariableDecl outerThisDef(int pos, ClassSymbol owner) {
1543         Type target = types.erasure(owner.enclClass().type.getEnclosingType());
1544         long flags = FINAL | SYNTHETIC;
1545         VarSymbol outerThis = makeOuterThisVarSymbol(owner, flags);
1546         return makeOuterThisVarDecl(pos, outerThis);
1547     }
1548 
1549     /** Return a list of trees that load the free variables in given list,
1550      *  in reverse order.
1551      *  @param pos          The source code position to be used for the trees.
1552      *  @param freevars     The list of free variables.
1553      */
1554     List<JCExpression> loadFreevars(DiagnosticPosition pos, List<VarSymbol> freevars) {
1555         List<JCExpression> args = List.nil();
1556         for (List<VarSymbol> l = freevars; l.nonEmpty(); l = l.tail)
1557             args = args.prepend(loadFreevar(pos, l.head));
1558         return args;
1559     }
1560 //where
1561         JCExpression loadFreevar(DiagnosticPosition pos, VarSymbol v) {
1562             return access(v, make.at(pos).Ident(v), null, false);
1563         }
1564 
1565     /** Construct a tree simulating the expression {@code C.this}.

1708         }
1709 
1710         JCStatement exceptionalRethrow = make.Throw(make.Ident(primaryException));
1711         JCBlock exceptionalCloseBlock = make.Block(0L, List.of(exceptionalCloseStatement, exceptionalRethrow));
1712         JCCatch exceptionalCatchClause = make.Catch(primaryExceptionDecl, exceptionalCloseBlock);
1713 
1714         //create the main try statement with the close:
1715         JCTry outerTry = make.Try(makeTwrBlock(resources.tail, block, depth + 1),
1716                                   List.of(exceptionalCatchClause),
1717                                   finallyClause);
1718 
1719         outerTry.finallyCanCompleteNormally = true;
1720         stats.add(outerTry);
1721 
1722         JCBlock newBlock = make.Block(0L, stats.toList());
1723         return newBlock;
1724     }
1725 
1726     private JCStatement makeResourceCloseInvocation(JCExpression resource) {
1727         // convert to AutoCloseable if needed
1728         if (types.asSuper(resource.type.referenceProjectionOrSelf(), syms.autoCloseableType.tsym) == null) {
1729             resource = convert(resource, syms.autoCloseableType);
1730         }
1731 
1732         // create resource.close() method invocation
1733         JCExpression resourceClose = makeCall(resource,
1734                                               names.close,
1735                                               List.nil());
1736         return make.Exec(resourceClose);
1737     }
1738 
1739     private JCExpression makeNonNullCheck(JCExpression expression) {
1740         return makeBinary(NE, expression, makeNull());
1741     }
1742 
1743     /** Construct a tree that represents the outer instance
1744      *  {@code C.this}. Never pick the current `this'.
1745      *  @param pos           The source code position to be used for the tree.
1746      *  @param c             The qualifier class.
1747      */
1748     JCExpression makeOuterThis(DiagnosticPosition pos, TypeSymbol c) {

1860     }
1861 
1862 /**************************************************************************
1863  * Code for .class
1864  *************************************************************************/
1865 
1866     /** Return the symbol of a class to contain a cache of
1867      *  compiler-generated statics such as class$ and the
1868      *  $assertionsDisabled flag.  We create an anonymous nested class
1869      *  (unless one already exists) and return its symbol.  However,
1870      *  for backward compatibility in 1.4 and earlier we use the
1871      *  top-level class itself.
1872      */
1873     private ClassSymbol outerCacheClass() {
1874         ClassSymbol clazz = outermostClassDef.sym;
1875         Scope s = clazz.members();
1876         for (Symbol sym : s.getSymbols(NON_RECURSIVE))
1877             if (sym.kind == TYP &&
1878                 sym.name == names.empty &&
1879                 (sym.flags() & INTERFACE) == 0) return (ClassSymbol) sym;
1880         return makeEmptyClass(STATIC | SYNTHETIC | IDENTITY_TYPE, clazz).sym;
1881     }
1882 
1883     /** Create an attributed tree of the form left.name(). */
1884     private JCMethodInvocation makeCall(JCExpression left, Name name, List<JCExpression> args) {
1885         Assert.checkNonNull(left.type);
1886         Symbol funcsym = lookupMethod(make_pos, name, left.type,
1887                                       TreeInfo.types(args));
1888         return make.App(make.Select(left, funcsym), args);
1889     }
1890 
1891     /** The tree simulating a T.class expression.
1892      *  @param clazz      The tree identifying type T.
1893      */
1894     private JCExpression classOf(JCTree clazz) {
1895         return classOfType(clazz.type, clazz.pos());
1896     }
1897 
1898     private JCExpression classOfType(Type type, DiagnosticPosition pos) {
1899         switch (type.getTag()) {
1900         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:

1912                 VarSymbol sym = new VarSymbol(
1913                         STATIC | PUBLIC | FINAL, names._class,
1914                         syms.classType, type.tsym);
1915                 return make_at(pos).Select(make.Type(type), sym);
1916         default:
1917             throw new AssertionError();
1918         }
1919     }
1920 
1921 /**************************************************************************
1922  * Code for enabling/disabling assertions.
1923  *************************************************************************/
1924 
1925     private ClassSymbol assertionsDisabledClassCache;
1926 
1927     /**Used to create an auxiliary class to hold $assertionsDisabled for interfaces.
1928      */
1929     private ClassSymbol assertionsDisabledClass() {
1930         if (assertionsDisabledClassCache != null) return assertionsDisabledClassCache;
1931 
1932         assertionsDisabledClassCache = makeEmptyClass(STATIC | SYNTHETIC | IDENTITY_TYPE, outermostClassDef.sym).sym;
1933 
1934         return assertionsDisabledClassCache;
1935     }
1936 
1937     // This code is not particularly robust if the user has
1938     // previously declared a member named '$assertionsDisabled'.
1939     // The same faulty idiom also appears in the translation of
1940     // class literals above.  We should report an error if a
1941     // previous declaration is not synthetic.
1942 
1943     private JCExpression assertFlagTest(DiagnosticPosition pos) {
1944         // Outermost class may be either true class or an interface.
1945         ClassSymbol outermostClass = outermostClassDef.sym;
1946 
1947         //only classes can hold a non-public field, look for a usable one:
1948         ClassSymbol container = !currentClass.isInterface() ? currentClass :
1949                 assertionsDisabledClass();
1950 
1951         VarSymbol assertDisabledSym =
1952             (VarSymbol)lookupSynthetic(dollarAssertionsDisabled,

2092     /** Visitor method: Translate a single node.
2093      *  Attach the source position from the old tree to its replacement tree.
2094      */
2095     @Override
2096     public <T extends JCTree> T translate(T tree) {
2097         if (tree == null) {
2098             return null;
2099         } else {
2100             make_at(tree.pos());
2101             T result = super.translate(tree);
2102             if (endPosTable != null && result != tree) {
2103                 endPosTable.replaceTree(tree, result);
2104             }
2105             return result;
2106         }
2107     }
2108 
2109     /** Visitor method: Translate a single node, boxing or unboxing if needed.
2110      */
2111     public <T extends JCExpression> T translate(T tree, Type type) {
2112         return (tree == null) ? null :
2113                 applyPrimitiveConversionsAsNeeded(boxIfNeeded(translate(tree), type), type);
2114     }
2115 
2116     /** Visitor method: Translate tree.
2117      */
2118     public <T extends JCTree> T translate(T tree, JCExpression enclOp) {
2119         JCExpression prevEnclOp = this.enclOp;
2120         this.enclOp = enclOp;
2121         T res = translate(tree);
2122         this.enclOp = prevEnclOp;
2123         return res;
2124     }
2125 
2126     /** Visitor method: Translate list of trees.
2127      */
2128     public <T extends JCExpression> List<T> translate(List<T> trees, Type type) {
2129         if (trees == null) return null;
2130         for (List<T> l = trees; l.nonEmpty(); l = l.tail)
2131             l.head = translate(l.head, type);
2132         return trees;
2133     }

2232             encl.trans_local = encl.trans_local.prepend(currentClass);
2233         }
2234 
2235         // Recursively translate members, taking into account that new members
2236         // might be created during the translation and prepended to the member
2237         // list `tree.defs'.
2238         List<JCTree> seen = List.nil();
2239         while (tree.defs != seen) {
2240             List<JCTree> unseen = tree.defs;
2241             for (List<JCTree> l = unseen; l.nonEmpty() && l != seen; l = l.tail) {
2242                 JCTree outermostMemberDefPrev = outermostMemberDef;
2243                 if (outermostMemberDefPrev == null) outermostMemberDef = l.head;
2244                 l.head = translate(l.head);
2245                 outermostMemberDef = outermostMemberDefPrev;
2246             }
2247             seen = unseen;
2248         }
2249 
2250         // Convert a protected modifier to public, mask static modifier.
2251         if ((tree.mods.flags & PROTECTED) != 0) tree.mods.flags |= PUBLIC;
2252         tree.mods.flags &= AdjustedClassFlags;
2253 
2254         // Convert name to flat representation, replacing '.' by '$'.
2255         tree.name = Convert.shortName(currentClass.flatName());
2256 
2257         // Add free variables proxy definitions to class.
2258 
2259         for (List<JCVariableDecl> l = fvdefs; l.nonEmpty(); l = l.tail) {
2260             tree.defs = tree.defs.prepend(l.head);
2261             enterSynthetic(tree.pos(), l.head.sym, currentClass.members());
2262         }
2263         // If this$n was accessed, add the field definition and
2264         // update initial constructors to initialize it
2265         if (currentClass.hasOuterInstance() && shouldEmitOuterThis(currentClass)) {
2266             tree.defs = tree.defs.prepend(otdef);
2267             enterSynthetic(tree.pos(), otdef.sym, currentClass.members());
2268 
2269            for (JCTree def : tree.defs) {
2270                 if (TreeInfo.isInitialConstructor(def)) {
2271                   JCMethodDecl mdef = (JCMethodDecl) def;
2272                   mdef.body.stats = mdef.body.stats.prepend(

3112             while (args.nonEmpty()) {
3113                 JCExpression arg = translate(args.head, varargsElement);
3114                 elems.append(arg);
3115                 args = args.tail;
3116             }
3117             JCNewArray boxedArgs = make.NewArray(make.Type(varargsElement),
3118                                                List.nil(),
3119                                                elems.toList());
3120             boxedArgs.type = new ArrayType(varargsElement, syms.arrayClass);
3121             result.append(boxedArgs);
3122         } else {
3123             if (args.length() != 1) throw new AssertionError(args);
3124             JCExpression arg = translate(args.head, parameter);
3125             anyChanges |= (arg != args.head);
3126             result.append(arg);
3127             if (!anyChanges) return _args;
3128         }
3129         return result.toList();
3130     }
3131 
3132     /** Apply primitive value/reference conversions as needed */
3133     @SuppressWarnings("unchecked")
3134     <T extends JCExpression> T applyPrimitiveConversionsAsNeeded(T tree, Type type) {
3135         boolean haveValue = tree.type.isPrimitiveClass();
3136         if (haveValue == type.isPrimitiveClass())
3137             return tree;
3138         // For narrowing conversion, insert a cast which should trigger a null check
3139         // For widening conversions, insert a cast if emitting a unified class file.
3140         return (T) make.TypeCast(type, tree);
3141 
3142     }
3143 
3144 
3145 
3146     /** Expand a boxing or unboxing conversion if needed. */
3147     @SuppressWarnings("unchecked") // XXX unchecked
3148     <T extends JCExpression> T boxIfNeeded(T tree, Type type) {
3149         boolean havePrimitive = tree.type.isPrimitive();
3150         if (havePrimitive == type.isPrimitive())
3151             return tree;
3152         if (havePrimitive) {
3153             Type unboxedTarget = types.unboxedType(type);
3154             if (!unboxedTarget.hasTag(NONE)) {
3155                 if (!types.isSubtype(tree.type, unboxedTarget)) //e.g. Character c = 89;
3156                     tree.type = unboxedTarget.constType(tree.type.constValue());
3157                 return (T)boxPrimitive(tree, types.erasure(type));
3158             } else {
3159                 tree = (T)boxPrimitive(tree);
3160             }
3161         } else {
3162             tree = (T)unbox(tree, type);
3163         }
3164         return tree;
3165     }

3524          * A statement of the form
3525          *
3526          * <pre>
3527          *     for ( T v : coll ) stmt ;
3528          * </pre>
3529          *
3530          * (where coll implements {@code Iterable<? extends T>}) gets translated to
3531          *
3532          * <pre>{@code
3533          *     for ( Iterator<? extends T> #i = coll.iterator(); #i.hasNext(); ) {
3534          *         T v = (T) #i.next();
3535          *         stmt;
3536          *     }
3537          * }</pre>
3538          *
3539          * where #i is a freshly named synthetic local variable.
3540          */
3541         private void visitIterableForeachLoop(JCEnhancedForLoop tree) {
3542             make_at(tree.expr.pos());
3543             Type iteratorTarget = syms.objectType;
3544             Type iterableType = types.asSuper(types.cvarUpperBound(tree.expr.type.referenceProjectionOrSelf()),
3545                                               syms.iterableType.tsym);
3546             if (iterableType.getTypeArguments().nonEmpty())
3547                 iteratorTarget = types.erasure(iterableType.getTypeArguments().head);
3548             Type eType = types.skipTypeVars(tree.expr.type, false);
3549             tree.expr.type = types.erasure(eType);
3550             if (eType.isCompound())
3551                 tree.expr = make.TypeCast(types.erasure(iterableType), tree.expr);
3552             Symbol iterator = lookupMethod(tree.expr.pos(),
3553                                            names.iterator,
3554                                            eType,
3555                                            List.nil());
3556             VarSymbol itvar = new VarSymbol(SYNTHETIC, names.fromString("i" + target.syntheticNameChar()),
3557                                             types.erasure(types.asSuper(iterator.type.getReturnType().referenceProjectionOrSelf(), syms.iteratorType.tsym)),
3558                                             currentMethodSym);
3559 
3560              JCStatement init = make.
3561                 VarDef(itvar, make.App(make.Select(tree.expr, iterator)
3562                      .setType(types.erasure(iterator.type))));
3563 
3564             Symbol hasNext = lookupMethod(tree.expr.pos(),
3565                                           names.hasNext,
3566                                           itvar.type,
3567                                           List.nil());
3568             JCMethodInvocation cond = make.App(make.Select(make.Ident(itvar), hasNext));
3569             Symbol next = lookupMethod(tree.expr.pos(),
3570                                        names.next,
3571                                        itvar.type,
3572                                        List.nil());
3573             JCExpression vardefinit = make.App(make.Select(make.Ident(itvar), next));
3574             if (tree.var.type.isPrimitive())
3575                 vardefinit = make.TypeCast(types.cvarUpperBound(iteratorTarget), vardefinit);
3576             else
3577                 vardefinit = make.TypeCast(tree.var.type, vardefinit);

3614                 new MethodSymbol(tree.flags | BLOCK,
3615                                  names.empty, null,
3616                                  currentClass);
3617         }
3618         super.visitBlock(tree);
3619         currentMethodSym = oldMethodSym;
3620     }
3621 
3622     public void visitDoLoop(JCDoWhileLoop tree) {
3623         tree.body = translate(tree.body);
3624         tree.cond = translate(tree.cond, syms.booleanType);
3625         result = tree;
3626     }
3627 
3628     public void visitWhileLoop(JCWhileLoop tree) {
3629         tree.cond = translate(tree.cond, syms.booleanType);
3630         tree.body = translate(tree.body);
3631         result = tree;
3632     }
3633 
3634     public void visitWithField(JCWithField tree) {
3635         Type fieldType = tree.field.type;
3636         tree.field = translate(tree.field, tree);
3637         tree.value = translate(tree.value, fieldType); // important to use pre-translation type.
3638 
3639         // If translated field is an Apply, we are
3640         // seeing an access method invocation. In this case, append
3641         // right hand side as last argument of the access method.
3642         if (tree.field.hasTag(APPLY)) {
3643             JCMethodInvocation app = (JCMethodInvocation) tree.field;
3644             app.args = List.of(tree.value).prependList(app.args);
3645             result = app;
3646         } else {
3647             result = tree;
3648         }
3649     }
3650 
3651     public void visitForLoop(JCForLoop tree) {
3652         tree.init = translate(tree.init);
3653         if (tree.cond != null)
3654             tree.cond = translate(tree.cond, syms.booleanType);
3655         tree.step = translate(tree.step);
3656         tree.body = translate(tree.body);
3657         result = tree;
3658     }
3659 
3660     public void visitReturn(JCReturn tree) {
3661         if (tree.expr != null)
3662             tree.expr = translate(tree.expr,
3663                                   types.erasure(currentMethodDef
3664                                                 .restype.type));
3665         result = tree;
3666     }
3667 
3668     public void visitSwitch(JCSwitch tree) {
3669         boolean matchException = tree.patternSwitch && !tree.wasEnumSelector;
3670         List<JCCase> cases = tree.patternSwitch ? addDefaultIfNeeded(matchException, tree.cases)

4121         tree.value = translate(tree.value, tree.target.type);
4122         result = tree;
4123     }
4124 
4125     public void visitNewArray(JCNewArray tree) {
4126         tree.elemtype = translate(tree.elemtype);
4127         for (List<JCExpression> t = tree.dims; t.tail != null; t = t.tail)
4128             if (t.head != null) t.head = translate(t.head, syms.intType);
4129         tree.elems = translate(tree.elems, types.elemtype(tree.type));
4130         result = tree;
4131     }
4132 
4133     public void visitSelect(JCFieldAccess tree) {
4134         // need to special case-access of the form C.super.x
4135         // these will always need an access method, unless C
4136         // is a default interface subclassed by the current class.
4137         boolean qualifiedSuperAccess =
4138             tree.selected.hasTag(SELECT) &&
4139             TreeInfo.name(tree.selected) == names._super &&
4140             !types.isDirectSuperInterface(((JCFieldAccess)tree.selected).selected.type.tsym, currentClass);
4141         /* JDK-8269956: Where a reflective (class) literal is needed, the unqualified Point.class is
4142          * always the "primary" mirror - representing the primitive reference runtime type - thereby
4143          * always matching the behavior of Object::getClass
4144          */
4145         boolean needPrimaryMirror = tree.name == names._class && tree.selected.type.isReferenceProjection();
4146         tree.selected = translate(tree.selected);
4147         if (needPrimaryMirror && tree.selected.type.isPrimitiveClass()) {
4148             tree.selected.setType(tree.selected.type.referenceProjection());
4149         }
4150         if (tree.name == names._class) {
4151             result = classOf(tree.selected);
4152         }
4153         else if (tree.name == names._super &&
4154                 types.isDirectSuperInterface(tree.selected.type.tsym, currentClass)) {
4155             //default super call!! Not a classic qualified super call
4156             TypeSymbol supSym = tree.selected.type.tsym;
4157             Assert.checkNonNull(types.asSuper(currentClass.type.referenceProjectionOrSelf(), supSym));
4158             result = tree;
4159         }
4160         else if (tree.name == names._this || tree.name == names._super) {
4161             result = makeThis(tree.pos(), tree.selected.type.tsym);
4162         }
4163         else
4164             result = access(tree.sym, tree, enclOp, qualifiedSuperAccess);
4165     }
4166 
4167     public void visitLetExpr(LetExpr tree) {
4168         tree.defs = translate(tree.defs);
4169         tree.expr = translate(tree.expr, tree.type);
4170         result = tree;
4171     }
4172 
4173     // There ought to be nothing to rewrite here;
4174     // we don't generate code.
4175     public void visitAnnotation(JCAnnotation tree) {
4176         result = tree;
4177     }
< prev index next >