< prev index next >

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

Print this page

 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 =

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, 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 (sym.name == names.init) {
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++) {

1842         if (ots.isEmpty()) {
1843             log.error(pos, Errors.NoEnclInstanceOfTypeInScope(c));
1844             Assert.error();
1845             return makeNull();
1846         }
1847         VarSymbol ot = ots.head;
1848         JCExpression tree = access(make.at(pos).Ident(ot));
1849         ot.flags_field &= ~NOOUTERTHIS;
1850         TypeSymbol otc = ot.type.tsym;
1851         while (otc != c) {
1852             do {
1853                 ots = ots.tail;
1854                 if (ots.isEmpty()) {
1855                     log.error(pos, Errors.NoEnclInstanceOfTypeInScope(c));
1856                     Assert.error(); // should have been caught in Attr
1857                     return tree;
1858                 }
1859                 ot = ots.head;
1860             } while (ot.owner != otc);
1861             if (otc.owner.kind != PCK && !otc.hasOuterInstance()) {
1862                 chk.earlyRefError(pos, c);
1863                 Assert.error(); // should have been caught in Attr
1864                 return makeNull();
1865             }
1866             tree = access(make.at(pos).Select(tree, ot));
1867             ot.flags_field &= ~NOOUTERTHIS;
1868             otc = ot.type.tsym;
1869         }
1870         return tree;
1871     }
1872 
1873     /** Construct a tree that represents the closest outer instance
1874      *  {@code C.this} such that the given symbol is a member of C.
1875      *  @param pos           The source code position to be used for the tree.
1876      *  @param sym           The accessed symbol.
1877      *  @param preciseMatch  should we accept a type that is a subtype of
1878      *                       sym's owner, even if it doesn't contain sym
1879      *                       due to hiding, overriding, or non-inheritance
1880      *                       due to protection?
1881      */
1882     JCExpression makeOwnerThis(DiagnosticPosition pos, Symbol sym, boolean preciseMatch) {
1883         Symbol c = sym.owner;
1884         if (preciseMatch ? sym.isMemberOf(currentClass, types)
1885                          : currentClass.isSubClass(sym.owner, types)) {
1886             // in this case, `this' works fine
1887             return make.at(pos).This(c.erasure(types));
1888         } else {
1889             // need to go via this$n
1890             return makeOwnerThisN(pos, sym, preciseMatch);
1891         }
1892     }
1893 
1894     /**
1895      * Similar to makeOwnerThis but will never pick "this".
1896      */
1897     JCExpression makeOwnerThisN(DiagnosticPosition pos, Symbol sym, boolean preciseMatch) {
1898         Symbol c = sym.owner;
1899         List<VarSymbol> ots = outerThisStack;
1900         if (ots.isEmpty()) {
1901             log.error(pos, Errors.NoEnclInstanceOfTypeInScope(c));
1902             Assert.error();
1903             return makeNull();
1904         }
1905         VarSymbol ot = ots.head;
1906         JCExpression tree = access(make.at(pos).Ident(ot));
1907         ot.flags_field &= ~NOOUTERTHIS;
1908         TypeSymbol otc = ot.type.tsym;
1909         while (!(preciseMatch ? sym.isMemberOf(otc, types) : otc.isSubClass(sym.owner, types))) {
1910             do {
1911                 ots = ots.tail;
1912                 if (ots.isEmpty()) {
1913                     log.error(pos, Errors.NoEnclInstanceOfTypeInScope(c));
1914                     Assert.error();
1915                     return tree;
1916                 }
1917                 ot = ots.head;
1918             } while (ot.owner != otc);
1919             tree = access(make.at(pos).Select(tree, ot));
1920             ot.flags_field &= ~NOOUTERTHIS;
1921             otc = ot.type.tsym;
1922         }
1923         return tree;
1924     }
1925 
1926     /** Return tree simulating the assignment {@code this.name = name}, where
1927      *  name is the name of a free variable.
1928      */
1929     JCStatement initField(int pos, Symbol rhs, Symbol lhs) {
1930         Assert.check(rhs.owner.kind == MTH);
1931         Assert.check(rhs.owner.owner == lhs.owner);
1932         make.at(pos);
1933         return
1934             make.Exec(

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

2334                 if (outermostMemberDefPrev == null) outermostMemberDef = l.head;
2335                 l.head = translate(l.head);
2336                 outermostMemberDef = outermostMemberDefPrev;
2337             }
2338             seen = unseen;
2339         }
2340 
2341         // Convert a protected modifier to public, mask static modifier.
2342         if ((tree.mods.flags & PROTECTED) != 0) tree.mods.flags |= PUBLIC;
2343         tree.mods.flags &= ClassFlags;
2344 
2345         // Convert name to flat representation, replacing '.' by '$'.
2346         tree.name = Convert.shortName(currentClass.flatName());
2347 
2348         // Add free variables proxy definitions to class.
2349 
2350         for (List<JCVariableDecl> l = fvdefs; l.nonEmpty(); l = l.tail) {
2351             tree.defs = tree.defs.prepend(l.head);
2352             enterSynthetic(tree.pos(), l.head.sym, currentClass.members());
2353         }
2354         // If this$n was accessed, add the field definition and
2355         // update initial constructors to initialize it
2356         if (currentClass.hasOuterInstance() && shouldEmitOuterThis(currentClass)) {
2357             tree.defs = tree.defs.prepend(otdef);
2358             enterSynthetic(tree.pos(), otdef.sym, currentClass.members());
2359 
2360            for (JCTree def : tree.defs) {
2361                 if (TreeInfo.isInitialConstructor(def)) {
2362                   JCMethodDecl mdef = (JCMethodDecl) def;
2363                   mdef.body.stats = mdef.body.stats.prepend(
2364                       initOuterThis(mdef.body.pos, mdef.params.head.sym));


2365                 }
2366             }
2367         }
2368 
2369         proxies = prevProxies;
2370         outerThisStack = prevOuterThisStack;
2371 
2372         // Append translated tree to `translated' queue.
2373         translated.append(tree);
2374 
2375         attrEnv = prevEnv;
2376         currentClass = currentClassPrev;
2377         currentMethodSym = currentMethodSymPrev;
2378 
2379         // Return empty block {} as a placeholder for an inner class.
2380         result = make_at(tree.pos()).Block(SYNTHETIC, List.nil());
2381     }
2382 
2383     private boolean shouldEmitOuterThis(ClassSymbol sym) {
2384       if (!optimizeOuterThis) {

2809             List<JCVariableDecl> fvdefs = freevarDefs(tree.pos, fvs, m, PARAMETER);
2810 
2811             // Recursively translate result type, parameters and thrown list.
2812             tree.restype = translate(tree.restype);
2813             tree.params = translateVarDefs(tree.params);
2814             tree.thrown = translate(tree.thrown);
2815 
2816             // when compiling stubs, don't process body
2817             if (tree.body == null) {
2818                 result = tree;
2819                 return;
2820             }
2821 
2822             // Add this$n (if needed) in front of and free variables behind
2823             // constructor parameter list.
2824             tree.params = tree.params.appendList(fvdefs);
2825             if (currentClass.hasOuterInstance()) {
2826                 tree.params = tree.params.prepend(otdef);
2827             }
2828 
2829             // If this is an initial constructor, i.e., it does not start with
2830             // this(...), insert initializers for this$n and proxies
2831             // before (pre-1.4, after) the call to superclass constructor.
2832             JCStatement selfCall = translate(tree.body.stats.head);
2833 
2834             List<JCStatement> added = List.nil();

2835             if (fvs.nonEmpty()) {
2836                 List<Type> addedargtypes = List.nil();
2837                 for (List<VarSymbol> l = fvs; l.nonEmpty(); l = l.tail) {
2838                     m.capturedLocals =
2839                         m.capturedLocals.prepend((VarSymbol)
2840                                                 (proxies.get(l.head)));
2841                     if (TreeInfo.isInitialConstructor(tree)) {
2842                         added = added.prepend(
2843                           initField(tree.body.pos, proxies.get(l.head), prevProxies.get(l.head)));
2844                     }
2845                     addedargtypes = addedargtypes.prepend(l.head.erasure(types));
2846                 }
2847                 Type olderasure = m.erasure(types);
2848                 m.erasure_field = new MethodType(
2849                     olderasure.getParameterTypes().appendList(addedargtypes),
2850                     olderasure.getReturnType(),
2851                     olderasure.getThrownTypes(),
2852                     syms.methodClass);
2853             }
2854 









2855             // pop local variables from proxy stack
2856             proxies = prevProxies;
2857 
2858             // recursively translate following local statements and
2859             // combine with this- or super-call
2860             List<JCStatement> stats = translate(tree.body.stats.tail);
2861             tree.body.stats = stats.prepend(selfCall).prependList(added);
2862             outerThisStack = prevOuterThisStack;
2863         } else {
2864             Map<Symbol, Symbol> prevLambdaTranslationMap =
2865                     lambdaTranslationMap;
2866             try {
2867                 lambdaTranslationMap = (tree.sym.flags() & SYNTHETIC) != 0 &&
2868                         tree.sym.name.startsWith(names.lambda) ?
2869                         makeTranslationMap(tree) : null;
2870                 super.visitMethodDef(tree);
2871             } finally {
2872                 lambdaTranslationMap = prevLambdaTranslationMap;
2873             }
2874         }
2875         if (tree.name == names.init && ((tree.sym.flags_field & Flags.COMPACT_RECORD_CONSTRUCTOR) != 0 ||
2876                 (tree.sym.flags_field & (GENERATEDCONSTR | RECORD)) == (GENERATEDCONSTR | RECORD))) {
2877             // lets find out if there is any field waiting to be initialized
2878             ListBuffer<VarSymbol> fields = new ListBuffer<>();
2879             for (Symbol sym : currentClass.getEnclosedElements()) {
2880                 if (sym.kind == Kinds.Kind.VAR && ((sym.flags() & RECORD) != 0))
2881                     fields.append((VarSymbol) sym);

 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 | IDENTITY_TYPE,
 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 =

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 (sym.name == names.init) {
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++) {

1842         if (ots.isEmpty()) {
1843             log.error(pos, Errors.NoEnclInstanceOfTypeInScope(c));
1844             Assert.error();
1845             return makeNull();
1846         }
1847         VarSymbol ot = ots.head;
1848         JCExpression tree = access(make.at(pos).Ident(ot));
1849         ot.flags_field &= ~NOOUTERTHIS;
1850         TypeSymbol otc = ot.type.tsym;
1851         while (otc != c) {
1852             do {
1853                 ots = ots.tail;
1854                 if (ots.isEmpty()) {
1855                     log.error(pos, Errors.NoEnclInstanceOfTypeInScope(c));
1856                     Assert.error(); // should have been caught in Attr
1857                     return tree;
1858                 }
1859                 ot = ots.head;
1860             } while (ot.owner != otc);
1861             if (otc.owner.kind != PCK && !otc.hasOuterInstance()) {
1862                 log.error(pos, Errors.NoEnclInstanceOfTypeInScope(c));
1863                 Assert.error(); // should have been caught in Attr
1864                 return makeNull();
1865             }
1866             tree = access(make.at(pos).Select(tree, ot));
1867             ot.flags_field &= ~NOOUTERTHIS;
1868             otc = ot.type.tsym;
1869         }
1870         return tree;
1871     }
1872 
1873     /** Construct a tree that represents the closest outer instance
1874      *  {@code C.this} such that the given symbol is a member of C.
1875      *  @param pos           The source code position to be used for the tree.
1876      *  @param sym           The accessed symbol.
1877      *  @param preciseMatch  should we accept a type that is a subtype of
1878      *                       sym's owner, even if it doesn't contain sym
1879      *                       due to hiding, overriding, or non-inheritance
1880      *                       due to protection?
1881      */
1882     JCExpression makeOwnerThis(DiagnosticPosition pos, Symbol sym, boolean preciseMatch) {
1883         Symbol c = sym.owner;
1884         if (preciseMatch ? sym.isMemberOf(currentClass, types)
1885                          : currentClass.isSubClass(sym.owner, types)) {
1886             // in this case, `this' works fine
1887             return make.at(pos).This(c.erasure(types));
1888         } else {
1889             // need to go via this$n
1890             return makeOwnerThisN(pos, sym, preciseMatch);
1891         }
1892     }
1893 
1894     /**
1895      * Similar to makeOwnerThis but will never pick "this".
1896      */
1897     JCExpression makeOwnerThisN(DiagnosticPosition pos, Symbol sym, boolean preciseMatch) {
1898         Symbol c = sym.owner;
1899         List<VarSymbol> ots = outerThisStack;
1900         if (ots.isEmpty()) {
1901             log.error(pos, Errors.NoEnclInstanceOfTypeInScope(c));

1902             return makeNull();
1903         }
1904         VarSymbol ot = ots.head;
1905         JCExpression tree = access(make.at(pos).Ident(ot));
1906         ot.flags_field &= ~NOOUTERTHIS;
1907         TypeSymbol otc = ot.type.tsym;
1908         while (!(preciseMatch ? sym.isMemberOf(otc, types) : otc.isSubClass(sym.owner, types))) {
1909             do {
1910                 ots = ots.tail;
1911                 if (ots.isEmpty()) {
1912                     log.error(pos, Errors.NoEnclInstanceOfTypeInScope(c));

1913                     return tree;
1914                 }
1915                 ot = ots.head;
1916             } while (ot.owner != otc);
1917             tree = access(make.at(pos).Select(tree, ot));
1918             ot.flags_field &= ~NOOUTERTHIS;
1919             otc = ot.type.tsym;
1920         }
1921         return tree;
1922     }
1923 
1924     /** Return tree simulating the assignment {@code this.name = name}, where
1925      *  name is the name of a free variable.
1926      */
1927     JCStatement initField(int pos, Symbol rhs, Symbol lhs) {
1928         Assert.check(rhs.owner.kind == MTH);
1929         Assert.check(rhs.owner.owner == lhs.owner);
1930         make.at(pos);
1931         return
1932             make.Exec(

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

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

2332                 if (outermostMemberDefPrev == null) outermostMemberDef = l.head;
2333                 l.head = translate(l.head);
2334                 outermostMemberDef = outermostMemberDefPrev;
2335             }
2336             seen = unseen;
2337         }
2338 
2339         // Convert a protected modifier to public, mask static modifier.
2340         if ((tree.mods.flags & PROTECTED) != 0) tree.mods.flags |= PUBLIC;
2341         tree.mods.flags &= ClassFlags;
2342 
2343         // Convert name to flat representation, replacing '.' by '$'.
2344         tree.name = Convert.shortName(currentClass.flatName());
2345 
2346         // Add free variables proxy definitions to class.
2347 
2348         for (List<JCVariableDecl> l = fvdefs; l.nonEmpty(); l = l.tail) {
2349             tree.defs = tree.defs.prepend(l.head);
2350             enterSynthetic(tree.pos(), l.head.sym, currentClass.members());
2351         }
2352         // If this$n was accessed, add the field definition and prepend
2353         // initializer code to any super() invocation to initialize it
2354         if (currentClass.hasOuterInstance() && shouldEmitOuterThis(currentClass)) {
2355             tree.defs = tree.defs.prepend(otdef);
2356             enterSynthetic(tree.pos(), otdef.sym, currentClass.members());
2357 
2358             for (JCTree def : tree.defs) {
2359                 if (TreeInfo.isConstructor(def)) {
2360                     JCMethodDecl mdef = (JCMethodDecl)def;
2361                     if (TreeInfo.hasConstructorCall(mdef, names._super)) {
2362                         List<JCStatement> initializer = List.of(initOuterThis(mdef.body.pos, mdef.params.head.sym));
2363                         TreeInfo.mapSuperCalls(mdef.body, supercall -> make.Block(0, initializer.append(supercall)));
2364                     }
2365                 }
2366             }
2367         }
2368 
2369         proxies = prevProxies;
2370         outerThisStack = prevOuterThisStack;
2371 
2372         // Append translated tree to `translated' queue.
2373         translated.append(tree);
2374 
2375         attrEnv = prevEnv;
2376         currentClass = currentClassPrev;
2377         currentMethodSym = currentMethodSymPrev;
2378 
2379         // Return empty block {} as a placeholder for an inner class.
2380         result = make_at(tree.pos()).Block(SYNTHETIC, List.nil());
2381     }
2382 
2383     private boolean shouldEmitOuterThis(ClassSymbol sym) {
2384       if (!optimizeOuterThis) {

2809             List<JCVariableDecl> fvdefs = freevarDefs(tree.pos, fvs, m, PARAMETER);
2810 
2811             // Recursively translate result type, parameters and thrown list.
2812             tree.restype = translate(tree.restype);
2813             tree.params = translateVarDefs(tree.params);
2814             tree.thrown = translate(tree.thrown);
2815 
2816             // when compiling stubs, don't process body
2817             if (tree.body == null) {
2818                 result = tree;
2819                 return;
2820             }
2821 
2822             // Add this$n (if needed) in front of and free variables behind
2823             // constructor parameter list.
2824             tree.params = tree.params.appendList(fvdefs);
2825             if (currentClass.hasOuterInstance()) {
2826                 tree.params = tree.params.prepend(otdef);
2827             }
2828 
2829             // Determine whether this constructor has a super() invocation
2830             boolean invokesSuper = TreeInfo.hasConstructorCall(tree, names._super);


2831 
2832             // Create initializers for this$n and proxies
2833             ListBuffer<JCStatement> added = new ListBuffer<>();
2834             if (fvs.nonEmpty()) {
2835                 List<Type> addedargtypes = List.nil();
2836                 for (List<VarSymbol> l = fvs; l.nonEmpty(); l = l.tail) {
2837                     m.capturedLocals =
2838                         m.capturedLocals.prepend((VarSymbol)
2839                                                 (proxies.get(l.head)));
2840                     if (invokesSuper) {
2841                         added = added.prepend(
2842                           initField(tree.body.pos, proxies.get(l.head), prevProxies.get(l.head)));
2843                     }
2844                     addedargtypes = addedargtypes.prepend(l.head.erasure(types));
2845                 }
2846                 Type olderasure = m.erasure(types);
2847                 m.erasure_field = new MethodType(
2848                     olderasure.getParameterTypes().appendList(addedargtypes),
2849                     olderasure.getReturnType(),
2850                     olderasure.getThrownTypes(),
2851                     syms.methodClass);
2852             }
2853 
2854             // Recursively translate existing local statements
2855             tree.body.stats = translate(tree.body.stats);
2856 
2857             // Prepend initializers in front of super() call
2858             if (added.nonEmpty()) {
2859                 List<JCStatement> initializers = added.toList();
2860                 TreeInfo.mapSuperCalls(tree.body, supercall -> make.Block(0, initializers.append(supercall)));
2861             }
2862 
2863             // pop local variables from proxy stack
2864             proxies = prevProxies;
2865 




2866             outerThisStack = prevOuterThisStack;
2867         } else {
2868             Map<Symbol, Symbol> prevLambdaTranslationMap =
2869                     lambdaTranslationMap;
2870             try {
2871                 lambdaTranslationMap = (tree.sym.flags() & SYNTHETIC) != 0 &&
2872                         tree.sym.name.startsWith(names.lambda) ?
2873                         makeTranslationMap(tree) : null;
2874                 super.visitMethodDef(tree);
2875             } finally {
2876                 lambdaTranslationMap = prevLambdaTranslationMap;
2877             }
2878         }
2879         if (tree.name == names.init && ((tree.sym.flags_field & Flags.COMPACT_RECORD_CONSTRUCTOR) != 0 ||
2880                 (tree.sym.flags_field & (GENERATEDCONSTR | RECORD)) == (GENERATEDCONSTR | RECORD))) {
2881             // lets find out if there is any field waiting to be initialized
2882             ListBuffer<VarSymbol> fields = new ListBuffer<>();
2883             for (Symbol sym : currentClass.getEnclosedElements()) {
2884                 if (sym.kind == Kinds.Kind.VAR && ((sym.flags() & RECORD) != 0))
2885                     fields.append((VarSymbol) sym);
< prev index next >