90 private final Log log;
91 private final Symtab syms;
92 private final Resolve rs;
93 private final Operators operators;
94 private final Check chk;
95 private final Attr attr;
96 private TreeMaker make;
97 private DiagnosticPosition make_pos;
98 private final ConstFold cfolder;
99 private final Target target;
100 private final TypeEnvs typeEnvs;
101 private final Name dollarAssertionsDisabled;
102 private final Types types;
103 private final TransTypes transTypes;
104 private final boolean debugLower;
105 private final boolean disableProtectedAccessors; // experimental
106 private final PkgInfo pkginfoOpt;
107 private final boolean optimizeOuterThis;
108 private final boolean useMatchException;
109 private final HashMap<TypePairs, String> typePairToName;
110 private int variableIndex = 0;
111
112 @SuppressWarnings("this-escape")
113 protected Lower(Context context) {
114 context.put(lowerKey, this);
115 names = Names.instance(context);
116 log = Log.instance(context);
117 syms = Symtab.instance(context);
118 rs = Resolve.instance(context);
119 operators = Operators.instance(context);
120 chk = Check.instance(context);
121 attr = Attr.instance(context);
122 make = TreeMaker.instance(context);
123 cfolder = ConstFold.instance(context);
124 target = Target.instance(context);
125 typeEnvs = TypeEnvs.instance(context);
126 dollarAssertionsDisabled = names.
127 fromString(target.syntheticNameChar() + "assertionsDisabled");
128
129 types = Types.instance(context);
130 transTypes = TransTypes.instance(context);
131 Options options = Options.instance(context);
132 debugLower = options.isSet("debuglower");
133 pkginfoOpt = PkgInfo.get(options);
134 optimizeOuterThis =
135 target.optimizeOuterThis() ||
136 options.getBoolean("optimizeOuterThis", false);
137 disableProtectedAccessors = options.isSet("disableProtectedAccessors");
138 Source source = Source.instance(context);
139 Preview preview = Preview.instance(context);
140 useMatchException = Feature.PATTERN_SWITCH.allowedInSource(source) &&
141 (preview.isEnabled() || !preview.isPreview(Feature.PATTERN_SWITCH));
142 typePairToName = TypePairs.initialize(syms);
143 }
144
145 /** The currently enclosing class.
146 */
147 ClassSymbol currentClass;
148
149 /** A queue of all translated classes.
150 */
151 ListBuffer<JCTree> translated;
152
153 /** Environment for symbol lookup, set by translateTopLevelClass.
154 */
155 Env<AttrContext> attrEnv;
156
157 /** A hash table mapping syntax trees to their ending source positions.
158 */
159 EndPosTable endPosTable;
160
161 /* ************************************************************************
162 * Global mappings
179 * The current expected return type.
180 */
181 Type currentRestype;
182
183 /** The current method definition.
184 */
185 JCMethodDecl currentMethodDef;
186
187 /** The current method symbol.
188 */
189 MethodSymbol currentMethodSym;
190
191 /** The currently enclosing outermost class definition.
192 */
193 JCClassDecl outermostClassDef;
194
195 /** The currently enclosing outermost member definition.
196 */
197 JCTree outermostMemberDef;
198
199 /** A navigator class for assembling a mapping from local class symbols
200 * to class definition trees.
201 * There is only one case; all other cases simply traverse down the tree.
202 */
203 class ClassMap extends TreeScanner {
204
205 /** All encountered class defs are entered into classdefs table.
206 */
207 public void visitClassDef(JCClassDecl tree) {
208 classdefs.put(tree.sym, tree);
209 super.visitClassDef(tree);
210 }
211 }
212 ClassMap classMap = new ClassMap();
213
214 /** Map a class symbol to its definition.
215 * @param c The class symbol of which we want to determine the definition.
216 */
217 JCClassDecl classDef(ClassSymbol c) {
218 // First lookup the class in the classdefs table.
851
852 /** Look up a method in a given scope.
853 */
854 private MethodSymbol lookupMethod(DiagnosticPosition pos, Name name, Type qual, List<Type> args) {
855 return rs.resolveInternalMethod(pos, attrEnv, qual, name, args, List.nil());
856 }
857
858 /** Anon inner classes are used as access constructor tags.
859 * accessConstructorTag will use an existing anon class if one is available,
860 * and synthesize a class (with makeEmptyClass) if one is not available.
861 * However, there is a small possibility that an existing class will not
862 * be generated as expected if it is inside a conditional with a constant
863 * expression. If that is found to be the case, create an empty class tree here.
864 */
865 private void checkAccessConstructorTags() {
866 for (List<ClassSymbol> l = accessConstrTags; l.nonEmpty(); l = l.tail) {
867 ClassSymbol c = l.head;
868 if (isTranslatedClassAvailable(c))
869 continue;
870 // Create class definition tree.
871 JCClassDecl cdec = makeEmptyClass(STATIC | SYNTHETIC,
872 c.outermostClass(), c.flatname, false);
873 swapAccessConstructorTag(c, cdec.sym);
874 translated.append(cdec);
875 }
876 }
877 // where
878 private boolean isTranslatedClassAvailable(ClassSymbol c) {
879 for (JCTree tree: translated) {
880 if (tree.hasTag(CLASSDEF)
881 && ((JCClassDecl) tree).sym == c) {
882 return true;
883 }
884 }
885 return false;
886 }
887
888 void swapAccessConstructorTag(ClassSymbol oldCTag, ClassSymbol newCTag) {
889 for (MethodSymbol methodSymbol : accessConstrs.values()) {
890 Assert.check(methodSymbol.type.hasTag(METHOD));
891 MethodType oldMethodType =
1323 accessConstrs.put(constr, aconstr);
1324 accessed.append(constr);
1325 }
1326 return aconstr;
1327 } else {
1328 return constr;
1329 }
1330 }
1331
1332 /** Return an anonymous class nested in this toplevel class.
1333 */
1334 ClassSymbol accessConstructorTag() {
1335 ClassSymbol topClass = currentClass.outermostClass();
1336 ModuleSymbol topModle = topClass.packge().modle;
1337 for (int i = 1; ; i++) {
1338 Name flatname = names.fromString("" + topClass.getQualifiedName() +
1339 target.syntheticNameChar() +
1340 i);
1341 ClassSymbol ctag = chk.getCompiled(topModle, flatname);
1342 if (ctag == null)
1343 ctag = makeEmptyClass(STATIC | SYNTHETIC, topClass).sym;
1344 else if (!ctag.isAnonymous())
1345 continue;
1346 // keep a record of all tags, to verify that all are generated as required
1347 accessConstrTags = accessConstrTags.prepend(ctag);
1348 return ctag;
1349 }
1350 }
1351
1352 /** Add all required access methods for a private symbol to enclosing class.
1353 * @param sym The symbol.
1354 */
1355 void makeAccessible(Symbol sym) {
1356 JCClassDecl cdef = classDef(sym.owner.enclClass());
1357 if (cdef == null) Assert.error("class def not found: " + sym + " in " + sym.owner);
1358 if (sym.name == names.init) {
1359 cdef.defs = cdef.defs.prepend(
1360 accessConstructorDef(cdef.pos, sym, accessConstrs.get(sym)));
1361 } else {
1362 MethodSymbol[] accessors = accessSyms.get(sym);
1363 for (int i = 0; i < AccessCode.numberOfAccessCodes; i++) {
1479
1480 /** A stack containing the this$n field of the currently translated
1481 * classes (if needed) in innermost first order.
1482 * Inside a constructor, proxies and any this$n symbol are duplicated
1483 * in an additional innermost scope, where they represent the constructor
1484 * parameters.
1485 */
1486 List<VarSymbol> outerThisStack;
1487
1488 /** The name of a free variable proxy.
1489 */
1490 Name proxyName(Name name, int index) {
1491 Name proxyName = names.fromString("val" + target.syntheticNameChar() + name);
1492 if (index > 0) {
1493 proxyName = proxyName.append(names.fromString("" + target.syntheticNameChar() + index));
1494 }
1495 return proxyName;
1496 }
1497
1498 /** Proxy definitions for all free variables in given list, in reverse order.
1499 * @param pos The source code position of the definition.
1500 * @param freevars The free variables.
1501 * @param owner The class in which the definitions go.
1502 */
1503 List<JCVariableDecl> freevarDefs(int pos, List<VarSymbol> freevars, Symbol owner) {
1504 return freevarDefs(pos, freevars, owner, 0);
1505 }
1506
1507 List<JCVariableDecl> freevarDefs(int pos, List<VarSymbol> freevars, Symbol owner,
1508 long additionalFlags) {
1509 long flags = FINAL | SYNTHETIC | additionalFlags;
1510 List<JCVariableDecl> defs = List.nil();
1511 Set<Name> proxyNames = new HashSet<>();
1512 for (List<VarSymbol> l = freevars; l.nonEmpty(); l = l.tail) {
1513 VarSymbol v = l.head;
1514 int index = 0;
1515 Name proxyName;
1516 do {
1517 proxyName = proxyName(v.name, index++);
1518 } while (!proxyNames.add(proxyName));
1519 VarSymbol proxy = new VarSymbol(
1520 flags, proxyName, v.erasure(types), owner);
1521 proxies.put(v, proxy);
1522 JCVariableDecl vd = make.at(pos).VarDef(proxy, null);
1523 vd.vartype = access(vd.vartype);
1524 defs = defs.prepend(vd);
1525 }
1526 return defs;
1567 JCVariableDecl outerThisDef(int pos, MethodSymbol owner) {
1568 ClassSymbol c = owner.enclClass();
1569 boolean isMandated =
1570 // Anonymous constructors
1571 (owner.isConstructor() && owner.isAnonymous()) ||
1572 // Constructors of non-private inner member classes
1573 (owner.isConstructor() && c.isInner() &&
1574 !c.isPrivate() && !c.isStatic());
1575 long flags =
1576 FINAL | (isMandated ? MANDATED : SYNTHETIC) | PARAMETER;
1577 VarSymbol outerThis = makeOuterThisVarSymbol(owner, flags);
1578 owner.extraParams = owner.extraParams.prepend(outerThis);
1579 return makeOuterThisVarDecl(pos, outerThis);
1580 }
1581
1582 /** Definition for this$n field.
1583 * @param pos The source code position of the definition.
1584 * @param owner The class in which the definition goes.
1585 */
1586 JCVariableDecl outerThisDef(int pos, ClassSymbol owner) {
1587 VarSymbol outerThis = makeOuterThisVarSymbol(owner, FINAL | SYNTHETIC);
1588 return makeOuterThisVarDecl(pos, outerThis);
1589 }
1590
1591 /** Return a list of trees that load the free variables in given list,
1592 * in reverse order.
1593 * @param pos The source code position to be used for the trees.
1594 * @param freevars The list of free variables.
1595 */
1596 List<JCExpression> loadFreevars(DiagnosticPosition pos, List<VarSymbol> freevars) {
1597 List<JCExpression> args = List.nil();
1598 for (List<VarSymbol> l = freevars; l.nonEmpty(); l = l.tail)
1599 args = args.prepend(loadFreevar(pos, l.head));
1600 return args;
1601 }
1602 //where
1603 JCExpression loadFreevar(DiagnosticPosition pos, VarSymbol v) {
1604 return access(v, make.at(pos).Ident(v), null, false);
1605 }
1606
1607 /** Construct a tree simulating the expression {@code C.this}.
1898 }
1899
1900 /* ************************************************************************
1901 * Code for .class
1902 *************************************************************************/
1903
1904 /** Return the symbol of a class to contain a cache of
1905 * compiler-generated statics such as class$ and the
1906 * $assertionsDisabled flag. We create an anonymous nested class
1907 * (unless one already exists) and return its symbol. However,
1908 * for backward compatibility in 1.4 and earlier we use the
1909 * top-level class itself.
1910 */
1911 private ClassSymbol outerCacheClass() {
1912 ClassSymbol clazz = outermostClassDef.sym;
1913 Scope s = clazz.members();
1914 for (Symbol sym : s.getSymbols(NON_RECURSIVE))
1915 if (sym.kind == TYP &&
1916 sym.name == names.empty &&
1917 (sym.flags() & INTERFACE) == 0) return (ClassSymbol) sym;
1918 return makeEmptyClass(STATIC | SYNTHETIC, clazz).sym;
1919 }
1920
1921 /** Create an attributed tree of the form left.name(). */
1922 private JCMethodInvocation makeCall(JCExpression left, Name name, List<JCExpression> args) {
1923 Assert.checkNonNull(left.type);
1924 Symbol funcsym = lookupMethod(make_pos, name, left.type,
1925 TreeInfo.types(args));
1926 return make.App(make.Select(left, funcsym), args);
1927 }
1928
1929 /** The tree simulating a T.class expression.
1930 * @param clazz The tree identifying type T.
1931 */
1932 private JCExpression classOf(JCTree clazz) {
1933 return classOfType(clazz.type, clazz.pos());
1934 }
1935
1936 private JCExpression classOfType(Type type, DiagnosticPosition pos) {
1937 switch (type.getTag()) {
1938 case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
1950 VarSymbol sym = new VarSymbol(
1951 STATIC | PUBLIC | FINAL, names._class,
1952 syms.classType, type.tsym);
1953 return make_at(pos).Select(make.Type(type), sym);
1954 default:
1955 throw new AssertionError();
1956 }
1957 }
1958
1959 /* ************************************************************************
1960 * Code for enabling/disabling assertions.
1961 *************************************************************************/
1962
1963 private ClassSymbol assertionsDisabledClassCache;
1964
1965 /**Used to create an auxiliary class to hold $assertionsDisabled for interfaces.
1966 */
1967 private ClassSymbol assertionsDisabledClass() {
1968 if (assertionsDisabledClassCache != null) return assertionsDisabledClassCache;
1969
1970 assertionsDisabledClassCache = makeEmptyClass(STATIC | SYNTHETIC, outermostClassDef.sym).sym;
1971
1972 return assertionsDisabledClassCache;
1973 }
1974
1975 // This code is not particularly robust if the user has
1976 // previously declared a member named '$assertionsDisabled'.
1977 // The same faulty idiom also appears in the translation of
1978 // class literals above. We should report an error if a
1979 // previous declaration is not synthetic.
1980
1981 private JCExpression assertFlagTest(DiagnosticPosition pos) {
1982 // Outermost class may be either true class or an interface.
1983 ClassSymbol outermostClass = outermostClassDef.sym;
1984
1985 //only classes can hold a non-public field, look for a usable one:
1986 ClassSymbol container = !currentClass.isInterface() ? currentClass :
1987 assertionsDisabledClass();
1988
1989 VarSymbol assertDisabledSym =
1990 (VarSymbol)lookupSynthetic(dollarAssertionsDisabled,
2238 proxies = new HashMap<>(proxies);
2239 List<VarSymbol> prevOuterThisStack = outerThisStack;
2240
2241 // If this is an enum definition
2242 if ((tree.mods.flags & ENUM) != 0 &&
2243 (types.supertype(currentClass.type).tsym.flags() & ENUM) == 0)
2244 visitEnumDef(tree);
2245
2246 if ((tree.mods.flags & RECORD) != 0) {
2247 visitRecordDef(tree);
2248 }
2249
2250 // If this is a nested class, define a this$n field for
2251 // it and add to proxies.
2252 JCVariableDecl otdef = null;
2253 if (currentClass.hasOuterInstance())
2254 otdef = outerThisDef(tree.pos, currentClass);
2255
2256 // If this is a local class, define proxies for all its free variables.
2257 List<JCVariableDecl> fvdefs = freevarDefs(
2258 tree.pos, freevars(currentClass), currentClass);
2259
2260 // Recursively translate superclass, interfaces.
2261 tree.extending = translate(tree.extending);
2262 tree.implementing = translate(tree.implementing);
2263
2264 if (currentClass.isDirectlyOrIndirectlyLocal()) {
2265 ClassSymbol encl = currentClass.owner.enclClass();
2266 if (encl.trans_local == null) {
2267 encl.trans_local = List.nil();
2268 }
2269 encl.trans_local = encl.trans_local.prepend(currentClass);
2270 }
2271
2272 // Recursively translate members, taking into account that new members
2273 // might be created during the translation and prepended to the member
2274 // list `tree.defs'.
2275 List<JCTree> seen = List.nil();
2276 while (tree.defs != seen) {
2277 List<JCTree> unseen = tree.defs;
2278 for (List<JCTree> l = unseen; l.nonEmpty() && l != seen; l = l.tail) {
2812 if (added.nonEmpty()) {
2813 List<JCStatement> initializers = added.toList();
2814 TreeInfo.mapSuperCalls(tree.body, supercall -> make.Block(0, initializers.append(supercall)));
2815 }
2816
2817 // pop local variables from proxy stack
2818 proxies = prevProxies;
2819
2820 outerThisStack = prevOuterThisStack;
2821 } else {
2822 super.visitMethodDef(tree);
2823 }
2824 if (tree.name == names.init && ((tree.sym.flags_field & Flags.COMPACT_RECORD_CONSTRUCTOR) != 0 ||
2825 (tree.sym.flags_field & (GENERATEDCONSTR | RECORD)) == (GENERATEDCONSTR | RECORD))) {
2826 // lets find out if there is any field waiting to be initialized
2827 ListBuffer<VarSymbol> fields = new ListBuffer<>();
2828 for (Symbol sym : currentClass.getEnclosedElements()) {
2829 if (sym.kind == Kinds.Kind.VAR && ((sym.flags() & RECORD) != 0))
2830 fields.append((VarSymbol) sym);
2831 }
2832 for (VarSymbol field: fields) {
2833 if ((field.flags_field & Flags.UNINITIALIZED_FIELD) != 0) {
2834 VarSymbol param = tree.params.stream().filter(p -> p.name == field.name).findFirst().get().sym;
2835 make.at(tree.pos);
2836 tree.body.stats = tree.body.stats.append(
2837 make.Exec(
2838 make.Assign(
2839 make.Select(make.This(field.owner.erasure(types)), field),
2840 make.Ident(param)).setType(field.erasure(types))));
2841 // we don't need the flag at the field anymore
2842 field.flags_field &= ~Flags.UNINITIALIZED_FIELD;
2843 }
2844 }
2845 }
2846 result = tree;
2847 }
2848
2849 public void visitTypeCast(JCTypeCast tree) {
2850 tree.clazz = translate(tree.clazz);
2851 if (tree.type.isPrimitive() != tree.expr.type.isPrimitive())
2852 tree.expr = translate(tree.expr, tree.type);
2853 else
2854 tree.expr = translate(tree.expr);
2855 result = tree;
2856 }
2857
2858 /**
2859 * All the exactness checks between primitive types that require a run-time
2860 * check are in {@code java.lang.runtime.ExactConversionsSupport}. Those methods
2861 * are in the form {@code ExactConversionsSupport.is<S>To<T>Exact} where both
2862 * {@code S} and {@code T} are primitive types and correspond to the runtime
2863 * action that will be executed to check whether a certain value (that is passed
2864 * as a parameter) can be converted to {@code T} without loss of information.
3040 Symbol constructor = accessConstructor(tree.pos(), tree.constructor);
3041 if (constructor != tree.constructor) {
3042 tree.args = tree.args.append(makeNull());
3043 tree.constructor = constructor;
3044 }
3045
3046 // If created class has an outer instance, and new is qualified, pass
3047 // qualifier as first argument. If new is not qualified, pass the
3048 // correct outer instance as first argument.
3049 if (c.hasOuterInstance()) {
3050 JCExpression thisArg;
3051 if (tree.encl != null) {
3052 thisArg = attr.makeNullCheck(translate(tree.encl));
3053 thisArg.type = tree.encl.type;
3054 } else if (c.isDirectlyOrIndirectlyLocal()) {
3055 // local class
3056 thisArg = makeThis(tree.pos(), c.innermostAccessibleEnclosingClass());
3057 } else {
3058 // nested class
3059 thisArg = makeOwnerThis(tree.pos(), c, false);
3060 }
3061 tree.args = tree.args.prepend(thisArg);
3062 }
3063 tree.encl = null;
3064
3065 // If we have an anonymous class, create its flat version, rather
3066 // than the class or interface following new.
3067 if (tree.def != null) {
3068 translate(tree.def);
3069
3070 tree.clazz = access(make_at(tree.clazz.pos()).Ident(tree.def.sym));
3071 tree.def = null;
3072 } else {
3073 tree.clazz = access(c, tree.clazz, enclOp, false);
3074 }
3075 result = tree;
3076 }
3077
3078 // Simplify conditionals with known constant controlling expressions.
3079 // This allows us to avoid generating supporting declarations for
|
90 private final Log log;
91 private final Symtab syms;
92 private final Resolve rs;
93 private final Operators operators;
94 private final Check chk;
95 private final Attr attr;
96 private TreeMaker make;
97 private DiagnosticPosition make_pos;
98 private final ConstFold cfolder;
99 private final Target target;
100 private final TypeEnvs typeEnvs;
101 private final Name dollarAssertionsDisabled;
102 private final Types types;
103 private final TransTypes transTypes;
104 private final boolean debugLower;
105 private final boolean disableProtectedAccessors; // experimental
106 private final PkgInfo pkginfoOpt;
107 private final boolean optimizeOuterThis;
108 private final boolean useMatchException;
109 private final HashMap<TypePairs, String> typePairToName;
110 private final boolean allowValueClasses;
111 private int variableIndex = 0;
112
113 @SuppressWarnings("this-escape")
114 protected Lower(Context context) {
115 context.put(lowerKey, this);
116 names = Names.instance(context);
117 log = Log.instance(context);
118 syms = Symtab.instance(context);
119 rs = Resolve.instance(context);
120 operators = Operators.instance(context);
121 chk = Check.instance(context);
122 attr = Attr.instance(context);
123 make = TreeMaker.instance(context);
124 cfolder = ConstFold.instance(context);
125 target = Target.instance(context);
126 typeEnvs = TypeEnvs.instance(context);
127 dollarAssertionsDisabled = names.
128 fromString(target.syntheticNameChar() + "assertionsDisabled");
129
130 types = Types.instance(context);
131 transTypes = TransTypes.instance(context);
132 Options options = Options.instance(context);
133 debugLower = options.isSet("debuglower");
134 pkginfoOpt = PkgInfo.get(options);
135 optimizeOuterThis =
136 target.optimizeOuterThis() ||
137 options.getBoolean("optimizeOuterThis", false);
138 disableProtectedAccessors = options.isSet("disableProtectedAccessors");
139 Source source = Source.instance(context);
140 Preview preview = Preview.instance(context);
141 useMatchException = Feature.PATTERN_SWITCH.allowedInSource(source) &&
142 (preview.isEnabled() || !preview.isPreview(Feature.PATTERN_SWITCH));
143 typePairToName = TypePairs.initialize(syms);
144 this.allowValueClasses = (!preview.isPreview(Feature.VALUE_CLASSES) || preview.isEnabled()) &&
145 Feature.VALUE_CLASSES.allowedInSource(source);
146 }
147
148 /** The currently enclosing class.
149 */
150 ClassSymbol currentClass;
151
152 /** A queue of all translated classes.
153 */
154 ListBuffer<JCTree> translated;
155
156 /** Environment for symbol lookup, set by translateTopLevelClass.
157 */
158 Env<AttrContext> attrEnv;
159
160 /** A hash table mapping syntax trees to their ending source positions.
161 */
162 EndPosTable endPosTable;
163
164 /* ************************************************************************
165 * Global mappings
182 * The current expected return type.
183 */
184 Type currentRestype;
185
186 /** The current method definition.
187 */
188 JCMethodDecl currentMethodDef;
189
190 /** The current method symbol.
191 */
192 MethodSymbol currentMethodSym;
193
194 /** The currently enclosing outermost class definition.
195 */
196 JCClassDecl outermostClassDef;
197
198 /** The currently enclosing outermost member definition.
199 */
200 JCTree outermostMemberDef;
201
202 /** A hash table mapping local classes to a set of outer this fields
203 */
204 public Map<ClassSymbol, Set<JCExpression>> initializerOuterThis = new WeakHashMap<>();
205
206 /** A navigator class for assembling a mapping from local class symbols
207 * to class definition trees.
208 * There is only one case; all other cases simply traverse down the tree.
209 */
210 class ClassMap extends TreeScanner {
211
212 /** All encountered class defs are entered into classdefs table.
213 */
214 public void visitClassDef(JCClassDecl tree) {
215 classdefs.put(tree.sym, tree);
216 super.visitClassDef(tree);
217 }
218 }
219 ClassMap classMap = new ClassMap();
220
221 /** Map a class symbol to its definition.
222 * @param c The class symbol of which we want to determine the definition.
223 */
224 JCClassDecl classDef(ClassSymbol c) {
225 // First lookup the class in the classdefs table.
858
859 /** Look up a method in a given scope.
860 */
861 private MethodSymbol lookupMethod(DiagnosticPosition pos, Name name, Type qual, List<Type> args) {
862 return rs.resolveInternalMethod(pos, attrEnv, qual, name, args, List.nil());
863 }
864
865 /** Anon inner classes are used as access constructor tags.
866 * accessConstructorTag will use an existing anon class if one is available,
867 * and synthesize a class (with makeEmptyClass) if one is not available.
868 * However, there is a small possibility that an existing class will not
869 * be generated as expected if it is inside a conditional with a constant
870 * expression. If that is found to be the case, create an empty class tree here.
871 */
872 private void checkAccessConstructorTags() {
873 for (List<ClassSymbol> l = accessConstrTags; l.nonEmpty(); l = l.tail) {
874 ClassSymbol c = l.head;
875 if (isTranslatedClassAvailable(c))
876 continue;
877 // Create class definition tree.
878 // IDENTITY_TYPE will be interpreted as ACC_SUPER for older class files so we are fine
879 JCClassDecl cdec = makeEmptyClass(STATIC | SYNTHETIC | IDENTITY_TYPE,
880 c.outermostClass(), c.flatname, false);
881 swapAccessConstructorTag(c, cdec.sym);
882 translated.append(cdec);
883 }
884 }
885 // where
886 private boolean isTranslatedClassAvailable(ClassSymbol c) {
887 for (JCTree tree: translated) {
888 if (tree.hasTag(CLASSDEF)
889 && ((JCClassDecl) tree).sym == c) {
890 return true;
891 }
892 }
893 return false;
894 }
895
896 void swapAccessConstructorTag(ClassSymbol oldCTag, ClassSymbol newCTag) {
897 for (MethodSymbol methodSymbol : accessConstrs.values()) {
898 Assert.check(methodSymbol.type.hasTag(METHOD));
899 MethodType oldMethodType =
1331 accessConstrs.put(constr, aconstr);
1332 accessed.append(constr);
1333 }
1334 return aconstr;
1335 } else {
1336 return constr;
1337 }
1338 }
1339
1340 /** Return an anonymous class nested in this toplevel class.
1341 */
1342 ClassSymbol accessConstructorTag() {
1343 ClassSymbol topClass = currentClass.outermostClass();
1344 ModuleSymbol topModle = topClass.packge().modle;
1345 for (int i = 1; ; i++) {
1346 Name flatname = names.fromString("" + topClass.getQualifiedName() +
1347 target.syntheticNameChar() +
1348 i);
1349 ClassSymbol ctag = chk.getCompiled(topModle, flatname);
1350 if (ctag == null)
1351 // IDENTITY_TYPE will be interpreted as ACC_SUPER for older class files so we are fine
1352 ctag = makeEmptyClass(STATIC | SYNTHETIC | IDENTITY_TYPE, topClass).sym;
1353 else if (!ctag.isAnonymous())
1354 continue;
1355 // keep a record of all tags, to verify that all are generated as required
1356 accessConstrTags = accessConstrTags.prepend(ctag);
1357 return ctag;
1358 }
1359 }
1360
1361 /** Add all required access methods for a private symbol to enclosing class.
1362 * @param sym The symbol.
1363 */
1364 void makeAccessible(Symbol sym) {
1365 JCClassDecl cdef = classDef(sym.owner.enclClass());
1366 if (cdef == null) Assert.error("class def not found: " + sym + " in " + sym.owner);
1367 if (sym.name == names.init) {
1368 cdef.defs = cdef.defs.prepend(
1369 accessConstructorDef(cdef.pos, sym, accessConstrs.get(sym)));
1370 } else {
1371 MethodSymbol[] accessors = accessSyms.get(sym);
1372 for (int i = 0; i < AccessCode.numberOfAccessCodes; i++) {
1488
1489 /** A stack containing the this$n field of the currently translated
1490 * classes (if needed) in innermost first order.
1491 * Inside a constructor, proxies and any this$n symbol are duplicated
1492 * in an additional innermost scope, where they represent the constructor
1493 * parameters.
1494 */
1495 List<VarSymbol> outerThisStack;
1496
1497 /** The name of a free variable proxy.
1498 */
1499 Name proxyName(Name name, int index) {
1500 Name proxyName = names.fromString("val" + target.syntheticNameChar() + name);
1501 if (index > 0) {
1502 proxyName = proxyName.append(names.fromString("" + target.syntheticNameChar() + index));
1503 }
1504 return proxyName;
1505 }
1506
1507 /** Proxy definitions for all free variables in given list, in reverse order.
1508 * @param pos The source code position of the definition.
1509 * @param freevars The free variables.
1510 * @param owner The class in which the definitions go.
1511 * @param additionalFlags Any additional flags
1512 */
1513 List<JCVariableDecl> freevarDefs(int pos, List<VarSymbol> freevars, Symbol owner,
1514 long additionalFlags) {
1515 long flags = FINAL | SYNTHETIC | additionalFlags;
1516 List<JCVariableDecl> defs = List.nil();
1517 Set<Name> proxyNames = new HashSet<>();
1518 for (List<VarSymbol> l = freevars; l.nonEmpty(); l = l.tail) {
1519 VarSymbol v = l.head;
1520 int index = 0;
1521 Name proxyName;
1522 do {
1523 proxyName = proxyName(v.name, index++);
1524 } while (!proxyNames.add(proxyName));
1525 VarSymbol proxy = new VarSymbol(
1526 flags, proxyName, v.erasure(types), owner);
1527 proxies.put(v, proxy);
1528 JCVariableDecl vd = make.at(pos).VarDef(proxy, null);
1529 vd.vartype = access(vd.vartype);
1530 defs = defs.prepend(vd);
1531 }
1532 return defs;
1573 JCVariableDecl outerThisDef(int pos, MethodSymbol owner) {
1574 ClassSymbol c = owner.enclClass();
1575 boolean isMandated =
1576 // Anonymous constructors
1577 (owner.isConstructor() && owner.isAnonymous()) ||
1578 // Constructors of non-private inner member classes
1579 (owner.isConstructor() && c.isInner() &&
1580 !c.isPrivate() && !c.isStatic());
1581 long flags =
1582 FINAL | (isMandated ? MANDATED : SYNTHETIC) | PARAMETER;
1583 VarSymbol outerThis = makeOuterThisVarSymbol(owner, flags);
1584 owner.extraParams = owner.extraParams.prepend(outerThis);
1585 return makeOuterThisVarDecl(pos, outerThis);
1586 }
1587
1588 /** Definition for this$n field.
1589 * @param pos The source code position of the definition.
1590 * @param owner The class in which the definition goes.
1591 */
1592 JCVariableDecl outerThisDef(int pos, ClassSymbol owner) {
1593 VarSymbol outerThis = makeOuterThisVarSymbol(owner, FINAL | SYNTHETIC | (allowValueClasses && owner.isValueClass() ? STRICT : 0));
1594 return makeOuterThisVarDecl(pos, outerThis);
1595 }
1596
1597 /** Return a list of trees that load the free variables in given list,
1598 * in reverse order.
1599 * @param pos The source code position to be used for the trees.
1600 * @param freevars The list of free variables.
1601 */
1602 List<JCExpression> loadFreevars(DiagnosticPosition pos, List<VarSymbol> freevars) {
1603 List<JCExpression> args = List.nil();
1604 for (List<VarSymbol> l = freevars; l.nonEmpty(); l = l.tail)
1605 args = args.prepend(loadFreevar(pos, l.head));
1606 return args;
1607 }
1608 //where
1609 JCExpression loadFreevar(DiagnosticPosition pos, VarSymbol v) {
1610 return access(v, make.at(pos).Ident(v), null, false);
1611 }
1612
1613 /** Construct a tree simulating the expression {@code C.this}.
1904 }
1905
1906 /* ************************************************************************
1907 * Code for .class
1908 *************************************************************************/
1909
1910 /** Return the symbol of a class to contain a cache of
1911 * compiler-generated statics such as class$ and the
1912 * $assertionsDisabled flag. We create an anonymous nested class
1913 * (unless one already exists) and return its symbol. However,
1914 * for backward compatibility in 1.4 and earlier we use the
1915 * top-level class itself.
1916 */
1917 private ClassSymbol outerCacheClass() {
1918 ClassSymbol clazz = outermostClassDef.sym;
1919 Scope s = clazz.members();
1920 for (Symbol sym : s.getSymbols(NON_RECURSIVE))
1921 if (sym.kind == TYP &&
1922 sym.name == names.empty &&
1923 (sym.flags() & INTERFACE) == 0) return (ClassSymbol) sym;
1924 // IDENTITY_TYPE will be interpreted as ACC_SUPER for older class files so we are fine
1925 return makeEmptyClass(STATIC | SYNTHETIC | IDENTITY_TYPE, clazz).sym;
1926 }
1927
1928 /** Create an attributed tree of the form left.name(). */
1929 private JCMethodInvocation makeCall(JCExpression left, Name name, List<JCExpression> args) {
1930 Assert.checkNonNull(left.type);
1931 Symbol funcsym = lookupMethod(make_pos, name, left.type,
1932 TreeInfo.types(args));
1933 return make.App(make.Select(left, funcsym), args);
1934 }
1935
1936 /** The tree simulating a T.class expression.
1937 * @param clazz The tree identifying type T.
1938 */
1939 private JCExpression classOf(JCTree clazz) {
1940 return classOfType(clazz.type, clazz.pos());
1941 }
1942
1943 private JCExpression classOfType(Type type, DiagnosticPosition pos) {
1944 switch (type.getTag()) {
1945 case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
1957 VarSymbol sym = new VarSymbol(
1958 STATIC | PUBLIC | FINAL, names._class,
1959 syms.classType, type.tsym);
1960 return make_at(pos).Select(make.Type(type), sym);
1961 default:
1962 throw new AssertionError();
1963 }
1964 }
1965
1966 /* ************************************************************************
1967 * Code for enabling/disabling assertions.
1968 *************************************************************************/
1969
1970 private ClassSymbol assertionsDisabledClassCache;
1971
1972 /**Used to create an auxiliary class to hold $assertionsDisabled for interfaces.
1973 */
1974 private ClassSymbol assertionsDisabledClass() {
1975 if (assertionsDisabledClassCache != null) return assertionsDisabledClassCache;
1976
1977 // IDENTITY_TYPE will be interpreted as ACC_SUPER for older class files so we are fine
1978 assertionsDisabledClassCache = makeEmptyClass(STATIC | SYNTHETIC | IDENTITY_TYPE, outermostClassDef.sym).sym;
1979
1980 return assertionsDisabledClassCache;
1981 }
1982
1983 // This code is not particularly robust if the user has
1984 // previously declared a member named '$assertionsDisabled'.
1985 // The same faulty idiom also appears in the translation of
1986 // class literals above. We should report an error if a
1987 // previous declaration is not synthetic.
1988
1989 private JCExpression assertFlagTest(DiagnosticPosition pos) {
1990 // Outermost class may be either true class or an interface.
1991 ClassSymbol outermostClass = outermostClassDef.sym;
1992
1993 //only classes can hold a non-public field, look for a usable one:
1994 ClassSymbol container = !currentClass.isInterface() ? currentClass :
1995 assertionsDisabledClass();
1996
1997 VarSymbol assertDisabledSym =
1998 (VarSymbol)lookupSynthetic(dollarAssertionsDisabled,
2246 proxies = new HashMap<>(proxies);
2247 List<VarSymbol> prevOuterThisStack = outerThisStack;
2248
2249 // If this is an enum definition
2250 if ((tree.mods.flags & ENUM) != 0 &&
2251 (types.supertype(currentClass.type).tsym.flags() & ENUM) == 0)
2252 visitEnumDef(tree);
2253
2254 if ((tree.mods.flags & RECORD) != 0) {
2255 visitRecordDef(tree);
2256 }
2257
2258 // If this is a nested class, define a this$n field for
2259 // it and add to proxies.
2260 JCVariableDecl otdef = null;
2261 if (currentClass.hasOuterInstance())
2262 otdef = outerThisDef(tree.pos, currentClass);
2263
2264 // If this is a local class, define proxies for all its free variables.
2265 List<JCVariableDecl> fvdefs = freevarDefs(
2266 tree.pos, freevars(currentClass), currentClass, allowValueClasses && currentClass.isValueClass() ? STRICT : 0);
2267
2268 // Recursively translate superclass, interfaces.
2269 tree.extending = translate(tree.extending);
2270 tree.implementing = translate(tree.implementing);
2271
2272 if (currentClass.isDirectlyOrIndirectlyLocal()) {
2273 ClassSymbol encl = currentClass.owner.enclClass();
2274 if (encl.trans_local == null) {
2275 encl.trans_local = List.nil();
2276 }
2277 encl.trans_local = encl.trans_local.prepend(currentClass);
2278 }
2279
2280 // Recursively translate members, taking into account that new members
2281 // might be created during the translation and prepended to the member
2282 // list `tree.defs'.
2283 List<JCTree> seen = List.nil();
2284 while (tree.defs != seen) {
2285 List<JCTree> unseen = tree.defs;
2286 for (List<JCTree> l = unseen; l.nonEmpty() && l != seen; l = l.tail) {
2820 if (added.nonEmpty()) {
2821 List<JCStatement> initializers = added.toList();
2822 TreeInfo.mapSuperCalls(tree.body, supercall -> make.Block(0, initializers.append(supercall)));
2823 }
2824
2825 // pop local variables from proxy stack
2826 proxies = prevProxies;
2827
2828 outerThisStack = prevOuterThisStack;
2829 } else {
2830 super.visitMethodDef(tree);
2831 }
2832 if (tree.name == names.init && ((tree.sym.flags_field & Flags.COMPACT_RECORD_CONSTRUCTOR) != 0 ||
2833 (tree.sym.flags_field & (GENERATEDCONSTR | RECORD)) == (GENERATEDCONSTR | RECORD))) {
2834 // lets find out if there is any field waiting to be initialized
2835 ListBuffer<VarSymbol> fields = new ListBuffer<>();
2836 for (Symbol sym : currentClass.getEnclosedElements()) {
2837 if (sym.kind == Kinds.Kind.VAR && ((sym.flags() & RECORD) != 0))
2838 fields.append((VarSymbol) sym);
2839 }
2840 ListBuffer<JCStatement> initializers = new ListBuffer<>();
2841 for (VarSymbol field: fields) {
2842 if ((field.flags_field & Flags.UNINITIALIZED_FIELD) != 0) {
2843 VarSymbol param = tree.params.stream().filter(p -> p.name == field.name).findFirst().get().sym;
2844 make.at(tree.pos);
2845 initializers.add(make.Exec(
2846 make.Assign(
2847 make.Select(make.This(field.owner.erasure(types)), field),
2848 make.Ident(param)).setType(field.erasure(types))));
2849 field.flags_field &= ~Flags.UNINITIALIZED_FIELD;
2850 }
2851 }
2852 if (initializers.nonEmpty()) {
2853 if (tree.sym.owner.isValueClass()) {
2854 TreeInfo.mapSuperCalls(tree.body, supercall -> make.Block(0, initializers.toList().append(supercall)));
2855 } else {
2856 tree.body.stats = tree.body.stats.appendList(initializers);
2857 }
2858 }
2859 }
2860 result = tree;
2861 }
2862
2863 public void visitTypeCast(JCTypeCast tree) {
2864 tree.clazz = translate(tree.clazz);
2865 if (tree.type.isPrimitive() != tree.expr.type.isPrimitive())
2866 tree.expr = translate(tree.expr, tree.type);
2867 else
2868 tree.expr = translate(tree.expr);
2869 result = tree;
2870 }
2871
2872 /**
2873 * All the exactness checks between primitive types that require a run-time
2874 * check are in {@code java.lang.runtime.ExactConversionsSupport}. Those methods
2875 * are in the form {@code ExactConversionsSupport.is<S>To<T>Exact} where both
2876 * {@code S} and {@code T} are primitive types and correspond to the runtime
2877 * action that will be executed to check whether a certain value (that is passed
2878 * as a parameter) can be converted to {@code T} without loss of information.
3054 Symbol constructor = accessConstructor(tree.pos(), tree.constructor);
3055 if (constructor != tree.constructor) {
3056 tree.args = tree.args.append(makeNull());
3057 tree.constructor = constructor;
3058 }
3059
3060 // If created class has an outer instance, and new is qualified, pass
3061 // qualifier as first argument. If new is not qualified, pass the
3062 // correct outer instance as first argument.
3063 if (c.hasOuterInstance()) {
3064 JCExpression thisArg;
3065 if (tree.encl != null) {
3066 thisArg = attr.makeNullCheck(translate(tree.encl));
3067 thisArg.type = tree.encl.type;
3068 } else if (c.isDirectlyOrIndirectlyLocal()) {
3069 // local class
3070 thisArg = makeThis(tree.pos(), c.innermostAccessibleEnclosingClass());
3071 } else {
3072 // nested class
3073 thisArg = makeOwnerThis(tree.pos(), c, false);
3074 if (currentMethodSym != null &&
3075 ((currentMethodSym.flags_field & (STATIC | BLOCK)) == BLOCK) &&
3076 currentMethodSym.owner.isValueClass()) {
3077 // instance initializer in a value class
3078 Set<JCExpression> outerThisSet = initializerOuterThis.get(currentClass);
3079 if (outerThisSet == null) {
3080 outerThisSet = new HashSet<>();
3081 }
3082 outerThisSet.add(thisArg);
3083 initializerOuterThis.put(currentClass, outerThisSet);
3084 }
3085 }
3086 tree.args = tree.args.prepend(thisArg);
3087 }
3088 tree.encl = null;
3089
3090 // If we have an anonymous class, create its flat version, rather
3091 // than the class or interface following new.
3092 if (tree.def != null) {
3093 translate(tree.def);
3094
3095 tree.clazz = access(make_at(tree.clazz.pos()).Ident(tree.def.sym));
3096 tree.def = null;
3097 } else {
3098 tree.clazz = access(c, tree.clazz, enclOp, false);
3099 }
3100 result = tree;
3101 }
3102
3103 // Simplify conditionals with known constant controlling expressions.
3104 // This allows us to avoid generating supporting declarations for
|