< 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     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;

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

1043 
1044     /** The qualifier to be used for accessing a symbol in an outer class.
1045      *  This is either C.sym or C.this.sym, depending on whether or not
1046      *  sym is static.
1047      *  @param sym   The accessed symbol.
1048      */
1049     JCExpression accessBase(DiagnosticPosition pos, Symbol sym) {
1050         return (sym.flags() & STATIC) != 0
1051             ? access(make.at(pos.getStartPosition()).QualIdent(sym.owner))
1052             : makeOwnerThis(pos, sym, true);
1053     }
1054 
1055     /** Do we need an access method to reference private symbol?
1056      */
1057     boolean needsPrivateAccess(Symbol sym) {
1058         if (target.hasNestmateAccess()) {
1059             return false;
1060         }
1061         if ((sym.flags() & PRIVATE) == 0 || sym.owner == currentClass) {
1062             return false;
1063         } else if (sym.name == names.init && sym.owner.isDirectlyOrIndirectlyLocal()) {
1064             // private constructor in local class: relax protection
1065             sym.flags_field &= ~PRIVATE;
1066             return false;
1067         } else {
1068             return true;
1069         }
1070     }
1071 
1072     /** Do we need an access method to reference symbol in other package?
1073      */
1074     boolean needsProtectedAccess(Symbol sym, JCTree tree) {
1075         if (disableProtectedAccessors) return false;
1076         if ((sym.flags() & PROTECTED) == 0 ||
1077             sym.owner.owner == currentClass.owner || // fast special case
1078             sym.packge() == currentClass.packge())
1079             return false;
1080         if (!currentClass.isSubClass(sym.owner, types))
1081             return true;
1082         if ((sym.flags() & STATIC) != 0 ||
1083             !tree.hasTag(SELECT) ||

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



1152                 // Convert type idents to
1153                 // <flat name> or <package name> . <flat name>
1154                 Name flatname = Convert.shortName(sym.flatName());
1155                 while (base != null &&
1156                        TreeInfo.symbol(base) != null &&
1157                        TreeInfo.symbol(base).kind != PCK) {
1158                     base = (base.hasTag(SELECT))
1159                         ? ((JCFieldAccess) base).selected
1160                         : null;
1161                 }
1162                 if (tree.hasTag(IDENT)) {
1163                     ((JCIdent) tree).name = flatname;
1164                 } else if (base == null) {
1165                     tree = make.at(tree.pos).Ident(sym);
1166                     ((JCIdent) tree).name = flatname;



1167                 } else {
1168                     ((JCFieldAccess) tree).selected = base;
1169                     ((JCFieldAccess) tree).name = flatname;



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

1247     JCExpression access(JCExpression tree) {
1248         Symbol sym = TreeInfo.symbol(tree);
1249         return sym == null ? tree : access(sym, tree, null, false);
1250     }
1251 
1252     /** Return access constructor for a private constructor,
1253      *  or the constructor itself, if no access constructor is needed.
1254      *  @param pos       The position to report diagnostics, if any.
1255      *  @param constr    The private constructor.
1256      */
1257     Symbol accessConstructor(DiagnosticPosition pos, Symbol constr) {
1258         if (needsPrivateAccess(constr)) {
1259             ClassSymbol accOwner = constr.owner.enclClass();
1260             MethodSymbol aconstr = accessConstrs.get(constr);
1261             if (aconstr == null) {
1262                 List<Type> argtypes = constr.type.getParameterTypes();
1263                 if ((accOwner.flags_field & ENUM) != 0)
1264                     argtypes = argtypes
1265                         .prepend(syms.intType)
1266                         .prepend(syms.stringType);

1267                 aconstr = new MethodSymbol(
1268                     SYNTHETIC,
1269                     names.init,
1270                     new MethodType(
1271                         argtypes.append(
1272                             accessConstructorTag().erasure(types)),
1273                         constr.type.getReturnType(),
1274                         constr.type.getThrownTypes(),
1275                         syms.methodClass),
1276                     accOwner);
1277                 enterSynthetic(pos, aconstr, accOwner.members());
1278                 accessConstrs.put(constr, aconstr);
1279                 accessed.append(constr);
1280             }
1281             return aconstr;
1282         } else {
1283             return constr;
1284         }
1285     }
1286 
1287     /** Return an anonymous class nested in this toplevel class.
1288      */
1289     ClassSymbol accessConstructorTag() {
1290         ClassSymbol topClass = currentClass.outermostClass();
1291         ModuleSymbol topModle = topClass.packge().modle;
1292         for (int i = 1; ; i++) {
1293             Name flatname = names.fromString("" + topClass.getQualifiedName() +
1294                                             target.syntheticNameChar() +
1295                                             i);
1296             ClassSymbol ctag = chk.getCompiled(topModle, flatname);
1297             if (ctag == null)
1298                 ctag = makeEmptyClass(STATIC | SYNTHETIC, topClass).sym;
1299             else if (!ctag.isAnonymous())
1300                 continue;
1301             // keep a record of all tags, to verify that all are generated as required
1302             accessConstrTags = accessConstrTags.prepend(ctag);
1303             return ctag;
1304         }
1305     }
1306 
1307     /** Add all required access methods for a private symbol to enclosing class.
1308      *  @param sym       The symbol.
1309      */
1310     void makeAccessible(Symbol sym) {
1311         JCClassDecl cdef = classDef(sym.owner.enclClass());
1312         if (cdef == null) Assert.error("class def not found: " + sym + " in " + sym.owner);
1313         if (sym.name == names.init) {
1314             cdef.defs = cdef.defs.prepend(
1315                 accessConstructorDef(cdef.pos, sym, accessConstrs.get(sym)));
1316         } else {
1317             MethodSymbol[] accessors = accessSyms.get(sym);
1318             for (int i = 0; i < AccessCode.numberOfAccessCodes; i++) {
1319                 if (accessors[i] != null)
1320                     cdef.defs = cdef.defs.prepend(
1321                         accessDef(cdef.pos, sym, accessors[i], i));
1322             }
1323         }
1324     }
1325 
1326     /** Construct definition of an access method.
1327      *  @param pos        The source code position of the definition.
1328      *  @param vsym       The private or protected symbol.
1329      *  @param accessor   The access method for the symbol.
1330      *  @param acode      The access code.
1331      */
1332     JCTree accessDef(int pos, Symbol vsym, MethodSymbol accessor, int acode) {
1333 //      System.err.println("access " + vsym + " with " + accessor);//DEBUG

1506         VarSymbol outerThis =
1507             new VarSymbol(flags | NOOUTERTHIS, outerThisName(target, owner), target, owner);
1508         outerThisStack = outerThisStack.prepend(outerThis);
1509         return outerThis;
1510     }
1511 
1512     private JCVariableDecl makeOuterThisVarDecl(int pos, VarSymbol sym) {
1513         JCVariableDecl vd = make.at(pos).VarDef(sym, null);
1514         vd.vartype = access(vd.vartype);
1515         return vd;
1516     }
1517 
1518     /** Definition for this$n field.
1519      *  @param pos        The source code position of the definition.
1520      *  @param owner      The method in which the definition goes.
1521      */
1522     JCVariableDecl outerThisDef(int pos, MethodSymbol owner) {
1523         ClassSymbol c = owner.enclClass();
1524         boolean isMandated =
1525             // Anonymous constructors
1526             (owner.isConstructor() && owner.isAnonymous()) ||
1527             // Constructors of non-private inner member classes
1528             (owner.isConstructor() && c.isInner() &&
1529              !c.isPrivate() && !c.isStatic());
1530         long flags =
1531             FINAL | (isMandated ? MANDATED : SYNTHETIC) | PARAMETER;
1532         VarSymbol outerThis = makeOuterThisVarSymbol(owner, flags);
1533         owner.extraParams = owner.extraParams.prepend(outerThis);
1534         return makeOuterThisVarDecl(pos, outerThis);
1535     }
1536 
1537     /** Definition for this$n field.
1538      *  @param pos        The source code position of the definition.
1539      *  @param owner      The class in which the definition goes.
1540      */
1541     JCVariableDecl outerThisDef(int pos, ClassSymbol owner) {
1542         VarSymbol outerThis = makeOuterThisVarSymbol(owner, FINAL | SYNTHETIC);
1543         return makeOuterThisVarDecl(pos, outerThis);
1544     }
1545 
1546     /** Return a list of trees that load the free variables in given list,
1547      *  in reverse order.
1548      *  @param pos          The source code position to be used for the trees.

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

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

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

2089     /** Visitor method: Translate a single node.
2090      *  Attach the source position from the old tree to its replacement tree.
2091      */
2092     @Override
2093     public <T extends JCTree> T translate(T tree) {
2094         if (tree == null) {
2095             return null;
2096         } else {
2097             make_at(tree.pos());
2098             T result = super.translate(tree);
2099             if (endPosTable != null && result != tree) {
2100                 endPosTable.replaceTree(tree, result);
2101             }
2102             return result;
2103         }
2104     }
2105 
2106     /** Visitor method: Translate a single node, boxing or unboxing if needed.
2107      */
2108     public <T extends JCExpression> T translate(T tree, Type type) {
2109         return (tree == null) ? null : boxIfNeeded(translate(tree), type);

2110     }
2111 
2112     /** Visitor method: Translate tree.
2113      */
2114     public <T extends JCTree> T translate(T tree, JCExpression enclOp) {
2115         JCExpression prevEnclOp = this.enclOp;
2116         this.enclOp = enclOp;
2117         T res = translate(tree);
2118         this.enclOp = prevEnclOp;
2119         return res;
2120     }
2121 
2122     /** Visitor method: Translate list of trees.
2123      */
2124     public <T extends JCExpression> List<T> translate(List<T> trees, Type type) {
2125         if (trees == null) return null;
2126         for (List<T> l = trees; l.nonEmpty(); l = l.tail)
2127             l.head = translate(l.head, type);
2128         return trees;
2129     }

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

2638 
2639         MethodType indyType = msym.type.asMethodType();
2640         indyType = new MethodType(
2641                 isStatic ? List.nil() : indyType.argtypes.prepend(tree.sym.type),
2642                 indyType.restype,
2643                 indyType.thrown,
2644                 syms.methodClass
2645         );
2646         DynamicMethodSymbol dynSym = new DynamicMethodSymbol(argName,
2647                 syms.noSymbol,
2648                 bsm.asHandle(),
2649                 indyType,
2650                 staticArgValues);
2651         JCFieldAccess qualifier = make.Select(make.QualIdent(site.tsym), argName);
2652         qualifier.sym = dynSym;
2653         qualifier.type = msym.type.asMethodType().restype;
2654         return qualifier;
2655     }
2656 
2657     public void visitMethodDef(JCMethodDecl tree) {

2658         if (tree.name == names.init && (currentClass.flags_field&ENUM) != 0) {
2659             // Add "String $enum$name, int $enum$ordinal" to the beginning of the
2660             // argument list for each constructor of an enum.
2661             JCVariableDecl nameParam = make_at(tree.pos()).
2662                 Param(names.fromString(target.syntheticNameChar() +
2663                                        "enum" + target.syntheticNameChar() + "name"),
2664                       syms.stringType, tree.sym);
2665             nameParam.mods.flags |= SYNTHETIC; nameParam.sym.flags_field |= SYNTHETIC;
2666             JCVariableDecl ordParam = make.
2667                 Param(names.fromString(target.syntheticNameChar() +
2668                                        "enum" + target.syntheticNameChar() +
2669                                        "ordinal"),
2670                       syms.intType, tree.sym);
2671             ordParam.mods.flags |= SYNTHETIC; ordParam.sym.flags_field |= SYNTHETIC;
2672 
2673             MethodSymbol m = tree.sym;
2674             tree.params = tree.params.prepend(ordParam).prepend(nameParam);
2675 
2676             m.extraParams = m.extraParams.prepend(ordParam.sym);
2677             m.extraParams = m.extraParams.prepend(nameParam.sym);

2679             m.erasure_field = new MethodType(
2680                 olderasure.getParameterTypes().prepend(syms.intType).prepend(syms.stringType),
2681                 olderasure.getReturnType(),
2682                 olderasure.getThrownTypes(),
2683                 syms.methodClass);
2684         }
2685 
2686         JCMethodDecl prevMethodDef = currentMethodDef;
2687         MethodSymbol prevMethodSym = currentMethodSym;
2688         try {
2689             currentMethodDef = tree;
2690             currentMethodSym = tree.sym;
2691             visitMethodDefInternal(tree);
2692         } finally {
2693             currentMethodDef = prevMethodDef;
2694             currentMethodSym = prevMethodSym;
2695         }
2696     }
2697 
2698     private void visitMethodDefInternal(JCMethodDecl tree) {
2699         if (tree.name == names.init &&
2700             !currentClass.isStatic() &&
2701             (currentClass.isInner() || currentClass.isDirectlyOrIndirectlyLocal())) {
2702             // We are seeing a constructor of an inner class.
2703             MethodSymbol m = tree.sym;
2704 
2705             // Push a new proxy scope for constructor parameters.
2706             // and create definitions for any this$n and proxy parameters.
2707             Map<Symbol, Symbol> prevProxies = proxies;
2708             proxies = new HashMap<>(proxies);
2709             List<VarSymbol> prevOuterThisStack = outerThisStack;
2710             List<VarSymbol> fvs = freevars(currentClass);
2711             JCVariableDecl otdef = null;
2712             if (currentClass.hasOuterInstance())
2713                 otdef = outerThisDef(tree.pos, m);
2714             List<JCVariableDecl> fvdefs = freevarDefs(tree.pos, fvs, m, PARAMETER);
2715 
2716             // Recursively translate result type, parameters and thrown list.
2717             tree.restype = translate(tree.restype);
2718             tree.params = translateVarDefs(tree.params);
2719             tree.thrown = translate(tree.thrown);

2760             // pop local variables from proxy stack
2761             proxies = prevProxies;
2762 
2763             // recursively translate following local statements and
2764             // combine with this- or super-call
2765             List<JCStatement> stats = translate(tree.body.stats.tail);
2766             tree.body.stats = stats.prepend(selfCall).prependList(added);
2767             outerThisStack = prevOuterThisStack;
2768         } else {
2769             Map<Symbol, Symbol> prevLambdaTranslationMap =
2770                     lambdaTranslationMap;
2771             try {
2772                 lambdaTranslationMap = (tree.sym.flags() & SYNTHETIC) != 0 &&
2773                         tree.sym.name.startsWith(names.lambda) ?
2774                         makeTranslationMap(tree) : null;
2775                 super.visitMethodDef(tree);
2776             } finally {
2777                 lambdaTranslationMap = prevLambdaTranslationMap;
2778             }
2779         }
2780         if (tree.name == names.init && ((tree.sym.flags_field & Flags.COMPACT_RECORD_CONSTRUCTOR) != 0 ||
2781                 (tree.sym.flags_field & (GENERATEDCONSTR | RECORD)) == (GENERATEDCONSTR | RECORD))) {
2782             // lets find out if there is any field waiting to be initialized
2783             ListBuffer<VarSymbol> fields = new ListBuffer<>();
2784             for (Symbol sym : currentClass.getEnclosedElements()) {
2785                 if (sym.kind == Kinds.Kind.VAR && ((sym.flags() & RECORD) != 0))
2786                     fields.append((VarSymbol) sym);
2787             }
2788             for (VarSymbol field: fields) {
2789                 if ((field.flags_field & Flags.UNINITIALIZED_FIELD) != 0) {
2790                     VarSymbol param = tree.params.stream().filter(p -> p.name == field.name).findFirst().get().sym;
2791                     make.at(tree.pos);
2792                     tree.body.stats = tree.body.stats.append(
2793                             make.Exec(
2794                                     make.Assign(
2795                                             make.Select(make.This(field.owner.erasure(types)), field),
2796                                             make.Ident(param)).setType(field.erasure(types))));
2797                     // we don't need the flag at the field anymore
2798                     field.flags_field &= ~Flags.UNINITIALIZED_FIELD;
2799                 }
2800             }

3002                 List.nil() : List.of(translate(tree.detail));
3003             if (!tree.cond.type.isFalse()) {
3004                 cond = makeBinary
3005                     (AND,
3006                      cond,
3007                      makeUnary(NOT, tree.cond));
3008             }
3009             result =
3010                 make.If(cond,
3011                         make_at(tree).
3012                            Throw(makeNewClass(syms.assertionErrorType, exnArgs)),
3013                         null);
3014         } else {
3015             result = make.Skip();
3016         }
3017     }
3018 
3019     public void visitApply(JCMethodInvocation tree) {
3020         Symbol meth = TreeInfo.symbol(tree.meth);
3021         List<Type> argtypes = meth.type.getParameterTypes();
3022         if (meth.name == names.init && meth.owner == syms.enumSym)

3023             argtypes = argtypes.tail.tail;
3024         tree.args = boxArgs(argtypes, tree.args, tree.varargsElement);
3025         tree.varargsElement = null;
3026         Name methName = TreeInfo.name(tree.meth);
3027         if (meth.name==names.init) {
3028             // We are seeing a this(...) or super(...) constructor call.
3029             // If an access constructor is used, append null as a last argument.
3030             Symbol constructor = accessConstructor(tree.pos(), meth);
3031             if (constructor != meth) {
3032                 tree.args = tree.args.append(makeNull());
3033                 TreeInfo.setSymbol(tree.meth, constructor);
3034             }
3035 
3036             // If we are calling a constructor of a local class, add
3037             // free variables after explicit constructor arguments.
3038             ClassSymbol c = (ClassSymbol)constructor.owner;
3039             if (c.isDirectlyOrIndirectlyLocal() && !c.isStatic()) {
3040                 tree.args = tree.args.appendList(loadFreevars(tree.pos(), freevars(c)));
3041             }
3042 
3043             // If we are calling a constructor of an enum class, pass
3044             // along the name and ordinal arguments
3045             if ((c.flags_field&ENUM) != 0 || c.getQualifiedName() == names.java_lang_Enum) {
3046                 List<JCVariableDecl> params = currentMethodDef.params;
3047                 if (currentMethodSym.owner.hasOuterInstance())

3109             while (args.nonEmpty()) {
3110                 JCExpression arg = translate(args.head, varargsElement);
3111                 elems.append(arg);
3112                 args = args.tail;
3113             }
3114             JCNewArray boxedArgs = make.NewArray(make.Type(varargsElement),
3115                                                List.nil(),
3116                                                elems.toList());
3117             boxedArgs.type = new ArrayType(varargsElement, syms.arrayClass);
3118             result.append(boxedArgs);
3119         } else {
3120             if (args.length() != 1) throw new AssertionError(args);
3121             JCExpression arg = translate(args.head, parameter);
3122             anyChanges |= (arg != args.head);
3123             result.append(arg);
3124             if (!anyChanges) return _args;
3125         }
3126         return result.toList();
3127     }
3128 











3129     /** Expand a boxing or unboxing conversion if needed. */
3130     @SuppressWarnings("unchecked") // XXX unchecked
3131     <T extends JCExpression> T boxIfNeeded(T tree, Type type) {
3132         boolean havePrimitive = tree.type.isPrimitive();
3133         if (havePrimitive == type.isPrimitive())
3134             return tree;
3135         if (havePrimitive) {
3136             Type unboxedTarget = types.unboxedType(type);
3137             if (!unboxedTarget.hasTag(NONE)) {
3138                 if (!types.isSubtype(tree.type, unboxedTarget)) //e.g. Character c = 89;
3139                     tree.type = unboxedTarget.constType(tree.type.constValue());
3140                 return (T)boxPrimitive(tree, types.erasure(type));
3141             } else {
3142                 tree = (T)boxPrimitive(tree);
3143             }
3144         } else {
3145             tree = (T)unbox(tree, type);
3146         }
3147         return tree;
3148     }

3512          * A statement of the form
3513          *
3514          * <pre>
3515          *     for ( T v : coll ) stmt ;
3516          * </pre>
3517          *
3518          * (where coll implements {@code Iterable<? extends T>}) gets translated to
3519          *
3520          * <pre>{@code
3521          *     for ( Iterator<? extends T> #i = coll.iterator(); #i.hasNext(); ) {
3522          *         T v = (T) #i.next();
3523          *         stmt;
3524          *     }
3525          * }</pre>
3526          *
3527          * where #i is a freshly named synthetic local variable.
3528          */
3529         private void visitIterableForeachLoop(JCEnhancedForLoop tree) {
3530             make_at(tree.expr.pos());
3531             Type iteratorTarget = syms.objectType;
3532             Type iterableType = types.asSuper(types.cvarUpperBound(tree.expr.type),
3533                                               syms.iterableType.tsym);
3534             if (iterableType.getTypeArguments().nonEmpty())
3535                 iteratorTarget = types.erasure(iterableType.getTypeArguments().head);
3536             tree.expr.type = types.erasure(types.skipTypeVars(tree.expr.type, false));
3537             tree.expr = transTypes.coerce(attrEnv, tree.expr, types.erasure(iterableType));
3538             Symbol iterator = lookupMethod(tree.expr.pos(),
3539                                            names.iterator,
3540                                            tree.expr.type,
3541                                            List.nil());
3542             Assert.check(types.isSameType(types.erasure(types.asSuper(iterator.type.getReturnType(), syms.iteratorType.tsym)), types.erasure(syms.iteratorType)));
3543             VarSymbol itvar = new VarSymbol(SYNTHETIC, names.fromString("i" + target.syntheticNameChar()),
3544                                             types.erasure(syms.iteratorType),
3545                                             currentMethodSym);
3546 
3547              JCStatement init = make.
3548                 VarDef(itvar, make.App(make.Select(tree.expr, iterator)
3549                      .setType(types.erasure(iterator.type))));
3550 
3551             Symbol hasNext = lookupMethod(tree.expr.pos(),
3552                                           names.hasNext,
3553                                           itvar.type,
3554                                           List.nil());
3555             JCMethodInvocation cond = make.App(make.Select(make.Ident(itvar), hasNext));
3556             Symbol next = lookupMethod(tree.expr.pos(),
3557                                        names.next,
3558                                        itvar.type,
3559                                        List.nil());
3560             JCExpression vardefinit = make.App(make.Select(make.Ident(itvar), next));
3561 
3562             Assert.check(tree.getDeclarationKind() == EnhancedForLoopTree.DeclarationKind.VARIABLE);

3605                 new MethodSymbol(tree.flags | BLOCK,
3606                                  names.empty, null,
3607                                  currentClass);
3608         }
3609         super.visitBlock(tree);
3610         currentMethodSym = oldMethodSym;
3611     }
3612 
3613     public void visitDoLoop(JCDoWhileLoop tree) {
3614         tree.body = translate(tree.body);
3615         tree.cond = translate(tree.cond, syms.booleanType);
3616         result = tree;
3617     }
3618 
3619     public void visitWhileLoop(JCWhileLoop tree) {
3620         tree.cond = translate(tree.cond, syms.booleanType);
3621         tree.body = translate(tree.body);
3622         result = tree;
3623     }
3624 

















3625     public void visitForLoop(JCForLoop tree) {
3626         tree.init = translate(tree.init);
3627         if (tree.cond != null)
3628             tree.cond = translate(tree.cond, syms.booleanType);
3629         tree.step = translate(tree.step);
3630         tree.body = translate(tree.body);
3631         result = tree;
3632     }
3633 
3634     public void visitReturn(JCReturn tree) {
3635         if (tree.expr != null)
3636             tree.expr = translate(tree.expr,
3637                                   types.erasure(currentMethodDef
3638                                                 .restype.type));
3639         result = tree;
3640     }
3641 
3642     public void visitSwitch(JCSwitch tree) {
3643         List<JCCase> cases = tree.patternSwitch ? addDefaultIfNeeded(tree.patternSwitch,
3644                                                                      tree.wasEnumSelector,

4098         tree.value = translate(tree.value, tree.target.type);
4099         result = tree;
4100     }
4101 
4102     public void visitNewArray(JCNewArray tree) {
4103         tree.elemtype = translate(tree.elemtype);
4104         for (List<JCExpression> t = tree.dims; t.tail != null; t = t.tail)
4105             if (t.head != null) t.head = translate(t.head, syms.intType);
4106         tree.elems = translate(tree.elems, types.elemtype(tree.type));
4107         result = tree;
4108     }
4109 
4110     public void visitSelect(JCFieldAccess tree) {
4111         // need to special case-access of the form C.super.x
4112         // these will always need an access method, unless C
4113         // is a default interface subclassed by the current class.
4114         boolean qualifiedSuperAccess =
4115             tree.selected.hasTag(SELECT) &&
4116             TreeInfo.name(tree.selected) == names._super &&
4117             !types.isDirectSuperInterface(((JCFieldAccess)tree.selected).selected.type.tsym, currentClass);





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



4119         if (tree.name == names._class) {
4120             result = classOf(tree.selected);
4121         }
4122         else if (tree.name == names._super &&
4123                 types.isDirectSuperInterface(tree.selected.type.tsym, currentClass)) {
4124             //default super call!! Not a classic qualified super call
4125             TypeSymbol supSym = tree.selected.type.tsym;
4126             Assert.checkNonNull(types.asSuper(currentClass.type, supSym));
4127             result = tree;
4128         }
4129         else if (tree.name == names._this || tree.name == names._super) {
4130             result = makeThis(tree.pos(), tree.selected.type.tsym);
4131         }
4132         else
4133             result = access(tree.sym, tree, enclOp, qualifiedSuperAccess);
4134     }
4135 
4136     public void visitLetExpr(LetExpr tree) {
4137         tree.defs = translate(tree.defs);
4138         tree.expr = translate(tree.expr, tree.type);
4139         result = tree;
4140     }
4141 
4142     // There ought to be nothing to rewrite here;
4143     // we don't generate code.
4144     public void visitAnnotation(JCAnnotation tree) {
4145         result = tree;
4146     }

  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     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;

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

1045 
1046     /** The qualifier to be used for accessing a symbol in an outer class.
1047      *  This is either C.sym or C.this.sym, depending on whether or not
1048      *  sym is static.
1049      *  @param sym   The accessed symbol.
1050      */
1051     JCExpression accessBase(DiagnosticPosition pos, Symbol sym) {
1052         return (sym.flags() & STATIC) != 0
1053             ? access(make.at(pos.getStartPosition()).QualIdent(sym.owner))
1054             : makeOwnerThis(pos, sym, true);
1055     }
1056 
1057     /** Do we need an access method to reference private symbol?
1058      */
1059     boolean needsPrivateAccess(Symbol sym) {
1060         if (target.hasNestmateAccess()) {
1061             return false;
1062         }
1063         if ((sym.flags() & PRIVATE) == 0 || sym.owner == currentClass) {
1064             return false;
1065         } else if (names.isInitOrVNew(sym.name) && sym.owner.isDirectlyOrIndirectlyLocal()) {
1066             // private constructor in local class: relax protection
1067             sym.flags_field &= ~PRIVATE;
1068             return false;
1069         } else {
1070             return true;
1071         }
1072     }
1073 
1074     /** Do we need an access method to reference symbol in other package?
1075      */
1076     boolean needsProtectedAccess(Symbol sym, JCTree tree) {
1077         if (disableProtectedAccessors) return false;
1078         if ((sym.flags() & PROTECTED) == 0 ||
1079             sym.owner.owner == currentClass.owner || // fast special case
1080             sym.packge() == currentClass.packge())
1081             return false;
1082         if (!currentClass.isSubClass(sym.owner, types))
1083             return true;
1084         if ((sym.flags() & STATIC) != 0 ||
1085             !tree.hasTag(SELECT) ||

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

1258     JCExpression access(JCExpression tree) {
1259         Symbol sym = TreeInfo.symbol(tree);
1260         return sym == null ? tree : access(sym, tree, null, false);
1261     }
1262 
1263     /** Return access constructor for a private constructor,
1264      *  or the constructor itself, if no access constructor is needed.
1265      *  @param pos       The position to report diagnostics, if any.
1266      *  @param constr    The private constructor.
1267      */
1268     Symbol accessConstructor(DiagnosticPosition pos, Symbol constr) {
1269         if (needsPrivateAccess(constr)) {
1270             ClassSymbol accOwner = constr.owner.enclClass();
1271             MethodSymbol aconstr = accessConstrs.get(constr);
1272             if (aconstr == null) {
1273                 List<Type> argtypes = constr.type.getParameterTypes();
1274                 if ((accOwner.flags_field & ENUM) != 0)
1275                     argtypes = argtypes
1276                         .prepend(syms.intType)
1277                         .prepend(syms.stringType);
1278                 Name constructorName = accOwner.isConcreteValueClass() ? names.vnew : names.init;
1279                 aconstr = new MethodSymbol(
1280                     SYNTHETIC,
1281                     constructorName,
1282                     new MethodType(
1283                         argtypes.append(
1284                             accessConstructorTag().erasure(types)),
1285                         constr.type.getReturnType(),
1286                         constr.type.getThrownTypes(),
1287                         syms.methodClass),
1288                     accOwner);
1289                 enterSynthetic(pos, aconstr, accOwner.members());
1290                 accessConstrs.put(constr, aconstr);
1291                 accessed.append(constr);
1292             }
1293             return aconstr;
1294         } else {
1295             return constr;
1296         }
1297     }
1298 
1299     /** Return an anonymous class nested in this toplevel class.
1300      */
1301     ClassSymbol accessConstructorTag() {
1302         ClassSymbol topClass = currentClass.outermostClass();
1303         ModuleSymbol topModle = topClass.packge().modle;
1304         for (int i = 1; ; i++) {
1305             Name flatname = names.fromString("" + topClass.getQualifiedName() +
1306                                             target.syntheticNameChar() +
1307                                             i);
1308             ClassSymbol ctag = chk.getCompiled(topModle, flatname);
1309             if (ctag == null)
1310                 ctag = makeEmptyClass(STATIC | SYNTHETIC | IDENTITY_TYPE, topClass).sym;
1311             else if (!ctag.isAnonymous())
1312                 continue;
1313             // keep a record of all tags, to verify that all are generated as required
1314             accessConstrTags = accessConstrTags.prepend(ctag);
1315             return ctag;
1316         }
1317     }
1318 
1319     /** Add all required access methods for a private symbol to enclosing class.
1320      *  @param sym       The symbol.
1321      */
1322     void makeAccessible(Symbol sym) {
1323         JCClassDecl cdef = classDef(sym.owner.enclClass());
1324         if (cdef == null) Assert.error("class def not found: " + sym + " in " + sym.owner);
1325         if (names.isInitOrVNew(sym.name)) {
1326             cdef.defs = cdef.defs.prepend(
1327                 accessConstructorDef(cdef.pos, sym, accessConstrs.get(sym)));
1328         } else {
1329             MethodSymbol[] accessors = accessSyms.get(sym);
1330             for (int i = 0; i < AccessCode.numberOfAccessCodes; i++) {
1331                 if (accessors[i] != null)
1332                     cdef.defs = cdef.defs.prepend(
1333                         accessDef(cdef.pos, sym, accessors[i], i));
1334             }
1335         }
1336     }
1337 
1338     /** Construct definition of an access method.
1339      *  @param pos        The source code position of the definition.
1340      *  @param vsym       The private or protected symbol.
1341      *  @param accessor   The access method for the symbol.
1342      *  @param acode      The access code.
1343      */
1344     JCTree accessDef(int pos, Symbol vsym, MethodSymbol accessor, int acode) {
1345 //      System.err.println("access " + vsym + " with " + accessor);//DEBUG

1518         VarSymbol outerThis =
1519             new VarSymbol(flags | NOOUTERTHIS, outerThisName(target, owner), target, owner);
1520         outerThisStack = outerThisStack.prepend(outerThis);
1521         return outerThis;
1522     }
1523 
1524     private JCVariableDecl makeOuterThisVarDecl(int pos, VarSymbol sym) {
1525         JCVariableDecl vd = make.at(pos).VarDef(sym, null);
1526         vd.vartype = access(vd.vartype);
1527         return vd;
1528     }
1529 
1530     /** Definition for this$n field.
1531      *  @param pos        The source code position of the definition.
1532      *  @param owner      The method in which the definition goes.
1533      */
1534     JCVariableDecl outerThisDef(int pos, MethodSymbol owner) {
1535         ClassSymbol c = owner.enclClass();
1536         boolean isMandated =
1537             // Anonymous constructors
1538             (owner.isInitOrVNew() && owner.isAnonymous()) ||
1539             // Constructors of non-private inner member classes
1540             (owner.isInitOrVNew() && c.isInner() &&
1541              !c.isPrivate() && !c.isStatic());
1542         long flags =
1543             FINAL | (isMandated ? MANDATED : SYNTHETIC) | PARAMETER;
1544         VarSymbol outerThis = makeOuterThisVarSymbol(owner, flags);
1545         owner.extraParams = owner.extraParams.prepend(outerThis);
1546         return makeOuterThisVarDecl(pos, outerThis);
1547     }
1548 
1549     /** Definition for this$n field.
1550      *  @param pos        The source code position of the definition.
1551      *  @param owner      The class in which the definition goes.
1552      */
1553     JCVariableDecl outerThisDef(int pos, ClassSymbol owner) {
1554         VarSymbol outerThis = makeOuterThisVarSymbol(owner, FINAL | SYNTHETIC);
1555         return makeOuterThisVarDecl(pos, outerThis);
1556     }
1557 
1558     /** Return a list of trees that load the free variables in given list,
1559      *  in reverse order.
1560      *  @param pos          The source code position to be used for the trees.

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

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

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

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

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

2651 
2652         MethodType indyType = msym.type.asMethodType();
2653         indyType = new MethodType(
2654                 isStatic ? List.nil() : indyType.argtypes.prepend(tree.sym.type),
2655                 indyType.restype,
2656                 indyType.thrown,
2657                 syms.methodClass
2658         );
2659         DynamicMethodSymbol dynSym = new DynamicMethodSymbol(argName,
2660                 syms.noSymbol,
2661                 bsm.asHandle(),
2662                 indyType,
2663                 staticArgValues);
2664         JCFieldAccess qualifier = make.Select(make.QualIdent(site.tsym), argName);
2665         qualifier.sym = dynSym;
2666         qualifier.type = msym.type.asMethodType().restype;
2667         return qualifier;
2668     }
2669 
2670     public void visitMethodDef(JCMethodDecl tree) {
2671         // TODO - enum so is always <init>
2672         if (tree.name == names.init && (currentClass.flags_field&ENUM) != 0) {
2673             // Add "String $enum$name, int $enum$ordinal" to the beginning of the
2674             // argument list for each constructor of an enum.
2675             JCVariableDecl nameParam = make_at(tree.pos()).
2676                 Param(names.fromString(target.syntheticNameChar() +
2677                                        "enum" + target.syntheticNameChar() + "name"),
2678                       syms.stringType, tree.sym);
2679             nameParam.mods.flags |= SYNTHETIC; nameParam.sym.flags_field |= SYNTHETIC;
2680             JCVariableDecl ordParam = make.
2681                 Param(names.fromString(target.syntheticNameChar() +
2682                                        "enum" + target.syntheticNameChar() +
2683                                        "ordinal"),
2684                       syms.intType, tree.sym);
2685             ordParam.mods.flags |= SYNTHETIC; ordParam.sym.flags_field |= SYNTHETIC;
2686 
2687             MethodSymbol m = tree.sym;
2688             tree.params = tree.params.prepend(ordParam).prepend(nameParam);
2689 
2690             m.extraParams = m.extraParams.prepend(ordParam.sym);
2691             m.extraParams = m.extraParams.prepend(nameParam.sym);

2693             m.erasure_field = new MethodType(
2694                 olderasure.getParameterTypes().prepend(syms.intType).prepend(syms.stringType),
2695                 olderasure.getReturnType(),
2696                 olderasure.getThrownTypes(),
2697                 syms.methodClass);
2698         }
2699 
2700         JCMethodDecl prevMethodDef = currentMethodDef;
2701         MethodSymbol prevMethodSym = currentMethodSym;
2702         try {
2703             currentMethodDef = tree;
2704             currentMethodSym = tree.sym;
2705             visitMethodDefInternal(tree);
2706         } finally {
2707             currentMethodDef = prevMethodDef;
2708             currentMethodSym = prevMethodSym;
2709         }
2710     }
2711 
2712     private void visitMethodDefInternal(JCMethodDecl tree) {
2713         if (names.isInitOrVNew(tree.name) &&
2714             !currentClass.isStatic() &&
2715             (currentClass.isInner() || currentClass.isDirectlyOrIndirectlyLocal())) {
2716             // We are seeing a constructor of an inner class.
2717             MethodSymbol m = tree.sym;
2718 
2719             // Push a new proxy scope for constructor parameters.
2720             // and create definitions for any this$n and proxy parameters.
2721             Map<Symbol, Symbol> prevProxies = proxies;
2722             proxies = new HashMap<>(proxies);
2723             List<VarSymbol> prevOuterThisStack = outerThisStack;
2724             List<VarSymbol> fvs = freevars(currentClass);
2725             JCVariableDecl otdef = null;
2726             if (currentClass.hasOuterInstance())
2727                 otdef = outerThisDef(tree.pos, m);
2728             List<JCVariableDecl> fvdefs = freevarDefs(tree.pos, fvs, m, PARAMETER);
2729 
2730             // Recursively translate result type, parameters and thrown list.
2731             tree.restype = translate(tree.restype);
2732             tree.params = translateVarDefs(tree.params);
2733             tree.thrown = translate(tree.thrown);

2774             // pop local variables from proxy stack
2775             proxies = prevProxies;
2776 
2777             // recursively translate following local statements and
2778             // combine with this- or super-call
2779             List<JCStatement> stats = translate(tree.body.stats.tail);
2780             tree.body.stats = stats.prepend(selfCall).prependList(added);
2781             outerThisStack = prevOuterThisStack;
2782         } else {
2783             Map<Symbol, Symbol> prevLambdaTranslationMap =
2784                     lambdaTranslationMap;
2785             try {
2786                 lambdaTranslationMap = (tree.sym.flags() & SYNTHETIC) != 0 &&
2787                         tree.sym.name.startsWith(names.lambda) ?
2788                         makeTranslationMap(tree) : null;
2789                 super.visitMethodDef(tree);
2790             } finally {
2791                 lambdaTranslationMap = prevLambdaTranslationMap;
2792             }
2793         }
2794         if (names.isInitOrVNew(tree.name) && ((tree.sym.flags_field & Flags.COMPACT_RECORD_CONSTRUCTOR) != 0 ||
2795                 (tree.sym.flags_field & (GENERATEDCONSTR | RECORD)) == (GENERATEDCONSTR | RECORD))) {
2796             // lets find out if there is any field waiting to be initialized
2797             ListBuffer<VarSymbol> fields = new ListBuffer<>();
2798             for (Symbol sym : currentClass.getEnclosedElements()) {
2799                 if (sym.kind == Kinds.Kind.VAR && ((sym.flags() & RECORD) != 0))
2800                     fields.append((VarSymbol) sym);
2801             }
2802             for (VarSymbol field: fields) {
2803                 if ((field.flags_field & Flags.UNINITIALIZED_FIELD) != 0) {
2804                     VarSymbol param = tree.params.stream().filter(p -> p.name == field.name).findFirst().get().sym;
2805                     make.at(tree.pos);
2806                     tree.body.stats = tree.body.stats.append(
2807                             make.Exec(
2808                                     make.Assign(
2809                                             make.Select(make.This(field.owner.erasure(types)), field),
2810                                             make.Ident(param)).setType(field.erasure(types))));
2811                     // we don't need the flag at the field anymore
2812                     field.flags_field &= ~Flags.UNINITIALIZED_FIELD;
2813                 }
2814             }

3016                 List.nil() : List.of(translate(tree.detail));
3017             if (!tree.cond.type.isFalse()) {
3018                 cond = makeBinary
3019                     (AND,
3020                      cond,
3021                      makeUnary(NOT, tree.cond));
3022             }
3023             result =
3024                 make.If(cond,
3025                         make_at(tree).
3026                            Throw(makeNewClass(syms.assertionErrorType, exnArgs)),
3027                         null);
3028         } else {
3029             result = make.Skip();
3030         }
3031     }
3032 
3033     public void visitApply(JCMethodInvocation tree) {
3034         Symbol meth = TreeInfo.symbol(tree.meth);
3035         List<Type> argtypes = meth.type.getParameterTypes();
3036         // TODO - is enum so always <init>.
3037         if (names.isInitOrVNew(meth.name) && meth.owner == syms.enumSym)
3038             argtypes = argtypes.tail.tail;
3039         tree.args = boxArgs(argtypes, tree.args, tree.varargsElement);
3040         tree.varargsElement = null;
3041         Name methName = TreeInfo.name(tree.meth);
3042         if (names.isInitOrVNew(meth.name)) {
3043             // We are seeing a this(...) or super(...) constructor call.
3044             // If an access constructor is used, append null as a last argument.
3045             Symbol constructor = accessConstructor(tree.pos(), meth);
3046             if (constructor != meth) {
3047                 tree.args = tree.args.append(makeNull());
3048                 TreeInfo.setSymbol(tree.meth, constructor);
3049             }
3050 
3051             // If we are calling a constructor of a local class, add
3052             // free variables after explicit constructor arguments.
3053             ClassSymbol c = (ClassSymbol)constructor.owner;
3054             if (c.isDirectlyOrIndirectlyLocal() && !c.isStatic()) {
3055                 tree.args = tree.args.appendList(loadFreevars(tree.pos(), freevars(c)));
3056             }
3057 
3058             // If we are calling a constructor of an enum class, pass
3059             // along the name and ordinal arguments
3060             if ((c.flags_field&ENUM) != 0 || c.getQualifiedName() == names.java_lang_Enum) {
3061                 List<JCVariableDecl> params = currentMethodDef.params;
3062                 if (currentMethodSym.owner.hasOuterInstance())

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

3538          * A statement of the form
3539          *
3540          * <pre>
3541          *     for ( T v : coll ) stmt ;
3542          * </pre>
3543          *
3544          * (where coll implements {@code Iterable<? extends T>}) gets translated to
3545          *
3546          * <pre>{@code
3547          *     for ( Iterator<? extends T> #i = coll.iterator(); #i.hasNext(); ) {
3548          *         T v = (T) #i.next();
3549          *         stmt;
3550          *     }
3551          * }</pre>
3552          *
3553          * where #i is a freshly named synthetic local variable.
3554          */
3555         private void visitIterableForeachLoop(JCEnhancedForLoop tree) {
3556             make_at(tree.expr.pos());
3557             Type iteratorTarget = syms.objectType;
3558             Type iterableType = types.asSuper(types.cvarUpperBound(tree.expr.type.referenceProjectionOrSelf()),
3559                                               syms.iterableType.tsym);
3560             if (iterableType.getTypeArguments().nonEmpty())
3561                 iteratorTarget = types.erasure(iterableType.getTypeArguments().head);
3562             tree.expr.type = types.erasure(types.skipTypeVars(tree.expr.type, false));
3563             tree.expr = transTypes.coerce(attrEnv, tree.expr, types.erasure(iterableType));
3564             Symbol iterator = lookupMethod(tree.expr.pos(),
3565                                            names.iterator,
3566                                            tree.expr.type,
3567                                            List.nil());
3568             Assert.check(types.isSameType(types.erasure(types.asSuper(iterator.type.getReturnType().referenceProjectionOrSelf(), syms.iteratorType.tsym)), types.erasure(syms.iteratorType)));
3569             VarSymbol itvar = new VarSymbol(SYNTHETIC, names.fromString("i" + target.syntheticNameChar()),
3570                                             types.erasure(syms.iteratorType),
3571                                             currentMethodSym);
3572 
3573              JCStatement init = make.
3574                 VarDef(itvar, make.App(make.Select(tree.expr, iterator)
3575                      .setType(types.erasure(iterator.type))));
3576 
3577             Symbol hasNext = lookupMethod(tree.expr.pos(),
3578                                           names.hasNext,
3579                                           itvar.type,
3580                                           List.nil());
3581             JCMethodInvocation cond = make.App(make.Select(make.Ident(itvar), hasNext));
3582             Symbol next = lookupMethod(tree.expr.pos(),
3583                                        names.next,
3584                                        itvar.type,
3585                                        List.nil());
3586             JCExpression vardefinit = make.App(make.Select(make.Ident(itvar), next));
3587 
3588             Assert.check(tree.getDeclarationKind() == EnhancedForLoopTree.DeclarationKind.VARIABLE);

3631                 new MethodSymbol(tree.flags | BLOCK,
3632                                  names.empty, null,
3633                                  currentClass);
3634         }
3635         super.visitBlock(tree);
3636         currentMethodSym = oldMethodSym;
3637     }
3638 
3639     public void visitDoLoop(JCDoWhileLoop tree) {
3640         tree.body = translate(tree.body);
3641         tree.cond = translate(tree.cond, syms.booleanType);
3642         result = tree;
3643     }
3644 
3645     public void visitWhileLoop(JCWhileLoop tree) {
3646         tree.cond = translate(tree.cond, syms.booleanType);
3647         tree.body = translate(tree.body);
3648         result = tree;
3649     }
3650 
3651     public void visitWithField(JCWithField tree) {
3652         Type fieldType = tree.field.type;
3653         tree.field = translate(tree.field, tree);
3654         tree.value = translate(tree.value, fieldType); // important to use pre-translation type.
3655 
3656         // If translated field is an Apply, we are
3657         // seeing an access method invocation. In this case, append
3658         // right hand side as last argument of the access method.
3659         if (tree.field.hasTag(APPLY)) {
3660             JCMethodInvocation app = (JCMethodInvocation) tree.field;
3661             app.args = List.of(tree.value).prependList(app.args);
3662             result = app;
3663         } else {
3664             result = tree;
3665         }
3666     }
3667 
3668     public void visitForLoop(JCForLoop tree) {
3669         tree.init = translate(tree.init);
3670         if (tree.cond != null)
3671             tree.cond = translate(tree.cond, syms.booleanType);
3672         tree.step = translate(tree.step);
3673         tree.body = translate(tree.body);
3674         result = tree;
3675     }
3676 
3677     public void visitReturn(JCReturn tree) {
3678         if (tree.expr != null)
3679             tree.expr = translate(tree.expr,
3680                                   types.erasure(currentMethodDef
3681                                                 .restype.type));
3682         result = tree;
3683     }
3684 
3685     public void visitSwitch(JCSwitch tree) {
3686         List<JCCase> cases = tree.patternSwitch ? addDefaultIfNeeded(tree.patternSwitch,
3687                                                                      tree.wasEnumSelector,

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