< prev index next >

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

Print this page

  85 
  86     private final Names names;
  87     private final Log log;
  88     private final Symtab syms;
  89     private final Resolve rs;
  90     private final Operators operators;
  91     private final Check chk;
  92     private final Attr attr;
  93     private TreeMaker make;
  94     private DiagnosticPosition make_pos;
  95     private final ConstFold cfolder;
  96     private final Target target;
  97     private final TypeEnvs typeEnvs;
  98     private final Name dollarAssertionsDisabled;
  99     private final Types types;
 100     private final TransTypes transTypes;
 101     private final boolean debugLower;
 102     private final boolean disableProtectedAccessors; // experimental
 103     private final PkgInfo pkginfoOpt;
 104     private final boolean optimizeOuterThis;

 105     private final boolean useMatchException;
 106 
 107     @SuppressWarnings("this-escape")
 108     protected Lower(Context context) {
 109         context.put(lowerKey, this);
 110         names = Names.instance(context);
 111         log = Log.instance(context);
 112         syms = Symtab.instance(context);
 113         rs = Resolve.instance(context);
 114         operators = Operators.instance(context);
 115         chk = Check.instance(context);
 116         attr = Attr.instance(context);
 117         make = TreeMaker.instance(context);
 118         cfolder = ConstFold.instance(context);
 119         target = Target.instance(context);
 120         typeEnvs = TypeEnvs.instance(context);
 121         dollarAssertionsDisabled = names.
 122             fromString(target.syntheticNameChar() + "assertionsDisabled");
 123 
 124         types = Types.instance(context);
 125         transTypes = TransTypes.instance(context);
 126         Options options = Options.instance(context);
 127         debugLower = options.isSet("debuglower");
 128         pkginfoOpt = PkgInfo.get(options);
 129         optimizeOuterThis =
 130             target.optimizeOuterThis() ||
 131             options.getBoolean("optimizeOuterThis", false);
 132         disableProtectedAccessors = options.isSet("disableProtectedAccessors");
 133         Source source = Source.instance(context);

 134         Preview preview = Preview.instance(context);
 135         useMatchException = Feature.PATTERN_SWITCH.allowedInSource(source) &&
 136                             (preview.isEnabled() || !preview.isPreview(Feature.PATTERN_SWITCH));
 137     }
 138 
 139     /** The currently enclosing class.
 140      */
 141     ClassSymbol currentClass;
 142 
 143     /** A queue of all translated classes.
 144      */
 145     ListBuffer<JCTree> translated;
 146 
 147     /** Environment for symbol lookup, set by translateTopLevelClass.
 148      */
 149     Env<AttrContext> attrEnv;
 150 
 151     /** A hash table mapping syntax trees to their ending source positions.
 152      */
 153     EndPosTable endPosTable;

 890 
 891     /** Look up a method in a given scope.
 892      */
 893     private MethodSymbol lookupMethod(DiagnosticPosition pos, Name name, Type qual, List<Type> args) {
 894         return rs.resolveInternalMethod(pos, attrEnv, qual, name, args, List.nil());
 895     }
 896 
 897     /** Anon inner classes are used as access constructor tags.
 898      * accessConstructorTag will use an existing anon class if one is available,
 899      * and synthesize a class (with makeEmptyClass) if one is not available.
 900      * However, there is a small possibility that an existing class will not
 901      * be generated as expected if it is inside a conditional with a constant
 902      * expression. If that is found to be the case, create an empty class tree here.
 903      */
 904     private void checkAccessConstructorTags() {
 905         for (List<ClassSymbol> l = accessConstrTags; l.nonEmpty(); l = l.tail) {
 906             ClassSymbol c = l.head;
 907             if (isTranslatedClassAvailable(c))
 908                 continue;
 909             // Create class definition tree.
 910             JCClassDecl cdec = makeEmptyClass(STATIC | SYNTHETIC,
 911                     c.outermostClass(), c.flatname, false);
 912             swapAccessConstructorTag(c, cdec.sym);
 913             translated.append(cdec);
 914         }
 915     }
 916     // where
 917     private boolean isTranslatedClassAvailable(ClassSymbol c) {
 918         for (JCTree tree: translated) {
 919             if (tree.hasTag(CLASSDEF)
 920                     && ((JCClassDecl) tree).sym == c) {
 921                 return true;
 922             }
 923         }
 924         return false;
 925     }
 926 
 927     void swapAccessConstructorTag(ClassSymbol oldCTag, ClassSymbol newCTag) {
 928         for (MethodSymbol methodSymbol : accessConstrs.values()) {
 929             Assert.check(methodSymbol.type.hasTag(METHOD));
 930             MethodType oldMethodType =

1127 
1128     /** The qualifier to be used for accessing a symbol in an outer class.
1129      *  This is either C.sym or C.this.sym, depending on whether or not
1130      *  sym is static.
1131      *  @param sym   The accessed symbol.
1132      */
1133     JCExpression accessBase(DiagnosticPosition pos, Symbol sym) {
1134         return (sym.flags() & STATIC) != 0
1135             ? access(make.at(pos.getStartPosition()).QualIdent(sym.owner))
1136             : makeOwnerThis(pos, sym, true);
1137     }
1138 
1139     /** Do we need an access method to reference private symbol?
1140      */
1141     boolean needsPrivateAccess(Symbol sym) {
1142         if (target.hasNestmateAccess()) {
1143             return false;
1144         }
1145         if ((sym.flags() & PRIVATE) == 0 || sym.owner == currentClass) {
1146             return false;
1147         } else if (sym.name == names.init && sym.owner.isDirectlyOrIndirectlyLocal()) {
1148             // private constructor in local class: relax protection
1149             sym.flags_field &= ~PRIVATE;
1150             return false;
1151         } else {
1152             return true;
1153         }
1154     }
1155 
1156     /** Do we need an access method to reference symbol in other package?
1157      */
1158     boolean needsProtectedAccess(Symbol sym, JCTree tree) {
1159         if (disableProtectedAccessors) return false;
1160         if ((sym.flags() & PROTECTED) == 0 ||
1161             sym.owner.owner == currentClass.owner || // fast special case
1162             sym.packge() == currentClass.packge())
1163             return false;
1164         if (!currentClass.isSubClass(sym.owner, types))
1165             return true;
1166         if ((sym.flags() & STATIC) != 0 ||
1167             !tree.hasTag(SELECT) ||

1216             sym.owner.enclClass() != currentClass) {
1217             // A constant is replaced by its constant value.
1218             Object cv = ((VarSymbol)sym).getConstValue();
1219             if (cv != null) {
1220                 make.at(tree.pos);
1221                 return makeLit(sym.type, cv);
1222             }
1223             if (lambdaTranslationMap != null && lambdaTranslationMap.get(sym) != null) {
1224                 return make.at(tree.pos).Ident(lambdaTranslationMap.get(sym));
1225             } else {
1226                 // Otherwise replace the variable by its proxy.
1227                 sym = proxies.get(sym);
1228                 Assert.check(sym != null && (sym.flags_field & FINAL) != 0);
1229                 tree = make.at(tree.pos).Ident(sym);
1230             }
1231         }
1232         JCExpression base = (tree.hasTag(SELECT)) ? ((JCFieldAccess) tree).selected : null;
1233         switch (sym.kind) {
1234         case TYP:
1235             if (sym.owner.kind != PCK) {



1236                 // Convert type idents to
1237                 // <flat name> or <package name> . <flat name>
1238                 Name flatname = Convert.shortName(sym.flatName());
1239                 while (base != null &&
1240                        TreeInfo.symbol(base) != null &&
1241                        TreeInfo.symbol(base).kind != PCK) {
1242                     base = (base.hasTag(SELECT))
1243                         ? ((JCFieldAccess) base).selected
1244                         : null;
1245                 }
1246                 if (tree.hasTag(IDENT)) {
1247                     ((JCIdent) tree).name = flatname;
1248                 } else if (base == null) {
1249                     tree = make.at(tree.pos).Ident(sym);
1250                     ((JCIdent) tree).name = flatname;



1251                 } else {
1252                     ((JCFieldAccess) tree).selected = base;
1253                     ((JCFieldAccess) tree).name = flatname;



1254                 }
1255             }
1256             break;
1257         case MTH: case VAR:
1258             if (sym.owner.kind == TYP) {
1259 
1260                 // Access methods are required for
1261                 //  - private members,
1262                 //  - protected members in a superclass of an
1263                 //    enclosing class contained in another package.
1264                 //  - all non-private members accessed via a qualified super.
1265                 boolean protAccess = refSuper && !needsPrivateAccess(sym)
1266                     || needsProtectedAccess(sym, tree);
1267                 boolean accReq = protAccess || needsPrivateAccess(sym);
1268 
1269                 // A base has to be supplied for
1270                 //  - simple identifiers accessing variables in outer classes.
1271                 boolean baseReq =
1272                     base == null &&
1273                     sym.owner != syms.predefClass &&

1331     JCExpression access(JCExpression tree) {
1332         Symbol sym = TreeInfo.symbol(tree);
1333         return sym == null ? tree : access(sym, tree, null, false);
1334     }
1335 
1336     /** Return access constructor for a private constructor,
1337      *  or the constructor itself, if no access constructor is needed.
1338      *  @param pos       The position to report diagnostics, if any.
1339      *  @param constr    The private constructor.
1340      */
1341     Symbol accessConstructor(DiagnosticPosition pos, Symbol constr) {
1342         if (needsPrivateAccess(constr)) {
1343             ClassSymbol accOwner = constr.owner.enclClass();
1344             MethodSymbol aconstr = accessConstrs.get(constr);
1345             if (aconstr == null) {
1346                 List<Type> argtypes = constr.type.getParameterTypes();
1347                 if ((accOwner.flags_field & ENUM) != 0)
1348                     argtypes = argtypes
1349                         .prepend(syms.intType)
1350                         .prepend(syms.stringType);

1351                 aconstr = new MethodSymbol(
1352                     SYNTHETIC,
1353                     names.init,
1354                     new MethodType(
1355                         argtypes.append(
1356                             accessConstructorTag().erasure(types)),
1357                         constr.type.getReturnType(),
1358                         constr.type.getThrownTypes(),
1359                         syms.methodClass),
1360                     accOwner);
1361                 enterSynthetic(pos, aconstr, accOwner.members());
1362                 accessConstrs.put(constr, aconstr);
1363                 accessed.append(constr);
1364             }
1365             return aconstr;
1366         } else {
1367             return constr;
1368         }
1369     }
1370 
1371     /** Return an anonymous class nested in this toplevel class.
1372      */
1373     ClassSymbol accessConstructorTag() {
1374         ClassSymbol topClass = currentClass.outermostClass();
1375         ModuleSymbol topModle = topClass.packge().modle;
1376         for (int i = 1; ; i++) {
1377             Name flatname = names.fromString("" + topClass.getQualifiedName() +
1378                                             target.syntheticNameChar() +
1379                                             i);
1380             ClassSymbol ctag = chk.getCompiled(topModle, flatname);
1381             if (ctag == null)
1382                 ctag = makeEmptyClass(STATIC | SYNTHETIC, topClass).sym;
1383             else if (!ctag.isAnonymous())
1384                 continue;
1385             // keep a record of all tags, to verify that all are generated as required
1386             accessConstrTags = accessConstrTags.prepend(ctag);
1387             return ctag;
1388         }
1389     }
1390 
1391     /** Add all required access methods for a private symbol to enclosing class.
1392      *  @param sym       The symbol.
1393      */
1394     void makeAccessible(Symbol sym) {
1395         JCClassDecl cdef = classDef(sym.owner.enclClass());
1396         if (cdef == null) Assert.error("class def not found: " + sym + " in " + sym.owner);
1397         if (sym.name == names.init) {
1398             cdef.defs = cdef.defs.prepend(
1399                 accessConstructorDef(cdef.pos, sym, accessConstrs.get(sym)));
1400         } else {
1401             MethodSymbol[] accessors = accessSyms.get(sym);
1402             for (int i = 0; i < AccessCode.numberOfAccessCodes; i++) {
1403                 if (accessors[i] != null)
1404                     cdef.defs = cdef.defs.prepend(
1405                         accessDef(cdef.pos, sym, accessors[i], i));
1406             }
1407         }
1408     }
1409 
1410     /** Construct definition of an access method.
1411      *  @param pos        The source code position of the definition.
1412      *  @param vsym       The private or protected symbol.
1413      *  @param accessor   The access method for the symbol.
1414      *  @param acode      The access code.
1415      */
1416     JCTree accessDef(int pos, Symbol vsym, MethodSymbol accessor, int acode) {
1417 //      System.err.println("access " + vsym + " with " + accessor);//DEBUG

1590         VarSymbol outerThis =
1591             new VarSymbol(flags | NOOUTERTHIS, outerThisName(target, owner), target, owner);
1592         outerThisStack = outerThisStack.prepend(outerThis);
1593         return outerThis;
1594     }
1595 
1596     private JCVariableDecl makeOuterThisVarDecl(int pos, VarSymbol sym) {
1597         JCVariableDecl vd = make.at(pos).VarDef(sym, null);
1598         vd.vartype = access(vd.vartype);
1599         return vd;
1600     }
1601 
1602     /** Definition for this$n field.
1603      *  @param pos        The source code position of the definition.
1604      *  @param owner      The method in which the definition goes.
1605      */
1606     JCVariableDecl outerThisDef(int pos, MethodSymbol owner) {
1607         ClassSymbol c = owner.enclClass();
1608         boolean isMandated =
1609             // Anonymous constructors
1610             (owner.isConstructor() && owner.isAnonymous()) ||
1611             // Constructors of non-private inner member classes
1612             (owner.isConstructor() && c.isInner() &&
1613              !c.isPrivate() && !c.isStatic());
1614         long flags =
1615             FINAL | (isMandated ? MANDATED : SYNTHETIC) | PARAMETER;
1616         VarSymbol outerThis = makeOuterThisVarSymbol(owner, flags);
1617         owner.extraParams = owner.extraParams.prepend(outerThis);
1618         return makeOuterThisVarDecl(pos, outerThis);
1619     }
1620 
1621     /** Definition for this$n field.
1622      *  @param pos        The source code position of the definition.
1623      *  @param owner      The class in which the definition goes.
1624      */
1625     JCVariableDecl outerThisDef(int pos, ClassSymbol owner) {
1626         VarSymbol outerThis = makeOuterThisVarSymbol(owner, FINAL | SYNTHETIC);
1627         return makeOuterThisVarDecl(pos, outerThis);
1628     }
1629 
1630     /** Return a list of trees that load the free variables in given list,
1631      *  in reverse order.
1632      *  @param pos          The source code position to be used for the trees.

1789         }
1790 
1791         JCStatement exceptionalRethrow = make.Throw(make.Ident(primaryException));
1792         JCBlock exceptionalCloseBlock = make.Block(0L, List.of(exceptionalCloseStatement, exceptionalRethrow));
1793         JCCatch exceptionalCatchClause = make.Catch(primaryExceptionDecl, exceptionalCloseBlock);
1794 
1795         //create the main try statement with the close:
1796         JCTry outerTry = make.Try(makeTwrBlock(resources.tail, block, depth + 1),
1797                                   List.of(exceptionalCatchClause),
1798                                   finallyClause);
1799 
1800         outerTry.finallyCanCompleteNormally = true;
1801         stats.add(outerTry);
1802 
1803         JCBlock newBlock = make.Block(0L, stats.toList());
1804         return newBlock;
1805     }
1806 
1807     private JCStatement makeResourceCloseInvocation(JCExpression resource) {
1808         // convert to AutoCloseable if needed
1809         if (types.asSuper(resource.type, syms.autoCloseableType.tsym) == null) {
1810             resource = convert(resource, syms.autoCloseableType);
1811         }
1812 
1813         // create resource.close() method invocation
1814         JCExpression resourceClose = makeCall(resource,
1815                                               names.close,
1816                                               List.nil());
1817         return make.Exec(resourceClose);
1818     }
1819 
1820     private JCExpression makeNonNullCheck(JCExpression expression) {
1821         return makeBinary(NE, expression, makeNull());
1822     }
1823 
1824     /** Construct a tree that represents the outer instance
1825      *  {@code C.this}. Never pick the current `this'.
1826      *  @param pos           The source code position to be used for the tree.
1827      *  @param c             The qualifier class.
1828      */
1829     JCExpression makeOuterThis(DiagnosticPosition pos, TypeSymbol c) {

1941     }
1942 
1943 /**************************************************************************
1944  * Code for .class
1945  *************************************************************************/
1946 
1947     /** Return the symbol of a class to contain a cache of
1948      *  compiler-generated statics such as class$ and the
1949      *  $assertionsDisabled flag.  We create an anonymous nested class
1950      *  (unless one already exists) and return its symbol.  However,
1951      *  for backward compatibility in 1.4 and earlier we use the
1952      *  top-level class itself.
1953      */
1954     private ClassSymbol outerCacheClass() {
1955         ClassSymbol clazz = outermostClassDef.sym;
1956         Scope s = clazz.members();
1957         for (Symbol sym : s.getSymbols(NON_RECURSIVE))
1958             if (sym.kind == TYP &&
1959                 sym.name == names.empty &&
1960                 (sym.flags() & INTERFACE) == 0) return (ClassSymbol) sym;
1961         return makeEmptyClass(STATIC | SYNTHETIC, clazz).sym;
1962     }
1963 
1964     /** Create an attributed tree of the form left.name(). */
1965     private JCMethodInvocation makeCall(JCExpression left, Name name, List<JCExpression> args) {
1966         Assert.checkNonNull(left.type);
1967         Symbol funcsym = lookupMethod(make_pos, name, left.type,
1968                                       TreeInfo.types(args));
1969         return make.App(make.Select(left, funcsym), args);
1970     }
1971 
1972     /** The tree simulating a T.class expression.
1973      *  @param clazz      The tree identifying type T.
1974      */
1975     private JCExpression classOf(JCTree clazz) {
1976         return classOfType(clazz.type, clazz.pos());
1977     }
1978 
1979     private JCExpression classOfType(Type type, DiagnosticPosition pos) {
1980         switch (type.getTag()) {
1981         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:

1993                 VarSymbol sym = new VarSymbol(
1994                         STATIC | PUBLIC | FINAL, names._class,
1995                         syms.classType, type.tsym);
1996                 return make_at(pos).Select(make.Type(type), sym);
1997         default:
1998             throw new AssertionError();
1999         }
2000     }
2001 
2002 /**************************************************************************
2003  * Code for enabling/disabling assertions.
2004  *************************************************************************/
2005 
2006     private ClassSymbol assertionsDisabledClassCache;
2007 
2008     /**Used to create an auxiliary class to hold $assertionsDisabled for interfaces.
2009      */
2010     private ClassSymbol assertionsDisabledClass() {
2011         if (assertionsDisabledClassCache != null) return assertionsDisabledClassCache;
2012 
2013         assertionsDisabledClassCache = makeEmptyClass(STATIC | SYNTHETIC, outermostClassDef.sym).sym;
2014 
2015         return assertionsDisabledClassCache;
2016     }
2017 
2018     // This code is not particularly robust if the user has
2019     // previously declared a member named '$assertionsDisabled'.
2020     // The same faulty idiom also appears in the translation of
2021     // class literals above.  We should report an error if a
2022     // previous declaration is not synthetic.
2023 
2024     private JCExpression assertFlagTest(DiagnosticPosition pos) {
2025         // Outermost class may be either true class or an interface.
2026         ClassSymbol outermostClass = outermostClassDef.sym;
2027 
2028         //only classes can hold a non-public field, look for a usable one:
2029         ClassSymbol container = !currentClass.isInterface() ? currentClass :
2030                 assertionsDisabledClass();
2031 
2032         VarSymbol assertDisabledSym =
2033             (VarSymbol)lookupSynthetic(dollarAssertionsDisabled,

2173     /** Visitor method: Translate a single node.
2174      *  Attach the source position from the old tree to its replacement tree.
2175      */
2176     @Override
2177     public <T extends JCTree> T translate(T tree) {
2178         if (tree == null) {
2179             return null;
2180         } else {
2181             make_at(tree.pos());
2182             T result = super.translate(tree);
2183             if (endPosTable != null && result != tree) {
2184                 endPosTable.replaceTree(tree, result);
2185             }
2186             return result;
2187         }
2188     }
2189 
2190     /** Visitor method: Translate a single node, boxing or unboxing if needed.
2191      */
2192     public <T extends JCExpression> T translate(T tree, Type type) {
2193         return (tree == null) ? null : boxIfNeeded(translate(tree), type);

2194     }
2195 
2196     /** Visitor method: Translate tree.
2197      */
2198     public <T extends JCTree> T translate(T tree, JCExpression enclOp) {
2199         JCExpression prevEnclOp = this.enclOp;
2200         this.enclOp = enclOp;
2201         T res = translate(tree);
2202         this.enclOp = prevEnclOp;
2203         return res;
2204     }
2205 
2206     /** Visitor method: Translate list of trees.
2207      */
2208     public <T extends JCExpression> List<T> translate(List<T> trees, Type type) {
2209         if (trees == null) return null;
2210         for (List<T> l = trees; l.nonEmpty(); l = l.tail)
2211             l.head = translate(l.head, type);
2212         return trees;
2213     }

2312             encl.trans_local = encl.trans_local.prepend(currentClass);
2313         }
2314 
2315         // Recursively translate members, taking into account that new members
2316         // might be created during the translation and prepended to the member
2317         // list `tree.defs'.
2318         List<JCTree> seen = List.nil();
2319         while (tree.defs != seen) {
2320             List<JCTree> unseen = tree.defs;
2321             for (List<JCTree> l = unseen; l.nonEmpty() && l != seen; l = l.tail) {
2322                 JCTree outermostMemberDefPrev = outermostMemberDef;
2323                 if (outermostMemberDefPrev == null) outermostMemberDef = l.head;
2324                 l.head = translate(l.head);
2325                 outermostMemberDef = outermostMemberDefPrev;
2326             }
2327             seen = unseen;
2328         }
2329 
2330         // Convert a protected modifier to public, mask static modifier.
2331         if ((tree.mods.flags & PROTECTED) != 0) tree.mods.flags |= PUBLIC;
2332         tree.mods.flags &= ClassFlags;
2333 
2334         // Convert name to flat representation, replacing '.' by '$'.
2335         tree.name = Convert.shortName(currentClass.flatName());
2336 
2337         // Add free variables proxy definitions to class.
2338 
2339         for (List<JCVariableDecl> l = fvdefs; l.nonEmpty(); l = l.tail) {
2340             tree.defs = tree.defs.prepend(l.head);
2341             enterSynthetic(tree.pos(), l.head.sym, currentClass.members());
2342         }
2343         // If this$n was accessed, add the field definition and
2344         // update initial constructors to initialize it
2345         if (currentClass.hasOuterInstance() && shouldEmitOuterThis(currentClass)) {
2346             tree.defs = tree.defs.prepend(otdef);
2347             enterSynthetic(tree.pos(), otdef.sym, currentClass.members());
2348 
2349            for (JCTree def : tree.defs) {
2350                 if (TreeInfo.isInitialConstructor(def)) {
2351                   JCMethodDecl mdef = (JCMethodDecl) def;
2352                   mdef.body.stats = mdef.body.stats.prepend(

2722 
2723         MethodType indyType = msym.type.asMethodType();
2724         indyType = new MethodType(
2725                 isStatic ? List.nil() : indyType.argtypes.prepend(tree.sym.type),
2726                 indyType.restype,
2727                 indyType.thrown,
2728                 syms.methodClass
2729         );
2730         DynamicMethodSymbol dynSym = new DynamicMethodSymbol(argName,
2731                 syms.noSymbol,
2732                 bsm.asHandle(),
2733                 indyType,
2734                 staticArgValues);
2735         JCFieldAccess qualifier = make.Select(make.QualIdent(site.tsym), argName);
2736         qualifier.sym = dynSym;
2737         qualifier.type = msym.type.asMethodType().restype;
2738         return qualifier;
2739     }
2740 
2741     public void visitMethodDef(JCMethodDecl tree) {

2742         if (tree.name == names.init && (currentClass.flags_field&ENUM) != 0) {
2743             // Add "String $enum$name, int $enum$ordinal" to the beginning of the
2744             // argument list for each constructor of an enum.
2745             JCVariableDecl nameParam = make_at(tree.pos()).
2746                 Param(names.fromString(target.syntheticNameChar() +
2747                                        "enum" + target.syntheticNameChar() + "name"),
2748                       syms.stringType, tree.sym);
2749             nameParam.mods.flags |= SYNTHETIC; nameParam.sym.flags_field |= SYNTHETIC;
2750             JCVariableDecl ordParam = make.
2751                 Param(names.fromString(target.syntheticNameChar() +
2752                                        "enum" + target.syntheticNameChar() +
2753                                        "ordinal"),
2754                       syms.intType, tree.sym);
2755             ordParam.mods.flags |= SYNTHETIC; ordParam.sym.flags_field |= SYNTHETIC;
2756 
2757             MethodSymbol m = tree.sym;
2758             tree.params = tree.params.prepend(ordParam).prepend(nameParam);
2759 
2760             m.extraParams = m.extraParams.prepend(ordParam.sym);
2761             m.extraParams = m.extraParams.prepend(nameParam.sym);

2763             m.erasure_field = new MethodType(
2764                 olderasure.getParameterTypes().prepend(syms.intType).prepend(syms.stringType),
2765                 olderasure.getReturnType(),
2766                 olderasure.getThrownTypes(),
2767                 syms.methodClass);
2768         }
2769 
2770         JCMethodDecl prevMethodDef = currentMethodDef;
2771         MethodSymbol prevMethodSym = currentMethodSym;
2772         try {
2773             currentMethodDef = tree;
2774             currentMethodSym = tree.sym;
2775             visitMethodDefInternal(tree);
2776         } finally {
2777             currentMethodDef = prevMethodDef;
2778             currentMethodSym = prevMethodSym;
2779         }
2780     }
2781 
2782     private void visitMethodDefInternal(JCMethodDecl tree) {
2783         if (tree.name == names.init &&
2784             !currentClass.isStatic() &&
2785             (currentClass.isInner() || currentClass.isDirectlyOrIndirectlyLocal())) {
2786             // We are seeing a constructor of an inner class.
2787             MethodSymbol m = tree.sym;
2788 
2789             // Push a new proxy scope for constructor parameters.
2790             // and create definitions for any this$n and proxy parameters.
2791             Map<Symbol, Symbol> prevProxies = proxies;
2792             proxies = new HashMap<>(proxies);
2793             List<VarSymbol> prevOuterThisStack = outerThisStack;
2794             List<VarSymbol> fvs = freevars(currentClass);
2795             JCVariableDecl otdef = null;
2796             if (currentClass.hasOuterInstance())
2797                 otdef = outerThisDef(tree.pos, m);
2798             List<JCVariableDecl> fvdefs = freevarDefs(tree.pos, fvs, m, PARAMETER);
2799 
2800             // Recursively translate result type, parameters and thrown list.
2801             tree.restype = translate(tree.restype);
2802             tree.params = translateVarDefs(tree.params);
2803             tree.thrown = translate(tree.thrown);

2844             // pop local variables from proxy stack
2845             proxies = prevProxies;
2846 
2847             // recursively translate following local statements and
2848             // combine with this- or super-call
2849             List<JCStatement> stats = translate(tree.body.stats.tail);
2850             tree.body.stats = stats.prepend(selfCall).prependList(added);
2851             outerThisStack = prevOuterThisStack;
2852         } else {
2853             Map<Symbol, Symbol> prevLambdaTranslationMap =
2854                     lambdaTranslationMap;
2855             try {
2856                 lambdaTranslationMap = (tree.sym.flags() & SYNTHETIC) != 0 &&
2857                         tree.sym.name.startsWith(names.lambda) ?
2858                         makeTranslationMap(tree) : null;
2859                 super.visitMethodDef(tree);
2860             } finally {
2861                 lambdaTranslationMap = prevLambdaTranslationMap;
2862             }
2863         }
2864         if (tree.name == names.init && ((tree.sym.flags_field & Flags.COMPACT_RECORD_CONSTRUCTOR) != 0 ||
2865                 (tree.sym.flags_field & (GENERATEDCONSTR | RECORD)) == (GENERATEDCONSTR | RECORD))) {
2866             // lets find out if there is any field waiting to be initialized
2867             ListBuffer<VarSymbol> fields = new ListBuffer<>();
2868             for (Symbol sym : currentClass.getEnclosedElements()) {
2869                 if (sym.kind == Kinds.Kind.VAR && ((sym.flags() & RECORD) != 0))
2870                     fields.append((VarSymbol) sym);
2871             }
2872             for (VarSymbol field: fields) {
2873                 if ((field.flags_field & Flags.UNINITIALIZED_FIELD) != 0) {
2874                     VarSymbol param = tree.params.stream().filter(p -> p.name == field.name).findFirst().get().sym;
2875                     make.at(tree.pos);
2876                     tree.body.stats = tree.body.stats.append(
2877                             make.Exec(
2878                                     make.Assign(
2879                                             make.Select(make.This(field.owner.erasure(types)), field),
2880                                             make.Ident(param)).setType(field.erasure(types))));
2881                     // we don't need the flag at the field anymore
2882                     field.flags_field &= ~Flags.UNINITIALIZED_FIELD;
2883                 }
2884             }

3086                 List.nil() : List.of(translate(tree.detail));
3087             if (!tree.cond.type.isFalse()) {
3088                 cond = makeBinary
3089                     (AND,
3090                      cond,
3091                      makeUnary(NOT, tree.cond));
3092             }
3093             result =
3094                 make.If(cond,
3095                         make_at(tree).
3096                            Throw(makeNewClass(syms.assertionErrorType, exnArgs)),
3097                         null);
3098         } else {
3099             result = make.Skip();
3100         }
3101     }
3102 
3103     public void visitApply(JCMethodInvocation tree) {
3104         Symbol meth = TreeInfo.symbol(tree.meth);
3105         List<Type> argtypes = meth.type.getParameterTypes();
3106         if (meth.name == names.init && meth.owner == syms.enumSym)

3107             argtypes = argtypes.tail.tail;
3108         tree.args = boxArgs(argtypes, tree.args, tree.varargsElement);
3109         tree.varargsElement = null;
3110         Name methName = TreeInfo.name(tree.meth);
3111         if (meth.name==names.init) {
3112             // We are seeing a this(...) or super(...) constructor call.
3113             // If an access constructor is used, append null as a last argument.
3114             Symbol constructor = accessConstructor(tree.pos(), meth);
3115             if (constructor != meth) {
3116                 tree.args = tree.args.append(makeNull());
3117                 TreeInfo.setSymbol(tree.meth, constructor);
3118             }
3119 
3120             // If we are calling a constructor of a local class, add
3121             // free variables after explicit constructor arguments.
3122             ClassSymbol c = (ClassSymbol)constructor.owner;
3123             if (c.isDirectlyOrIndirectlyLocal() && !c.isStatic()) {
3124                 tree.args = tree.args.appendList(loadFreevars(tree.pos(), freevars(c)));
3125             }
3126 
3127             // If we are calling a constructor of an enum class, pass
3128             // along the name and ordinal arguments
3129             if ((c.flags_field&ENUM) != 0 || c.getQualifiedName() == names.java_lang_Enum) {
3130                 List<JCVariableDecl> params = currentMethodDef.params;
3131                 if (currentMethodSym.owner.hasOuterInstance())

3199             while (args.nonEmpty()) {
3200                 JCExpression arg = translate(args.head, varargsElement);
3201                 elems.append(arg);
3202                 args = args.tail;
3203             }
3204             JCNewArray boxedArgs = make.NewArray(make.Type(varargsElement),
3205                                                List.nil(),
3206                                                elems.toList());
3207             boxedArgs.type = new ArrayType(varargsElement, syms.arrayClass);
3208             result.append(boxedArgs);
3209         } else {
3210             if (args.length() != 1) throw new AssertionError(args);
3211             JCExpression arg = translate(args.head, parameter);
3212             anyChanges |= (arg != args.head);
3213             result.append(arg);
3214             if (!anyChanges) return _args;
3215         }
3216         return result.toList();
3217     }
3218 











3219     /** Expand a boxing or unboxing conversion if needed. */
3220     @SuppressWarnings("unchecked") // XXX unchecked
3221     <T extends JCExpression> T boxIfNeeded(T tree, Type type) {
3222         boolean havePrimitive = tree.type.isPrimitive();
3223         if (havePrimitive == type.isPrimitive())
3224             return tree;
3225         if (havePrimitive) {
3226             Type unboxedTarget = types.unboxedType(type);
3227             if (!unboxedTarget.hasTag(NONE)) {
3228                 if (!types.isSubtype(tree.type, unboxedTarget)) //e.g. Character c = 89;
3229                     tree.type = unboxedTarget.constType(tree.type.constValue());
3230                 return (T)boxPrimitive(tree, types.erasure(type));
3231             } else {
3232                 tree = (T)boxPrimitive(tree);
3233             }
3234         } else {
3235             tree = (T)unbox(tree, type);
3236         }
3237         return tree;
3238     }

3602          * A statement of the form
3603          *
3604          * <pre>
3605          *     for ( T v : coll ) stmt ;
3606          * </pre>
3607          *
3608          * (where coll implements {@code Iterable<? extends T>}) gets translated to
3609          *
3610          * <pre>{@code
3611          *     for ( Iterator<? extends T> #i = coll.iterator(); #i.hasNext(); ) {
3612          *         T v = (T) #i.next();
3613          *         stmt;
3614          *     }
3615          * }</pre>
3616          *
3617          * where #i is a freshly named synthetic local variable.
3618          */
3619         private void visitIterableForeachLoop(JCEnhancedForLoop tree) {
3620             make_at(tree.expr.pos());
3621             Type iteratorTarget = syms.objectType;
3622             Type iterableType = types.asSuper(types.cvarUpperBound(tree.expr.type),
3623                                               syms.iterableType.tsym);
3624             if (iterableType.getTypeArguments().nonEmpty())
3625                 iteratorTarget = types.erasure(iterableType.getTypeArguments().head);
3626             tree.expr.type = types.erasure(types.skipTypeVars(tree.expr.type, false));
3627             tree.expr = transTypes.coerce(attrEnv, tree.expr, types.erasure(iterableType));
3628             Symbol iterator = lookupMethod(tree.expr.pos(),
3629                                            names.iterator,
3630                                            tree.expr.type,
3631                                            List.nil());
3632             Assert.check(types.isSameType(types.erasure(types.asSuper(iterator.type.getReturnType(), syms.iteratorType.tsym)), types.erasure(syms.iteratorType)));
3633             VarSymbol itvar = new VarSymbol(SYNTHETIC, names.fromString("i" + target.syntheticNameChar()),
3634                                             types.erasure(syms.iteratorType),
3635                                             currentMethodSym);
3636 
3637              JCStatement init = make.
3638                 VarDef(itvar, make.App(make.Select(tree.expr, iterator)
3639                      .setType(types.erasure(iterator.type))));
3640 
3641             Symbol hasNext = lookupMethod(tree.expr.pos(),
3642                                           names.hasNext,
3643                                           itvar.type,
3644                                           List.nil());
3645             JCMethodInvocation cond = make.App(make.Select(make.Ident(itvar), hasNext));
3646             Symbol next = lookupMethod(tree.expr.pos(),
3647                                        names.next,
3648                                        itvar.type,
3649                                        List.nil());
3650             JCExpression vardefinit = make.App(make.Select(make.Ident(itvar), next));
3651 
3652             Assert.check(tree.getDeclarationKind() == EnhancedForLoopTree.DeclarationKind.VARIABLE);

3695                 new MethodSymbol(tree.flags | BLOCK,
3696                                  names.empty, null,
3697                                  currentClass);
3698         }
3699         super.visitBlock(tree);
3700         currentMethodSym = oldMethodSym;
3701     }
3702 
3703     public void visitDoLoop(JCDoWhileLoop tree) {
3704         tree.body = translate(tree.body);
3705         tree.cond = translate(tree.cond, syms.booleanType);
3706         result = tree;
3707     }
3708 
3709     public void visitWhileLoop(JCWhileLoop tree) {
3710         tree.cond = translate(tree.cond, syms.booleanType);
3711         tree.body = translate(tree.body);
3712         result = tree;
3713     }
3714 

















3715     public void visitForLoop(JCForLoop tree) {
3716         tree.init = translate(tree.init);
3717         if (tree.cond != null)
3718             tree.cond = translate(tree.cond, syms.booleanType);
3719         tree.step = translate(tree.step);
3720         tree.body = translate(tree.body);
3721         result = tree;
3722     }
3723 
3724     public void visitReturn(JCReturn tree) {
3725         if (tree.expr != null)
3726             tree.expr = translate(tree.expr,
3727                                   types.erasure(currentMethodDef
3728                                                 .restype.type));
3729         result = tree;
3730     }
3731 
3732     public void visitSwitch(JCSwitch tree) {
3733         List<JCCase> cases = tree.patternSwitch ? addDefaultIfNeeded(tree.patternSwitch,
3734                                                                      tree.wasEnumSelector,

4188         tree.value = translate(tree.value, tree.target.type);
4189         result = tree;
4190     }
4191 
4192     public void visitNewArray(JCNewArray tree) {
4193         tree.elemtype = translate(tree.elemtype);
4194         for (List<JCExpression> t = tree.dims; t.tail != null; t = t.tail)
4195             if (t.head != null) t.head = translate(t.head, syms.intType);
4196         tree.elems = translate(tree.elems, types.elemtype(tree.type));
4197         result = tree;
4198     }
4199 
4200     public void visitSelect(JCFieldAccess tree) {
4201         // need to special case-access of the form C.super.x
4202         // these will always need an access method, unless C
4203         // is a default interface subclassed by the current class.
4204         boolean qualifiedSuperAccess =
4205             tree.selected.hasTag(SELECT) &&
4206             TreeInfo.name(tree.selected) == names._super &&
4207             !types.isDirectSuperInterface(((JCFieldAccess)tree.selected).selected.type.tsym, currentClass);





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



4209         if (tree.name == names._class) {
4210             result = classOf(tree.selected);
4211         }
4212         else if (tree.name == names._super &&
4213                 types.isDirectSuperInterface(tree.selected.type.tsym, currentClass)) {
4214             //default super call!! Not a classic qualified super call
4215             TypeSymbol supSym = tree.selected.type.tsym;
4216             Assert.checkNonNull(types.asSuper(currentClass.type, supSym));
4217             result = tree;
4218         }
4219         else if (tree.name == names._this || tree.name == names._super) {
4220             result = makeThis(tree.pos(), tree.selected.type.tsym);
4221         }
4222         else
4223             result = access(tree.sym, tree, enclOp, qualifiedSuperAccess);
4224     }
4225 
4226     public void visitLetExpr(LetExpr tree) {
4227         tree.defs = translate(tree.defs);
4228         tree.expr = translate(tree.expr, tree.type);
4229         result = tree;
4230     }
4231 
4232     // There ought to be nothing to rewrite here;
4233     // we don't generate code.
4234     public void visitAnnotation(JCAnnotation tree) {
4235         result = tree;
4236     }

  85 
  86     private final Names names;
  87     private final Log log;
  88     private final Symtab syms;
  89     private final Resolve rs;
  90     private final Operators operators;
  91     private final Check chk;
  92     private final Attr attr;
  93     private TreeMaker make;
  94     private DiagnosticPosition make_pos;
  95     private final ConstFold cfolder;
  96     private final Target target;
  97     private final TypeEnvs typeEnvs;
  98     private final Name dollarAssertionsDisabled;
  99     private final Types types;
 100     private final TransTypes transTypes;
 101     private final boolean debugLower;
 102     private final boolean disableProtectedAccessors; // experimental
 103     private final PkgInfo pkginfoOpt;
 104     private final boolean optimizeOuterThis;
 105     private final boolean allowPrimitiveClasses;
 106     private final boolean useMatchException;
 107 
 108     @SuppressWarnings("this-escape")
 109     protected Lower(Context context) {
 110         context.put(lowerKey, this);
 111         names = Names.instance(context);
 112         log = Log.instance(context);
 113         syms = Symtab.instance(context);
 114         rs = Resolve.instance(context);
 115         operators = Operators.instance(context);
 116         chk = Check.instance(context);
 117         attr = Attr.instance(context);
 118         make = TreeMaker.instance(context);
 119         cfolder = ConstFold.instance(context);
 120         target = Target.instance(context);
 121         typeEnvs = TypeEnvs.instance(context);
 122         dollarAssertionsDisabled = names.
 123             fromString(target.syntheticNameChar() + "assertionsDisabled");
 124 
 125         types = Types.instance(context);
 126         transTypes = TransTypes.instance(context);
 127         Options options = Options.instance(context);
 128         debugLower = options.isSet("debuglower");
 129         pkginfoOpt = PkgInfo.get(options);
 130         optimizeOuterThis =
 131             target.optimizeOuterThis() ||
 132             options.getBoolean("optimizeOuterThis", false);
 133         disableProtectedAccessors = options.isSet("disableProtectedAccessors");
 134         Source source = Source.instance(context);
 135         allowPrimitiveClasses = Source.Feature.PRIMITIVE_CLASSES.allowedInSource(source) && options.isSet("enablePrimitiveClasses");
 136         Preview preview = Preview.instance(context);
 137         useMatchException = Feature.PATTERN_SWITCH.allowedInSource(source) &&
 138                             (preview.isEnabled() || !preview.isPreview(Feature.PATTERN_SWITCH));
 139     }
 140 
 141     /** The currently enclosing class.
 142      */
 143     ClassSymbol currentClass;
 144 
 145     /** A queue of all translated classes.
 146      */
 147     ListBuffer<JCTree> translated;
 148 
 149     /** Environment for symbol lookup, set by translateTopLevelClass.
 150      */
 151     Env<AttrContext> attrEnv;
 152 
 153     /** A hash table mapping syntax trees to their ending source positions.
 154      */
 155     EndPosTable endPosTable;

 892 
 893     /** Look up a method in a given scope.
 894      */
 895     private MethodSymbol lookupMethod(DiagnosticPosition pos, Name name, Type qual, List<Type> args) {
 896         return rs.resolveInternalMethod(pos, attrEnv, qual, name, args, List.nil());
 897     }
 898 
 899     /** Anon inner classes are used as access constructor tags.
 900      * accessConstructorTag will use an existing anon class if one is available,
 901      * and synthesize a class (with makeEmptyClass) if one is not available.
 902      * However, there is a small possibility that an existing class will not
 903      * be generated as expected if it is inside a conditional with a constant
 904      * expression. If that is found to be the case, create an empty class tree here.
 905      */
 906     private void checkAccessConstructorTags() {
 907         for (List<ClassSymbol> l = accessConstrTags; l.nonEmpty(); l = l.tail) {
 908             ClassSymbol c = l.head;
 909             if (isTranslatedClassAvailable(c))
 910                 continue;
 911             // Create class definition tree.
 912             JCClassDecl cdec = makeEmptyClass(STATIC | SYNTHETIC | IDENTITY_TYPE,
 913                     c.outermostClass(), c.flatname, false);
 914             swapAccessConstructorTag(c, cdec.sym);
 915             translated.append(cdec);
 916         }
 917     }
 918     // where
 919     private boolean isTranslatedClassAvailable(ClassSymbol c) {
 920         for (JCTree tree: translated) {
 921             if (tree.hasTag(CLASSDEF)
 922                     && ((JCClassDecl) tree).sym == c) {
 923                 return true;
 924             }
 925         }
 926         return false;
 927     }
 928 
 929     void swapAccessConstructorTag(ClassSymbol oldCTag, ClassSymbol newCTag) {
 930         for (MethodSymbol methodSymbol : accessConstrs.values()) {
 931             Assert.check(methodSymbol.type.hasTag(METHOD));
 932             MethodType oldMethodType =

1129 
1130     /** The qualifier to be used for accessing a symbol in an outer class.
1131      *  This is either C.sym or C.this.sym, depending on whether or not
1132      *  sym is static.
1133      *  @param sym   The accessed symbol.
1134      */
1135     JCExpression accessBase(DiagnosticPosition pos, Symbol sym) {
1136         return (sym.flags() & STATIC) != 0
1137             ? access(make.at(pos.getStartPosition()).QualIdent(sym.owner))
1138             : makeOwnerThis(pos, sym, true);
1139     }
1140 
1141     /** Do we need an access method to reference private symbol?
1142      */
1143     boolean needsPrivateAccess(Symbol sym) {
1144         if (target.hasNestmateAccess()) {
1145             return false;
1146         }
1147         if ((sym.flags() & PRIVATE) == 0 || sym.owner == currentClass) {
1148             return false;
1149         } else if (names.isInitOrVNew(sym.name) && sym.owner.isDirectlyOrIndirectlyLocal()) {
1150             // private constructor in local class: relax protection
1151             sym.flags_field &= ~PRIVATE;
1152             return false;
1153         } else {
1154             return true;
1155         }
1156     }
1157 
1158     /** Do we need an access method to reference symbol in other package?
1159      */
1160     boolean needsProtectedAccess(Symbol sym, JCTree tree) {
1161         if (disableProtectedAccessors) return false;
1162         if ((sym.flags() & PROTECTED) == 0 ||
1163             sym.owner.owner == currentClass.owner || // fast special case
1164             sym.packge() == currentClass.packge())
1165             return false;
1166         if (!currentClass.isSubClass(sym.owner, types))
1167             return true;
1168         if ((sym.flags() & STATIC) != 0 ||
1169             !tree.hasTag(SELECT) ||

1218             sym.owner.enclClass() != currentClass) {
1219             // A constant is replaced by its constant value.
1220             Object cv = ((VarSymbol)sym).getConstValue();
1221             if (cv != null) {
1222                 make.at(tree.pos);
1223                 return makeLit(sym.type, cv);
1224             }
1225             if (lambdaTranslationMap != null && lambdaTranslationMap.get(sym) != null) {
1226                 return make.at(tree.pos).Ident(lambdaTranslationMap.get(sym));
1227             } else {
1228                 // Otherwise replace the variable by its proxy.
1229                 sym = proxies.get(sym);
1230                 Assert.check(sym != null && (sym.flags_field & FINAL) != 0);
1231                 tree = make.at(tree.pos).Ident(sym);
1232             }
1233         }
1234         JCExpression base = (tree.hasTag(SELECT)) ? ((JCFieldAccess) tree).selected : null;
1235         switch (sym.kind) {
1236         case TYP:
1237             if (sym.owner.kind != PCK) {
1238                 // Make sure not to lose type fidelity due to symbol sharing between projections
1239                 boolean requireReferenceProjection = allowPrimitiveClasses &&
1240                         tree.hasTag(SELECT) && ((JCFieldAccess) tree).name == names.ref && tree.type.isReferenceProjection();
1241                 // Convert type idents to
1242                 // <flat name> or <package name> . <flat name>
1243                 Name flatname = Convert.shortName(sym.flatName());
1244                 while (base != null &&
1245                        TreeInfo.symbol(base) != null &&
1246                        TreeInfo.symbol(base).kind != PCK) {
1247                     base = (base.hasTag(SELECT))
1248                         ? ((JCFieldAccess) base).selected
1249                         : null;
1250                 }
1251                 if (tree.hasTag(IDENT)) {
1252                     ((JCIdent) tree).name = flatname;
1253                 } else if (base == null) {
1254                     tree = make.at(tree.pos).Ident(sym);
1255                     ((JCIdent) tree).name = flatname;
1256                     if (requireReferenceProjection) {
1257                         tree.setType(tree.type.referenceProjection());
1258                     }
1259                 } else {
1260                     ((JCFieldAccess) tree).selected = base;
1261                     ((JCFieldAccess) tree).name = flatname;
1262                     if (requireReferenceProjection) {
1263                         tree.setType(tree.type.referenceProjection());
1264                     }
1265                 }
1266             }
1267             break;
1268         case MTH: case VAR:
1269             if (sym.owner.kind == TYP) {
1270 
1271                 // Access methods are required for
1272                 //  - private members,
1273                 //  - protected members in a superclass of an
1274                 //    enclosing class contained in another package.
1275                 //  - all non-private members accessed via a qualified super.
1276                 boolean protAccess = refSuper && !needsPrivateAccess(sym)
1277                     || needsProtectedAccess(sym, tree);
1278                 boolean accReq = protAccess || needsPrivateAccess(sym);
1279 
1280                 // A base has to be supplied for
1281                 //  - simple identifiers accessing variables in outer classes.
1282                 boolean baseReq =
1283                     base == null &&
1284                     sym.owner != syms.predefClass &&

1342     JCExpression access(JCExpression tree) {
1343         Symbol sym = TreeInfo.symbol(tree);
1344         return sym == null ? tree : access(sym, tree, null, false);
1345     }
1346 
1347     /** Return access constructor for a private constructor,
1348      *  or the constructor itself, if no access constructor is needed.
1349      *  @param pos       The position to report diagnostics, if any.
1350      *  @param constr    The private constructor.
1351      */
1352     Symbol accessConstructor(DiagnosticPosition pos, Symbol constr) {
1353         if (needsPrivateAccess(constr)) {
1354             ClassSymbol accOwner = constr.owner.enclClass();
1355             MethodSymbol aconstr = accessConstrs.get(constr);
1356             if (aconstr == null) {
1357                 List<Type> argtypes = constr.type.getParameterTypes();
1358                 if ((accOwner.flags_field & ENUM) != 0)
1359                     argtypes = argtypes
1360                         .prepend(syms.intType)
1361                         .prepend(syms.stringType);
1362                 Name constructorName = accOwner.isConcreteValueClass() ? names.vnew : names.init;
1363                 aconstr = new MethodSymbol(
1364                     SYNTHETIC,
1365                     constructorName,
1366                     new MethodType(
1367                         argtypes.append(
1368                             accessConstructorTag().erasure(types)),
1369                         constr.type.getReturnType(),
1370                         constr.type.getThrownTypes(),
1371                         syms.methodClass),
1372                     accOwner);
1373                 enterSynthetic(pos, aconstr, accOwner.members());
1374                 accessConstrs.put(constr, aconstr);
1375                 accessed.append(constr);
1376             }
1377             return aconstr;
1378         } else {
1379             return constr;
1380         }
1381     }
1382 
1383     /** Return an anonymous class nested in this toplevel class.
1384      */
1385     ClassSymbol accessConstructorTag() {
1386         ClassSymbol topClass = currentClass.outermostClass();
1387         ModuleSymbol topModle = topClass.packge().modle;
1388         for (int i = 1; ; i++) {
1389             Name flatname = names.fromString("" + topClass.getQualifiedName() +
1390                                             target.syntheticNameChar() +
1391                                             i);
1392             ClassSymbol ctag = chk.getCompiled(topModle, flatname);
1393             if (ctag == null)
1394                 ctag = makeEmptyClass(STATIC | SYNTHETIC | IDENTITY_TYPE, topClass).sym;
1395             else if (!ctag.isAnonymous())
1396                 continue;
1397             // keep a record of all tags, to verify that all are generated as required
1398             accessConstrTags = accessConstrTags.prepend(ctag);
1399             return ctag;
1400         }
1401     }
1402 
1403     /** Add all required access methods for a private symbol to enclosing class.
1404      *  @param sym       The symbol.
1405      */
1406     void makeAccessible(Symbol sym) {
1407         JCClassDecl cdef = classDef(sym.owner.enclClass());
1408         if (cdef == null) Assert.error("class def not found: " + sym + " in " + sym.owner);
1409         if (names.isInitOrVNew(sym.name)) {
1410             cdef.defs = cdef.defs.prepend(
1411                 accessConstructorDef(cdef.pos, sym, accessConstrs.get(sym)));
1412         } else {
1413             MethodSymbol[] accessors = accessSyms.get(sym);
1414             for (int i = 0; i < AccessCode.numberOfAccessCodes; i++) {
1415                 if (accessors[i] != null)
1416                     cdef.defs = cdef.defs.prepend(
1417                         accessDef(cdef.pos, sym, accessors[i], i));
1418             }
1419         }
1420     }
1421 
1422     /** Construct definition of an access method.
1423      *  @param pos        The source code position of the definition.
1424      *  @param vsym       The private or protected symbol.
1425      *  @param accessor   The access method for the symbol.
1426      *  @param acode      The access code.
1427      */
1428     JCTree accessDef(int pos, Symbol vsym, MethodSymbol accessor, int acode) {
1429 //      System.err.println("access " + vsym + " with " + accessor);//DEBUG

1602         VarSymbol outerThis =
1603             new VarSymbol(flags | NOOUTERTHIS, outerThisName(target, owner), target, owner);
1604         outerThisStack = outerThisStack.prepend(outerThis);
1605         return outerThis;
1606     }
1607 
1608     private JCVariableDecl makeOuterThisVarDecl(int pos, VarSymbol sym) {
1609         JCVariableDecl vd = make.at(pos).VarDef(sym, null);
1610         vd.vartype = access(vd.vartype);
1611         return vd;
1612     }
1613 
1614     /** Definition for this$n field.
1615      *  @param pos        The source code position of the definition.
1616      *  @param owner      The method in which the definition goes.
1617      */
1618     JCVariableDecl outerThisDef(int pos, MethodSymbol owner) {
1619         ClassSymbol c = owner.enclClass();
1620         boolean isMandated =
1621             // Anonymous constructors
1622             (owner.isInitOrVNew() && owner.isAnonymous()) ||
1623             // Constructors of non-private inner member classes
1624             (owner.isInitOrVNew() && c.isInner() &&
1625              !c.isPrivate() && !c.isStatic());
1626         long flags =
1627             FINAL | (isMandated ? MANDATED : SYNTHETIC) | PARAMETER;
1628         VarSymbol outerThis = makeOuterThisVarSymbol(owner, flags);
1629         owner.extraParams = owner.extraParams.prepend(outerThis);
1630         return makeOuterThisVarDecl(pos, outerThis);
1631     }
1632 
1633     /** Definition for this$n field.
1634      *  @param pos        The source code position of the definition.
1635      *  @param owner      The class in which the definition goes.
1636      */
1637     JCVariableDecl outerThisDef(int pos, ClassSymbol owner) {
1638         VarSymbol outerThis = makeOuterThisVarSymbol(owner, FINAL | SYNTHETIC);
1639         return makeOuterThisVarDecl(pos, outerThis);
1640     }
1641 
1642     /** Return a list of trees that load the free variables in given list,
1643      *  in reverse order.
1644      *  @param pos          The source code position to be used for the trees.

1801         }
1802 
1803         JCStatement exceptionalRethrow = make.Throw(make.Ident(primaryException));
1804         JCBlock exceptionalCloseBlock = make.Block(0L, List.of(exceptionalCloseStatement, exceptionalRethrow));
1805         JCCatch exceptionalCatchClause = make.Catch(primaryExceptionDecl, exceptionalCloseBlock);
1806 
1807         //create the main try statement with the close:
1808         JCTry outerTry = make.Try(makeTwrBlock(resources.tail, block, depth + 1),
1809                                   List.of(exceptionalCatchClause),
1810                                   finallyClause);
1811 
1812         outerTry.finallyCanCompleteNormally = true;
1813         stats.add(outerTry);
1814 
1815         JCBlock newBlock = make.Block(0L, stats.toList());
1816         return newBlock;
1817     }
1818 
1819     private JCStatement makeResourceCloseInvocation(JCExpression resource) {
1820         // convert to AutoCloseable if needed
1821         if (types.asSuper(resource.type.referenceProjectionOrSelf(), syms.autoCloseableType.tsym) == null) {
1822             resource = convert(resource, syms.autoCloseableType);
1823         }
1824 
1825         // create resource.close() method invocation
1826         JCExpression resourceClose = makeCall(resource,
1827                                               names.close,
1828                                               List.nil());
1829         return make.Exec(resourceClose);
1830     }
1831 
1832     private JCExpression makeNonNullCheck(JCExpression expression) {
1833         return makeBinary(NE, expression, makeNull());
1834     }
1835 
1836     /** Construct a tree that represents the outer instance
1837      *  {@code C.this}. Never pick the current `this'.
1838      *  @param pos           The source code position to be used for the tree.
1839      *  @param c             The qualifier class.
1840      */
1841     JCExpression makeOuterThis(DiagnosticPosition pos, TypeSymbol c) {

1953     }
1954 
1955 /**************************************************************************
1956  * Code for .class
1957  *************************************************************************/
1958 
1959     /** Return the symbol of a class to contain a cache of
1960      *  compiler-generated statics such as class$ and the
1961      *  $assertionsDisabled flag.  We create an anonymous nested class
1962      *  (unless one already exists) and return its symbol.  However,
1963      *  for backward compatibility in 1.4 and earlier we use the
1964      *  top-level class itself.
1965      */
1966     private ClassSymbol outerCacheClass() {
1967         ClassSymbol clazz = outermostClassDef.sym;
1968         Scope s = clazz.members();
1969         for (Symbol sym : s.getSymbols(NON_RECURSIVE))
1970             if (sym.kind == TYP &&
1971                 sym.name == names.empty &&
1972                 (sym.flags() & INTERFACE) == 0) return (ClassSymbol) sym;
1973         return makeEmptyClass(STATIC | SYNTHETIC | IDENTITY_TYPE, clazz).sym;
1974     }
1975 
1976     /** Create an attributed tree of the form left.name(). */
1977     private JCMethodInvocation makeCall(JCExpression left, Name name, List<JCExpression> args) {
1978         Assert.checkNonNull(left.type);
1979         Symbol funcsym = lookupMethod(make_pos, name, left.type,
1980                                       TreeInfo.types(args));
1981         return make.App(make.Select(left, funcsym), args);
1982     }
1983 
1984     /** The tree simulating a T.class expression.
1985      *  @param clazz      The tree identifying type T.
1986      */
1987     private JCExpression classOf(JCTree clazz) {
1988         return classOfType(clazz.type, clazz.pos());
1989     }
1990 
1991     private JCExpression classOfType(Type type, DiagnosticPosition pos) {
1992         switch (type.getTag()) {
1993         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:

2005                 VarSymbol sym = new VarSymbol(
2006                         STATIC | PUBLIC | FINAL, names._class,
2007                         syms.classType, type.tsym);
2008                 return make_at(pos).Select(make.Type(type), sym);
2009         default:
2010             throw new AssertionError();
2011         }
2012     }
2013 
2014 /**************************************************************************
2015  * Code for enabling/disabling assertions.
2016  *************************************************************************/
2017 
2018     private ClassSymbol assertionsDisabledClassCache;
2019 
2020     /**Used to create an auxiliary class to hold $assertionsDisabled for interfaces.
2021      */
2022     private ClassSymbol assertionsDisabledClass() {
2023         if (assertionsDisabledClassCache != null) return assertionsDisabledClassCache;
2024 
2025         assertionsDisabledClassCache = makeEmptyClass(STATIC | SYNTHETIC | IDENTITY_TYPE, outermostClassDef.sym).sym;
2026 
2027         return assertionsDisabledClassCache;
2028     }
2029 
2030     // This code is not particularly robust if the user has
2031     // previously declared a member named '$assertionsDisabled'.
2032     // The same faulty idiom also appears in the translation of
2033     // class literals above.  We should report an error if a
2034     // previous declaration is not synthetic.
2035 
2036     private JCExpression assertFlagTest(DiagnosticPosition pos) {
2037         // Outermost class may be either true class or an interface.
2038         ClassSymbol outermostClass = outermostClassDef.sym;
2039 
2040         //only classes can hold a non-public field, look for a usable one:
2041         ClassSymbol container = !currentClass.isInterface() ? currentClass :
2042                 assertionsDisabledClass();
2043 
2044         VarSymbol assertDisabledSym =
2045             (VarSymbol)lookupSynthetic(dollarAssertionsDisabled,

2185     /** Visitor method: Translate a single node.
2186      *  Attach the source position from the old tree to its replacement tree.
2187      */
2188     @Override
2189     public <T extends JCTree> T translate(T tree) {
2190         if (tree == null) {
2191             return null;
2192         } else {
2193             make_at(tree.pos());
2194             T result = super.translate(tree);
2195             if (endPosTable != null && result != tree) {
2196                 endPosTable.replaceTree(tree, result);
2197             }
2198             return result;
2199         }
2200     }
2201 
2202     /** Visitor method: Translate a single node, boxing or unboxing if needed.
2203      */
2204     public <T extends JCExpression> T translate(T tree, Type type) {
2205         return (tree == null) ? null :
2206                 applyPrimitiveConversionsAsNeeded(boxIfNeeded(translate(tree), type), type);
2207     }
2208 
2209     /** Visitor method: Translate tree.
2210      */
2211     public <T extends JCTree> T translate(T tree, JCExpression enclOp) {
2212         JCExpression prevEnclOp = this.enclOp;
2213         this.enclOp = enclOp;
2214         T res = translate(tree);
2215         this.enclOp = prevEnclOp;
2216         return res;
2217     }
2218 
2219     /** Visitor method: Translate list of trees.
2220      */
2221     public <T extends JCExpression> List<T> translate(List<T> trees, Type type) {
2222         if (trees == null) return null;
2223         for (List<T> l = trees; l.nonEmpty(); l = l.tail)
2224             l.head = translate(l.head, type);
2225         return trees;
2226     }

2325             encl.trans_local = encl.trans_local.prepend(currentClass);
2326         }
2327 
2328         // Recursively translate members, taking into account that new members
2329         // might be created during the translation and prepended to the member
2330         // list `tree.defs'.
2331         List<JCTree> seen = List.nil();
2332         while (tree.defs != seen) {
2333             List<JCTree> unseen = tree.defs;
2334             for (List<JCTree> l = unseen; l.nonEmpty() && l != seen; l = l.tail) {
2335                 JCTree outermostMemberDefPrev = outermostMemberDef;
2336                 if (outermostMemberDefPrev == null) outermostMemberDef = l.head;
2337                 l.head = translate(l.head);
2338                 outermostMemberDef = outermostMemberDefPrev;
2339             }
2340             seen = unseen;
2341         }
2342 
2343         // Convert a protected modifier to public, mask static modifier.
2344         if ((tree.mods.flags & PROTECTED) != 0) tree.mods.flags |= PUBLIC;
2345         tree.mods.flags &= AdjustedClassFlags;
2346 
2347         // Convert name to flat representation, replacing '.' by '$'.
2348         tree.name = Convert.shortName(currentClass.flatName());
2349 
2350         // Add free variables proxy definitions to class.
2351 
2352         for (List<JCVariableDecl> l = fvdefs; l.nonEmpty(); l = l.tail) {
2353             tree.defs = tree.defs.prepend(l.head);
2354             enterSynthetic(tree.pos(), l.head.sym, currentClass.members());
2355         }
2356         // If this$n was accessed, add the field definition and
2357         // update initial constructors to initialize it
2358         if (currentClass.hasOuterInstance() && shouldEmitOuterThis(currentClass)) {
2359             tree.defs = tree.defs.prepend(otdef);
2360             enterSynthetic(tree.pos(), otdef.sym, currentClass.members());
2361 
2362            for (JCTree def : tree.defs) {
2363                 if (TreeInfo.isInitialConstructor(def)) {
2364                   JCMethodDecl mdef = (JCMethodDecl) def;
2365                   mdef.body.stats = mdef.body.stats.prepend(

2735 
2736         MethodType indyType = msym.type.asMethodType();
2737         indyType = new MethodType(
2738                 isStatic ? List.nil() : indyType.argtypes.prepend(tree.sym.type),
2739                 indyType.restype,
2740                 indyType.thrown,
2741                 syms.methodClass
2742         );
2743         DynamicMethodSymbol dynSym = new DynamicMethodSymbol(argName,
2744                 syms.noSymbol,
2745                 bsm.asHandle(),
2746                 indyType,
2747                 staticArgValues);
2748         JCFieldAccess qualifier = make.Select(make.QualIdent(site.tsym), argName);
2749         qualifier.sym = dynSym;
2750         qualifier.type = msym.type.asMethodType().restype;
2751         return qualifier;
2752     }
2753 
2754     public void visitMethodDef(JCMethodDecl tree) {
2755         // TODO - enum so is always <init>
2756         if (tree.name == names.init && (currentClass.flags_field&ENUM) != 0) {
2757             // Add "String $enum$name, int $enum$ordinal" to the beginning of the
2758             // argument list for each constructor of an enum.
2759             JCVariableDecl nameParam = make_at(tree.pos()).
2760                 Param(names.fromString(target.syntheticNameChar() +
2761                                        "enum" + target.syntheticNameChar() + "name"),
2762                       syms.stringType, tree.sym);
2763             nameParam.mods.flags |= SYNTHETIC; nameParam.sym.flags_field |= SYNTHETIC;
2764             JCVariableDecl ordParam = make.
2765                 Param(names.fromString(target.syntheticNameChar() +
2766                                        "enum" + target.syntheticNameChar() +
2767                                        "ordinal"),
2768                       syms.intType, tree.sym);
2769             ordParam.mods.flags |= SYNTHETIC; ordParam.sym.flags_field |= SYNTHETIC;
2770 
2771             MethodSymbol m = tree.sym;
2772             tree.params = tree.params.prepend(ordParam).prepend(nameParam);
2773 
2774             m.extraParams = m.extraParams.prepend(ordParam.sym);
2775             m.extraParams = m.extraParams.prepend(nameParam.sym);

2777             m.erasure_field = new MethodType(
2778                 olderasure.getParameterTypes().prepend(syms.intType).prepend(syms.stringType),
2779                 olderasure.getReturnType(),
2780                 olderasure.getThrownTypes(),
2781                 syms.methodClass);
2782         }
2783 
2784         JCMethodDecl prevMethodDef = currentMethodDef;
2785         MethodSymbol prevMethodSym = currentMethodSym;
2786         try {
2787             currentMethodDef = tree;
2788             currentMethodSym = tree.sym;
2789             visitMethodDefInternal(tree);
2790         } finally {
2791             currentMethodDef = prevMethodDef;
2792             currentMethodSym = prevMethodSym;
2793         }
2794     }
2795 
2796     private void visitMethodDefInternal(JCMethodDecl tree) {
2797         if (names.isInitOrVNew(tree.name) &&
2798             !currentClass.isStatic() &&
2799             (currentClass.isInner() || currentClass.isDirectlyOrIndirectlyLocal())) {
2800             // We are seeing a constructor of an inner class.
2801             MethodSymbol m = tree.sym;
2802 
2803             // Push a new proxy scope for constructor parameters.
2804             // and create definitions for any this$n and proxy parameters.
2805             Map<Symbol, Symbol> prevProxies = proxies;
2806             proxies = new HashMap<>(proxies);
2807             List<VarSymbol> prevOuterThisStack = outerThisStack;
2808             List<VarSymbol> fvs = freevars(currentClass);
2809             JCVariableDecl otdef = null;
2810             if (currentClass.hasOuterInstance())
2811                 otdef = outerThisDef(tree.pos, m);
2812             List<JCVariableDecl> fvdefs = freevarDefs(tree.pos, fvs, m, PARAMETER);
2813 
2814             // Recursively translate result type, parameters and thrown list.
2815             tree.restype = translate(tree.restype);
2816             tree.params = translateVarDefs(tree.params);
2817             tree.thrown = translate(tree.thrown);

2858             // pop local variables from proxy stack
2859             proxies = prevProxies;
2860 
2861             // recursively translate following local statements and
2862             // combine with this- or super-call
2863             List<JCStatement> stats = translate(tree.body.stats.tail);
2864             tree.body.stats = stats.prepend(selfCall).prependList(added);
2865             outerThisStack = prevOuterThisStack;
2866         } else {
2867             Map<Symbol, Symbol> prevLambdaTranslationMap =
2868                     lambdaTranslationMap;
2869             try {
2870                 lambdaTranslationMap = (tree.sym.flags() & SYNTHETIC) != 0 &&
2871                         tree.sym.name.startsWith(names.lambda) ?
2872                         makeTranslationMap(tree) : null;
2873                 super.visitMethodDef(tree);
2874             } finally {
2875                 lambdaTranslationMap = prevLambdaTranslationMap;
2876             }
2877         }
2878         if (names.isInitOrVNew(tree.name) && ((tree.sym.flags_field & Flags.COMPACT_RECORD_CONSTRUCTOR) != 0 ||
2879                 (tree.sym.flags_field & (GENERATEDCONSTR | RECORD)) == (GENERATEDCONSTR | RECORD))) {
2880             // lets find out if there is any field waiting to be initialized
2881             ListBuffer<VarSymbol> fields = new ListBuffer<>();
2882             for (Symbol sym : currentClass.getEnclosedElements()) {
2883                 if (sym.kind == Kinds.Kind.VAR && ((sym.flags() & RECORD) != 0))
2884                     fields.append((VarSymbol) sym);
2885             }
2886             for (VarSymbol field: fields) {
2887                 if ((field.flags_field & Flags.UNINITIALIZED_FIELD) != 0) {
2888                     VarSymbol param = tree.params.stream().filter(p -> p.name == field.name).findFirst().get().sym;
2889                     make.at(tree.pos);
2890                     tree.body.stats = tree.body.stats.append(
2891                             make.Exec(
2892                                     make.Assign(
2893                                             make.Select(make.This(field.owner.erasure(types)), field),
2894                                             make.Ident(param)).setType(field.erasure(types))));
2895                     // we don't need the flag at the field anymore
2896                     field.flags_field &= ~Flags.UNINITIALIZED_FIELD;
2897                 }
2898             }

3100                 List.nil() : List.of(translate(tree.detail));
3101             if (!tree.cond.type.isFalse()) {
3102                 cond = makeBinary
3103                     (AND,
3104                      cond,
3105                      makeUnary(NOT, tree.cond));
3106             }
3107             result =
3108                 make.If(cond,
3109                         make_at(tree).
3110                            Throw(makeNewClass(syms.assertionErrorType, exnArgs)),
3111                         null);
3112         } else {
3113             result = make.Skip();
3114         }
3115     }
3116 
3117     public void visitApply(JCMethodInvocation tree) {
3118         Symbol meth = TreeInfo.symbol(tree.meth);
3119         List<Type> argtypes = meth.type.getParameterTypes();
3120         // TODO - is enum so always <init>.
3121         if (names.isInitOrVNew(meth.name) && meth.owner == syms.enumSym)
3122             argtypes = argtypes.tail.tail;
3123         tree.args = boxArgs(argtypes, tree.args, tree.varargsElement);
3124         tree.varargsElement = null;
3125         Name methName = TreeInfo.name(tree.meth);
3126         if (names.isInitOrVNew(meth.name)) {
3127             // We are seeing a this(...) or super(...) constructor call.
3128             // If an access constructor is used, append null as a last argument.
3129             Symbol constructor = accessConstructor(tree.pos(), meth);
3130             if (constructor != meth) {
3131                 tree.args = tree.args.append(makeNull());
3132                 TreeInfo.setSymbol(tree.meth, constructor);
3133             }
3134 
3135             // If we are calling a constructor of a local class, add
3136             // free variables after explicit constructor arguments.
3137             ClassSymbol c = (ClassSymbol)constructor.owner;
3138             if (c.isDirectlyOrIndirectlyLocal() && !c.isStatic()) {
3139                 tree.args = tree.args.appendList(loadFreevars(tree.pos(), freevars(c)));
3140             }
3141 
3142             // If we are calling a constructor of an enum class, pass
3143             // along the name and ordinal arguments
3144             if ((c.flags_field&ENUM) != 0 || c.getQualifiedName() == names.java_lang_Enum) {
3145                 List<JCVariableDecl> params = currentMethodDef.params;
3146                 if (currentMethodSym.owner.hasOuterInstance())

3214             while (args.nonEmpty()) {
3215                 JCExpression arg = translate(args.head, varargsElement);
3216                 elems.append(arg);
3217                 args = args.tail;
3218             }
3219             JCNewArray boxedArgs = make.NewArray(make.Type(varargsElement),
3220                                                List.nil(),
3221                                                elems.toList());
3222             boxedArgs.type = new ArrayType(varargsElement, syms.arrayClass);
3223             result.append(boxedArgs);
3224         } else {
3225             if (args.length() != 1) throw new AssertionError(args);
3226             JCExpression arg = translate(args.head, parameter);
3227             anyChanges |= (arg != args.head);
3228             result.append(arg);
3229             if (!anyChanges) return _args;
3230         }
3231         return result.toList();
3232     }
3233 
3234     /** Apply primitive value/reference conversions as needed */
3235     @SuppressWarnings("unchecked")
3236     <T extends JCExpression> T applyPrimitiveConversionsAsNeeded(T tree, Type type) {
3237         boolean haveValue = tree.type.isPrimitiveClass();
3238         if (haveValue == type.isPrimitiveClass())
3239             return tree;
3240         // For narrowing conversion, insert a cast which should trigger a null check
3241         // For widening conversions, insert a cast if emitting a unified class file.
3242         return (T) make.TypeCast(type, tree);
3243     }
3244 
3245     /** Expand a boxing or unboxing conversion if needed. */
3246     @SuppressWarnings("unchecked") // XXX unchecked
3247     <T extends JCExpression> T boxIfNeeded(T tree, Type type) {
3248         boolean havePrimitive = tree.type.isPrimitive();
3249         if (havePrimitive == type.isPrimitive())
3250             return tree;
3251         if (havePrimitive) {
3252             Type unboxedTarget = types.unboxedType(type);
3253             if (!unboxedTarget.hasTag(NONE)) {
3254                 if (!types.isSubtype(tree.type, unboxedTarget)) //e.g. Character c = 89;
3255                     tree.type = unboxedTarget.constType(tree.type.constValue());
3256                 return (T)boxPrimitive(tree, types.erasure(type));
3257             } else {
3258                 tree = (T)boxPrimitive(tree);
3259             }
3260         } else {
3261             tree = (T)unbox(tree, type);
3262         }
3263         return tree;
3264     }

3628          * A statement of the form
3629          *
3630          * <pre>
3631          *     for ( T v : coll ) stmt ;
3632          * </pre>
3633          *
3634          * (where coll implements {@code Iterable<? extends T>}) gets translated to
3635          *
3636          * <pre>{@code
3637          *     for ( Iterator<? extends T> #i = coll.iterator(); #i.hasNext(); ) {
3638          *         T v = (T) #i.next();
3639          *         stmt;
3640          *     }
3641          * }</pre>
3642          *
3643          * where #i is a freshly named synthetic local variable.
3644          */
3645         private void visitIterableForeachLoop(JCEnhancedForLoop tree) {
3646             make_at(tree.expr.pos());
3647             Type iteratorTarget = syms.objectType;
3648             Type iterableType = types.asSuper(types.cvarUpperBound(tree.expr.type.referenceProjectionOrSelf()),
3649                                               syms.iterableType.tsym);
3650             if (iterableType.getTypeArguments().nonEmpty())
3651                 iteratorTarget = types.erasure(iterableType.getTypeArguments().head);
3652             tree.expr.type = types.erasure(types.skipTypeVars(tree.expr.type, false));
3653             tree.expr = transTypes.coerce(attrEnv, tree.expr, types.erasure(iterableType));
3654             Symbol iterator = lookupMethod(tree.expr.pos(),
3655                                            names.iterator,
3656                                            tree.expr.type,
3657                                            List.nil());
3658             Assert.check(types.isSameType(types.erasure(types.asSuper(iterator.type.getReturnType().referenceProjectionOrSelf(), syms.iteratorType.tsym)), types.erasure(syms.iteratorType)));
3659             VarSymbol itvar = new VarSymbol(SYNTHETIC, names.fromString("i" + target.syntheticNameChar()),
3660                                             types.erasure(syms.iteratorType),
3661                                             currentMethodSym);
3662 
3663              JCStatement init = make.
3664                 VarDef(itvar, make.App(make.Select(tree.expr, iterator)
3665                      .setType(types.erasure(iterator.type))));
3666 
3667             Symbol hasNext = lookupMethod(tree.expr.pos(),
3668                                           names.hasNext,
3669                                           itvar.type,
3670                                           List.nil());
3671             JCMethodInvocation cond = make.App(make.Select(make.Ident(itvar), hasNext));
3672             Symbol next = lookupMethod(tree.expr.pos(),
3673                                        names.next,
3674                                        itvar.type,
3675                                        List.nil());
3676             JCExpression vardefinit = make.App(make.Select(make.Ident(itvar), next));
3677 
3678             Assert.check(tree.getDeclarationKind() == EnhancedForLoopTree.DeclarationKind.VARIABLE);

3721                 new MethodSymbol(tree.flags | BLOCK,
3722                                  names.empty, null,
3723                                  currentClass);
3724         }
3725         super.visitBlock(tree);
3726         currentMethodSym = oldMethodSym;
3727     }
3728 
3729     public void visitDoLoop(JCDoWhileLoop tree) {
3730         tree.body = translate(tree.body);
3731         tree.cond = translate(tree.cond, syms.booleanType);
3732         result = tree;
3733     }
3734 
3735     public void visitWhileLoop(JCWhileLoop tree) {
3736         tree.cond = translate(tree.cond, syms.booleanType);
3737         tree.body = translate(tree.body);
3738         result = tree;
3739     }
3740 
3741     public void visitWithField(JCWithField tree) {
3742         Type fieldType = tree.field.type;
3743         tree.field = translate(tree.field, tree);
3744         tree.value = translate(tree.value, fieldType); // important to use pre-translation type.
3745 
3746         // If translated field is an Apply, we are
3747         // seeing an access method invocation. In this case, append
3748         // right hand side as last argument of the access method.
3749         if (tree.field.hasTag(APPLY)) {
3750             JCMethodInvocation app = (JCMethodInvocation) tree.field;
3751             app.args = List.of(tree.value).prependList(app.args);
3752             result = app;
3753         } else {
3754             result = tree;
3755         }
3756     }
3757 
3758     public void visitForLoop(JCForLoop tree) {
3759         tree.init = translate(tree.init);
3760         if (tree.cond != null)
3761             tree.cond = translate(tree.cond, syms.booleanType);
3762         tree.step = translate(tree.step);
3763         tree.body = translate(tree.body);
3764         result = tree;
3765     }
3766 
3767     public void visitReturn(JCReturn tree) {
3768         if (tree.expr != null)
3769             tree.expr = translate(tree.expr,
3770                                   types.erasure(currentMethodDef
3771                                                 .restype.type));
3772         result = tree;
3773     }
3774 
3775     public void visitSwitch(JCSwitch tree) {
3776         List<JCCase> cases = tree.patternSwitch ? addDefaultIfNeeded(tree.patternSwitch,
3777                                                                      tree.wasEnumSelector,

4231         tree.value = translate(tree.value, tree.target.type);
4232         result = tree;
4233     }
4234 
4235     public void visitNewArray(JCNewArray tree) {
4236         tree.elemtype = translate(tree.elemtype);
4237         for (List<JCExpression> t = tree.dims; t.tail != null; t = t.tail)
4238             if (t.head != null) t.head = translate(t.head, syms.intType);
4239         tree.elems = translate(tree.elems, types.elemtype(tree.type));
4240         result = tree;
4241     }
4242 
4243     public void visitSelect(JCFieldAccess tree) {
4244         // need to special case-access of the form C.super.x
4245         // these will always need an access method, unless C
4246         // is a default interface subclassed by the current class.
4247         boolean qualifiedSuperAccess =
4248             tree.selected.hasTag(SELECT) &&
4249             TreeInfo.name(tree.selected) == names._super &&
4250             !types.isDirectSuperInterface(((JCFieldAccess)tree.selected).selected.type.tsym, currentClass);
4251         /* JDK-8269956: Where a reflective (class) literal is needed, the unqualified Point.class is
4252          * always the "primary" mirror - representing the primitive reference runtime type - thereby
4253          * always matching the behavior of Object::getClass
4254          */
4255         boolean needPrimaryMirror = tree.name == names._class && tree.selected.type.isReferenceProjection();
4256         tree.selected = translate(tree.selected);
4257         if (needPrimaryMirror && allowPrimitiveClasses && tree.selected.type.isPrimitiveClass()) {
4258             tree.selected.setType(tree.selected.type.referenceProjection());
4259         }
4260         if (tree.name == names._class) {
4261             result = classOf(tree.selected);
4262         }
4263         else if (tree.name == names._super &&
4264                 types.isDirectSuperInterface(tree.selected.type.tsym, currentClass)) {
4265             //default super call!! Not a classic qualified super call
4266             TypeSymbol supSym = tree.selected.type.tsym;
4267             Assert.checkNonNull(types.asSuper(currentClass.type.referenceProjectionOrSelf(), supSym));
4268             result = tree;
4269         }
4270         else if (tree.name == names._this || tree.name == names._super) {
4271             result = makeThis(tree.pos(), tree.selected.type.tsym);
4272         }
4273         else
4274             result = access(tree.sym, tree, enclOp, qualifiedSuperAccess);
4275     }
4276 
4277     public void visitLetExpr(LetExpr tree) {
4278         tree.defs = translate(tree.defs);
4279         tree.expr = translate(tree.expr, tree.type);
4280         result = tree;
4281     }
4282 
4283     // There ought to be nothing to rewrite here;
4284     // we don't generate code.
4285     public void visitAnnotation(JCAnnotation tree) {
4286         result = tree;
4287     }
< prev index next >