< prev index next >

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

Print this page

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

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

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

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

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

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



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



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



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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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











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

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

3685                 new MethodSymbol(tree.flags | BLOCK,
3686                                  names.empty, null,
3687                                  currentClass);
3688         }
3689         super.visitBlock(tree);
3690         currentMethodSym = oldMethodSym;
3691     }
3692 
3693     public void visitDoLoop(JCDoWhileLoop tree) {
3694         tree.body = translate(tree.body);
3695         tree.cond = translate(tree.cond, syms.booleanType);
3696         result = tree;
3697     }
3698 
3699     public void visitWhileLoop(JCWhileLoop tree) {
3700         tree.cond = translate(tree.cond, syms.booleanType);
3701         tree.body = translate(tree.body);
3702         result = tree;
3703     }
3704 

















3705     public void visitForLoop(JCForLoop tree) {
3706         tree.init = translate(tree.init);
3707         if (tree.cond != null)
3708             tree.cond = translate(tree.cond, syms.booleanType);
3709         tree.step = translate(tree.step);
3710         tree.body = translate(tree.body);
3711         result = tree;
3712     }
3713 
3714     public void visitReturn(JCReturn tree) {
3715         if (tree.expr != null)
3716             tree.expr = translate(tree.expr,
3717                                   types.erasure(currentMethodDef
3718                                                 .restype.type));
3719         result = tree;
3720     }
3721 
3722     public void visitSwitch(JCSwitch tree) {
3723         List<JCCase> cases = tree.patternSwitch ? addDefaultIfNeeded(tree.patternSwitch,
3724                                                                      tree.wasEnumSelector,

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





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



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

  84 
  85     private final Names names;
  86     private final Log log;
  87     private final Symtab syms;
  88     private final Resolve rs;
  89     private final Operators operators;
  90     private final Check chk;
  91     private final Attr attr;
  92     private TreeMaker make;
  93     private DiagnosticPosition make_pos;
  94     private final ConstFold cfolder;
  95     private final Target target;
  96     private final TypeEnvs typeEnvs;
  97     private final Name dollarAssertionsDisabled;
  98     private final Types types;
  99     private final TransTypes transTypes;
 100     private final boolean debugLower;
 101     private final boolean disableProtectedAccessors; // experimental
 102     private final PkgInfo pkginfoOpt;
 103     private final boolean optimizeOuterThis;
 104     private final boolean allowPrimitiveClasses;
 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         allowPrimitiveClasses = Source.Feature.PRIMITIVE_CLASSES.allowedInSource(source) && options.isSet("enablePrimitiveClasses");
 135         Preview preview = Preview.instance(context);
 136         useMatchException = Feature.PATTERN_SWITCH.allowedInSource(source) &&
 137                             (preview.isEnabled() || !preview.isPreview(Feature.PATTERN_SWITCH));
 138     }
 139 
 140     /** The currently enclosing class.
 141      */
 142     ClassSymbol currentClass;
 143 
 144     /** A queue of all translated classes.
 145      */
 146     ListBuffer<JCTree> translated;
 147 
 148     /** Environment for symbol lookup, set by translateTopLevelClass.
 149      */
 150     Env<AttrContext> attrEnv;
 151 
 152     /** A hash table mapping syntax trees to their ending source positions.
 153      */
 154     EndPosTable endPosTable;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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