1117 sym.owner.enclClass() != currentClass) {
1118 // A constant is replaced by its constant value.
1119 Object cv = ((VarSymbol)sym).getConstValue();
1120 if (cv != null) {
1121 make.at(tree.pos);
1122 return makeLit(sym.type, cv);
1123 }
1124 if (lambdaTranslationMap != null && lambdaTranslationMap.get(sym) != null) {
1125 return make.at(tree.pos).Ident(lambdaTranslationMap.get(sym));
1126 } else {
1127 // Otherwise replace the variable by its proxy.
1128 sym = proxies.get(sym);
1129 Assert.check(sym != null && (sym.flags_field & FINAL) != 0);
1130 tree = make.at(tree.pos).Ident(sym);
1131 }
1132 }
1133 JCExpression base = (tree.hasTag(SELECT)) ? ((JCFieldAccess) tree).selected : null;
1134 switch (sym.kind) {
1135 case TYP:
1136 if (sym.owner.kind != PCK) {
1137 // Convert type idents to
1138 // <flat name> or <package name> . <flat name>
1139 Name flatname = Convert.shortName(sym.flatName());
1140 while (base != null &&
1141 TreeInfo.symbol(base) != null &&
1142 TreeInfo.symbol(base).kind != PCK) {
1143 base = (base.hasTag(SELECT))
1144 ? ((JCFieldAccess) base).selected
1145 : null;
1146 }
1147 if (tree.hasTag(IDENT)) {
1148 ((JCIdent) tree).name = flatname;
1149 } else if (base == null) {
1150 tree = make.at(tree.pos).Ident(sym);
1151 ((JCIdent) tree).name = flatname;
1152 } else {
1153 ((JCFieldAccess) tree).selected = base;
1154 ((JCFieldAccess) tree).name = flatname;
1155 }
1156 }
1157 break;
1158 case MTH: case VAR:
1159 if (sym.owner.kind == TYP) {
1160
1161 // Access methods are required for
1162 // - private members,
1163 // - protected members in a superclass of an
1164 // enclosing class contained in another package.
1165 // - all non-private members accessed via a qualified super.
1166 boolean protAccess = refSuper && !needsPrivateAccess(sym)
1167 || needsProtectedAccess(sym, tree);
1168 boolean accReq = protAccess || needsPrivateAccess(sym);
1169
1170 // A base has to be supplied for
1171 // - simple identifiers accessing variables in outer classes.
1172 boolean baseReq =
1173 base == null &&
1174 sym.owner != syms.predefClass &&
1439 * @param pos The source code position of the definition.
1440 * @param freevars The free variables.
1441 * @param owner The class in which the definitions go.
1442 */
1443 List<JCVariableDecl> freevarDefs(int pos, List<VarSymbol> freevars, Symbol owner) {
1444 return freevarDefs(pos, freevars, owner, 0);
1445 }
1446
1447 List<JCVariableDecl> freevarDefs(int pos, List<VarSymbol> freevars, Symbol owner,
1448 long additionalFlags) {
1449 long flags = FINAL | SYNTHETIC | additionalFlags;
1450 List<JCVariableDecl> defs = List.nil();
1451 Set<Name> proxyNames = new HashSet<>();
1452 for (List<VarSymbol> l = freevars; l.nonEmpty(); l = l.tail) {
1453 VarSymbol v = l.head;
1454 int index = 0;
1455 Name proxyName;
1456 do {
1457 proxyName = proxyName(v.name, index++);
1458 } while (!proxyNames.add(proxyName));
1459 VarSymbol proxy = new VarSymbol(
1460 flags, proxyName, v.erasure(types), owner);
1461 proxies.put(v, proxy);
1462 JCVariableDecl vd = make.at(pos).VarDef(proxy, null);
1463 vd.vartype = access(vd.vartype);
1464 defs = defs.prepend(vd);
1465 }
1466 return defs;
1467 }
1468
1469 /** The name of a this$n field
1470 * @param type The class referenced by the this$n field
1471 */
1472 Name outerThisName(Type type, Symbol owner) {
1473 Type t = type.getEnclosingType();
1474 int nestingLevel = 0;
1475 while (t.hasTag(CLASS)) {
1476 t = t.getEnclosingType();
1477 nestingLevel++;
1478 }
1479 Name result = names.fromString("this" + target.syntheticNameChar() + nestingLevel);
1480 while (owner.kind == TYP && ((ClassSymbol)owner).members().findFirst(result) != null)
1507 JCVariableDecl outerThisDef(int pos, MethodSymbol owner) {
1508 ClassSymbol c = owner.enclClass();
1509 boolean isMandated =
1510 // Anonymous constructors
1511 (owner.isConstructor() && owner.isAnonymous()) ||
1512 // Constructors of non-private inner member classes
1513 (owner.isConstructor() && c.isInner() &&
1514 !c.isPrivate() && !c.isStatic());
1515 long flags =
1516 FINAL | (isMandated ? MANDATED : SYNTHETIC) | PARAMETER;
1517 VarSymbol outerThis = makeOuterThisVarSymbol(owner, flags);
1518 owner.extraParams = owner.extraParams.prepend(outerThis);
1519 return makeOuterThisVarDecl(pos, outerThis);
1520 }
1521
1522 /** Definition for this$n field.
1523 * @param pos The source code position of the definition.
1524 * @param owner The class in which the definition goes.
1525 */
1526 JCVariableDecl outerThisDef(int pos, ClassSymbol owner) {
1527 VarSymbol outerThis = makeOuterThisVarSymbol(owner, FINAL | SYNTHETIC);
1528 return makeOuterThisVarDecl(pos, outerThis);
1529 }
1530
1531 /** Return a list of trees that load the free variables in given list,
1532 * in reverse order.
1533 * @param pos The source code position to be used for the trees.
1534 * @param freevars The list of free variables.
1535 */
1536 List<JCExpression> loadFreevars(DiagnosticPosition pos, List<VarSymbol> freevars) {
1537 List<JCExpression> args = List.nil();
1538 for (List<VarSymbol> l = freevars; l.nonEmpty(); l = l.tail)
1539 args = args.prepend(loadFreevar(pos, l.head));
1540 return args;
1541 }
1542 //where
1543 JCExpression loadFreevar(DiagnosticPosition pos, VarSymbol v) {
1544 return access(v, make.at(pos).Ident(v), null, false);
1545 }
1546
1547 /** Construct a tree simulating the expression {@code C.this}.
1690 }
1691
1692 JCStatement exceptionalRethrow = make.Throw(make.Ident(primaryException));
1693 JCBlock exceptionalCloseBlock = make.Block(0L, List.of(exceptionalCloseStatement, exceptionalRethrow));
1694 JCCatch exceptionalCatchClause = make.Catch(primaryExceptionDecl, exceptionalCloseBlock);
1695
1696 //create the main try statement with the close:
1697 JCTry outerTry = make.Try(makeTwrBlock(resources.tail, block, depth + 1),
1698 List.of(exceptionalCatchClause),
1699 finallyClause);
1700
1701 outerTry.finallyCanCompleteNormally = true;
1702 stats.add(outerTry);
1703
1704 JCBlock newBlock = make.Block(0L, stats.toList());
1705 return newBlock;
1706 }
1707
1708 private JCStatement makeResourceCloseInvocation(JCExpression resource) {
1709 // convert to AutoCloseable if needed
1710 if (types.asSuper(resource.type, syms.autoCloseableType.tsym) == null) {
1711 resource = convert(resource, syms.autoCloseableType);
1712 }
1713
1714 // create resource.close() method invocation
1715 JCExpression resourceClose = makeCall(resource,
1716 names.close,
1717 List.nil());
1718 return make.Exec(resourceClose);
1719 }
1720
1721 private JCExpression makeNonNullCheck(JCExpression expression) {
1722 return makeBinary(NE, expression, makeNull());
1723 }
1724
1725 /** Construct a tree that represents the outer instance
1726 * {@code C.this}. Never pick the current `this'.
1727 * @param pos The source code position to be used for the tree.
1728 * @param c The qualifier class.
1729 */
1730 JCExpression makeOuterThis(DiagnosticPosition pos, TypeSymbol c) {
2074 /** Visitor method: Translate a single node.
2075 * Attach the source position from the old tree to its replacement tree.
2076 */
2077 @Override
2078 public <T extends JCTree> T translate(T tree) {
2079 if (tree == null) {
2080 return null;
2081 } else {
2082 make_at(tree.pos());
2083 T result = super.translate(tree);
2084 if (endPosTable != null && result != tree) {
2085 endPosTable.replaceTree(tree, result);
2086 }
2087 return result;
2088 }
2089 }
2090
2091 /** Visitor method: Translate a single node, boxing or unboxing if needed.
2092 */
2093 public <T extends JCExpression> T translate(T tree, Type type) {
2094 return (tree == null) ? null : boxIfNeeded(translate(tree), type);
2095 }
2096
2097 /** Visitor method: Translate tree.
2098 */
2099 public <T extends JCTree> T translate(T tree, JCExpression enclOp) {
2100 JCExpression prevEnclOp = this.enclOp;
2101 this.enclOp = enclOp;
2102 T res = translate(tree);
2103 this.enclOp = prevEnclOp;
2104 return res;
2105 }
2106
2107 /** Visitor method: Translate list of trees.
2108 */
2109 public <T extends JCExpression> List<T> translate(List<T> trees, Type type) {
2110 if (trees == null) return null;
2111 for (List<T> l = trees; l.nonEmpty(); l = l.tail)
2112 l.head = translate(l.head, type);
2113 return trees;
2114 }
2213 encl.trans_local = encl.trans_local.prepend(currentClass);
2214 }
2215
2216 // Recursively translate members, taking into account that new members
2217 // might be created during the translation and prepended to the member
2218 // list `tree.defs'.
2219 List<JCTree> seen = List.nil();
2220 while (tree.defs != seen) {
2221 List<JCTree> unseen = tree.defs;
2222 for (List<JCTree> l = unseen; l.nonEmpty() && l != seen; l = l.tail) {
2223 JCTree outermostMemberDefPrev = outermostMemberDef;
2224 if (outermostMemberDefPrev == null) outermostMemberDef = l.head;
2225 l.head = translate(l.head);
2226 outermostMemberDef = outermostMemberDefPrev;
2227 }
2228 seen = unseen;
2229 }
2230
2231 // Convert a protected modifier to public, mask static modifier.
2232 if ((tree.mods.flags & PROTECTED) != 0) tree.mods.flags |= PUBLIC;
2233 tree.mods.flags &= ClassFlags;
2234
2235 // Convert name to flat representation, replacing '.' by '$'.
2236 tree.name = Convert.shortName(currentClass.flatName());
2237
2238 // Add free variables proxy definitions to class.
2239
2240 for (List<JCVariableDecl> l = fvdefs; l.nonEmpty(); l = l.tail) {
2241 tree.defs = tree.defs.prepend(l.head);
2242 enterSynthetic(tree.pos(), l.head.sym, currentClass.members());
2243 }
2244 // If this$n was accessed, add the field definition and
2245 // update initial constructors to initialize it
2246 if (currentClass.hasOuterInstance() && shouldEmitOuterThis(currentClass)) {
2247 tree.defs = tree.defs.prepend(otdef);
2248 enterSynthetic(tree.pos(), otdef.sym, currentClass.members());
2249
2250 for (JCTree def : tree.defs) {
2251 if (TreeInfo.isInitialConstructor(def)) {
2252 JCMethodDecl mdef = (JCMethodDecl) def;
2253 mdef.body.stats = mdef.body.stats.prepend(
3092 while (args.nonEmpty()) {
3093 JCExpression arg = translate(args.head, varargsElement);
3094 elems.append(arg);
3095 args = args.tail;
3096 }
3097 JCNewArray boxedArgs = make.NewArray(make.Type(varargsElement),
3098 List.nil(),
3099 elems.toList());
3100 boxedArgs.type = new ArrayType(varargsElement, syms.arrayClass);
3101 result.append(boxedArgs);
3102 } else {
3103 if (args.length() != 1) throw new AssertionError(args);
3104 JCExpression arg = translate(args.head, parameter);
3105 anyChanges |= (arg != args.head);
3106 result.append(arg);
3107 if (!anyChanges) return _args;
3108 }
3109 return result.toList();
3110 }
3111
3112 /** Expand a boxing or unboxing conversion if needed. */
3113 @SuppressWarnings("unchecked") // XXX unchecked
3114 <T extends JCExpression> T boxIfNeeded(T tree, Type type) {
3115 boolean havePrimitive = tree.type.isPrimitive();
3116 if (havePrimitive == type.isPrimitive())
3117 return tree;
3118 if (havePrimitive) {
3119 Type unboxedTarget = types.unboxedType(type);
3120 if (!unboxedTarget.hasTag(NONE)) {
3121 if (!types.isSubtype(tree.type, unboxedTarget)) //e.g. Character c = 89;
3122 tree.type = unboxedTarget.constType(tree.type.constValue());
3123 return (T)boxPrimitive(tree, types.erasure(type));
3124 } else {
3125 tree = (T)boxPrimitive(tree);
3126 }
3127 } else {
3128 tree = (T)unbox(tree, type);
3129 }
3130 return tree;
3131 }
3490 * A statement of the form
3491 *
3492 * <pre>
3493 * for ( T v : coll ) stmt ;
3494 * </pre>
3495 *
3496 * (where coll implements {@code Iterable<? extends T>}) gets translated to
3497 *
3498 * <pre>{@code
3499 * for ( Iterator<? extends T> #i = coll.iterator(); #i.hasNext(); ) {
3500 * T v = (T) #i.next();
3501 * stmt;
3502 * }
3503 * }</pre>
3504 *
3505 * where #i is a freshly named synthetic local variable.
3506 */
3507 private void visitIterableForeachLoop(JCEnhancedForLoop tree) {
3508 make_at(tree.expr.pos());
3509 Type iteratorTarget = syms.objectType;
3510 Type iterableType = types.asSuper(types.cvarUpperBound(tree.expr.type),
3511 syms.iterableType.tsym);
3512 if (iterableType.getTypeArguments().nonEmpty())
3513 iteratorTarget = types.erasure(iterableType.getTypeArguments().head);
3514 Type eType = types.skipTypeVars(tree.expr.type, false);
3515 tree.expr.type = types.erasure(eType);
3516 if (eType.isCompound())
3517 tree.expr = make.TypeCast(types.erasure(iterableType), tree.expr);
3518 Symbol iterator = lookupMethod(tree.expr.pos(),
3519 names.iterator,
3520 eType,
3521 List.nil());
3522 VarSymbol itvar = new VarSymbol(SYNTHETIC, names.fromString("i" + target.syntheticNameChar()),
3523 types.erasure(types.asSuper(iterator.type.getReturnType(), syms.iteratorType.tsym)),
3524 currentMethodSym);
3525
3526 JCStatement init = make.
3527 VarDef(itvar, make.App(make.Select(tree.expr, iterator)
3528 .setType(types.erasure(iterator.type))));
3529
3530 Symbol hasNext = lookupMethod(tree.expr.pos(),
3531 names.hasNext,
3532 itvar.type,
3533 List.nil());
3534 JCMethodInvocation cond = make.App(make.Select(make.Ident(itvar), hasNext));
3535 Symbol next = lookupMethod(tree.expr.pos(),
3536 names.next,
3537 itvar.type,
3538 List.nil());
3539 JCExpression vardefinit = make.App(make.Select(make.Ident(itvar), next));
3540 if (tree.var.type.isPrimitive())
3541 vardefinit = make.TypeCast(types.cvarUpperBound(iteratorTarget), vardefinit);
3542 else
3543 vardefinit = make.TypeCast(tree.var.type, vardefinit);
3580 new MethodSymbol(tree.flags | BLOCK,
3581 names.empty, null,
3582 currentClass);
3583 }
3584 super.visitBlock(tree);
3585 currentMethodSym = oldMethodSym;
3586 }
3587
3588 public void visitDoLoop(JCDoWhileLoop tree) {
3589 tree.body = translate(tree.body);
3590 tree.cond = translate(tree.cond, syms.booleanType);
3591 result = tree;
3592 }
3593
3594 public void visitWhileLoop(JCWhileLoop tree) {
3595 tree.cond = translate(tree.cond, syms.booleanType);
3596 tree.body = translate(tree.body);
3597 result = tree;
3598 }
3599
3600 public void visitForLoop(JCForLoop tree) {
3601 tree.init = translate(tree.init);
3602 if (tree.cond != null)
3603 tree.cond = translate(tree.cond, syms.booleanType);
3604 tree.step = translate(tree.step);
3605 tree.body = translate(tree.body);
3606 result = tree;
3607 }
3608
3609 public void visitReturn(JCReturn tree) {
3610 if (tree.expr != null)
3611 tree.expr = translate(tree.expr,
3612 types.erasure(currentMethodDef
3613 .restype.type));
3614 result = tree;
3615 }
3616
3617 public void visitSwitch(JCSwitch tree) {
3618 List<JCCase> cases = tree.patternSwitch ? addDefaultIfNeeded(tree.cases) : tree.cases;
3619 handleSwitch(tree, tree.selector, cases);
4058 tree.value = translate(tree.value, tree.target.type);
4059 result = tree;
4060 }
4061
4062 public void visitNewArray(JCNewArray tree) {
4063 tree.elemtype = translate(tree.elemtype);
4064 for (List<JCExpression> t = tree.dims; t.tail != null; t = t.tail)
4065 if (t.head != null) t.head = translate(t.head, syms.intType);
4066 tree.elems = translate(tree.elems, types.elemtype(tree.type));
4067 result = tree;
4068 }
4069
4070 public void visitSelect(JCFieldAccess tree) {
4071 // need to special case-access of the form C.super.x
4072 // these will always need an access method, unless C
4073 // is a default interface subclassed by the current class.
4074 boolean qualifiedSuperAccess =
4075 tree.selected.hasTag(SELECT) &&
4076 TreeInfo.name(tree.selected) == names._super &&
4077 !types.isDirectSuperInterface(((JCFieldAccess)tree.selected).selected.type.tsym, currentClass);
4078 tree.selected = translate(tree.selected);
4079 if (tree.name == names._class) {
4080 result = classOf(tree.selected);
4081 }
4082 else if (tree.name == names._super &&
4083 types.isDirectSuperInterface(tree.selected.type.tsym, currentClass)) {
4084 //default super call!! Not a classic qualified super call
4085 TypeSymbol supSym = tree.selected.type.tsym;
4086 Assert.checkNonNull(types.asSuper(currentClass.type, supSym));
4087 result = tree;
4088 }
4089 else if (tree.name == names._this || tree.name == names._super) {
4090 result = makeThis(tree.pos(), tree.selected.type.tsym);
4091 }
4092 else
4093 result = access(tree.sym, tree, enclOp, qualifiedSuperAccess);
4094 }
4095
4096 public void visitLetExpr(LetExpr tree) {
4097 tree.defs = translate(tree.defs);
4098 tree.expr = translate(tree.expr, tree.type);
4099 result = tree;
4100 }
4101
4102 // There ought to be nothing to rewrite here;
4103 // we don't generate code.
4104 public void visitAnnotation(JCAnnotation tree) {
4105 result = tree;
4106 }
|
1117 sym.owner.enclClass() != currentClass) {
1118 // A constant is replaced by its constant value.
1119 Object cv = ((VarSymbol)sym).getConstValue();
1120 if (cv != null) {
1121 make.at(tree.pos);
1122 return makeLit(sym.type, cv);
1123 }
1124 if (lambdaTranslationMap != null && lambdaTranslationMap.get(sym) != null) {
1125 return make.at(tree.pos).Ident(lambdaTranslationMap.get(sym));
1126 } else {
1127 // Otherwise replace the variable by its proxy.
1128 sym = proxies.get(sym);
1129 Assert.check(sym != null && (sym.flags_field & FINAL) != 0);
1130 tree = make.at(tree.pos).Ident(sym);
1131 }
1132 }
1133 JCExpression base = (tree.hasTag(SELECT)) ? ((JCFieldAccess) tree).selected : null;
1134 switch (sym.kind) {
1135 case TYP:
1136 if (sym.owner.kind != PCK) {
1137 // Make sure not to lose type fidelity due to symbol sharing between projections
1138 boolean requireReferenceProjection =
1139 tree.hasTag(SELECT) && ((JCFieldAccess) tree).name == names.ref && tree.type.isReferenceProjection();
1140 // Convert type idents to
1141 // <flat name> or <package name> . <flat name>
1142 Name flatname = Convert.shortName(sym.flatName());
1143 while (base != null &&
1144 TreeInfo.symbol(base) != null &&
1145 TreeInfo.symbol(base).kind != PCK) {
1146 base = (base.hasTag(SELECT))
1147 ? ((JCFieldAccess) base).selected
1148 : null;
1149 }
1150 if (tree.hasTag(IDENT)) {
1151 ((JCIdent) tree).name = flatname;
1152 } else if (base == null) {
1153 tree = make.at(tree.pos).Ident(sym);
1154 ((JCIdent) tree).name = flatname;
1155 if (requireReferenceProjection) {
1156 tree.setType(tree.type.referenceProjection());
1157 }
1158 } else {
1159 ((JCFieldAccess) tree).selected = base;
1160 ((JCFieldAccess) tree).name = flatname;
1161 if (requireReferenceProjection) {
1162 tree.setType(tree.type.referenceProjection());
1163 }
1164 }
1165 }
1166 break;
1167 case MTH: case VAR:
1168 if (sym.owner.kind == TYP) {
1169
1170 // Access methods are required for
1171 // - private members,
1172 // - protected members in a superclass of an
1173 // enclosing class contained in another package.
1174 // - all non-private members accessed via a qualified super.
1175 boolean protAccess = refSuper && !needsPrivateAccess(sym)
1176 || needsProtectedAccess(sym, tree);
1177 boolean accReq = protAccess || needsPrivateAccess(sym);
1178
1179 // A base has to be supplied for
1180 // - simple identifiers accessing variables in outer classes.
1181 boolean baseReq =
1182 base == null &&
1183 sym.owner != syms.predefClass &&
1448 * @param pos The source code position of the definition.
1449 * @param freevars The free variables.
1450 * @param owner The class in which the definitions go.
1451 */
1452 List<JCVariableDecl> freevarDefs(int pos, List<VarSymbol> freevars, Symbol owner) {
1453 return freevarDefs(pos, freevars, owner, 0);
1454 }
1455
1456 List<JCVariableDecl> freevarDefs(int pos, List<VarSymbol> freevars, Symbol owner,
1457 long additionalFlags) {
1458 long flags = FINAL | SYNTHETIC | additionalFlags;
1459 List<JCVariableDecl> defs = List.nil();
1460 Set<Name> proxyNames = new HashSet<>();
1461 for (List<VarSymbol> l = freevars; l.nonEmpty(); l = l.tail) {
1462 VarSymbol v = l.head;
1463 int index = 0;
1464 Name proxyName;
1465 do {
1466 proxyName = proxyName(v.name, index++);
1467 } while (!proxyNames.add(proxyName));
1468 final Type type = v.erasure(types);
1469 VarSymbol proxy = new VarSymbol(
1470 flags, proxyName, type, owner);
1471 proxies.put(v, proxy);
1472 JCVariableDecl vd = make.at(pos).VarDef(proxy, null);
1473 vd.vartype = access(vd.vartype);
1474 defs = defs.prepend(vd);
1475 }
1476 return defs;
1477 }
1478
1479 /** The name of a this$n field
1480 * @param type The class referenced by the this$n field
1481 */
1482 Name outerThisName(Type type, Symbol owner) {
1483 Type t = type.getEnclosingType();
1484 int nestingLevel = 0;
1485 while (t.hasTag(CLASS)) {
1486 t = t.getEnclosingType();
1487 nestingLevel++;
1488 }
1489 Name result = names.fromString("this" + target.syntheticNameChar() + nestingLevel);
1490 while (owner.kind == TYP && ((ClassSymbol)owner).members().findFirst(result) != null)
1517 JCVariableDecl outerThisDef(int pos, MethodSymbol owner) {
1518 ClassSymbol c = owner.enclClass();
1519 boolean isMandated =
1520 // Anonymous constructors
1521 (owner.isConstructor() && owner.isAnonymous()) ||
1522 // Constructors of non-private inner member classes
1523 (owner.isConstructor() && c.isInner() &&
1524 !c.isPrivate() && !c.isStatic());
1525 long flags =
1526 FINAL | (isMandated ? MANDATED : SYNTHETIC) | PARAMETER;
1527 VarSymbol outerThis = makeOuterThisVarSymbol(owner, flags);
1528 owner.extraParams = owner.extraParams.prepend(outerThis);
1529 return makeOuterThisVarDecl(pos, outerThis);
1530 }
1531
1532 /** Definition for this$n field.
1533 * @param pos The source code position of the definition.
1534 * @param owner The class in which the definition goes.
1535 */
1536 JCVariableDecl outerThisDef(int pos, ClassSymbol owner) {
1537 Type target = types.erasure(owner.enclClass().type.getEnclosingType());
1538 long flags = FINAL | SYNTHETIC;
1539 VarSymbol outerThis = makeOuterThisVarSymbol(owner, flags);
1540 return makeOuterThisVarDecl(pos, outerThis);
1541 }
1542
1543 /** Return a list of trees that load the free variables in given list,
1544 * in reverse order.
1545 * @param pos The source code position to be used for the trees.
1546 * @param freevars The list of free variables.
1547 */
1548 List<JCExpression> loadFreevars(DiagnosticPosition pos, List<VarSymbol> freevars) {
1549 List<JCExpression> args = List.nil();
1550 for (List<VarSymbol> l = freevars; l.nonEmpty(); l = l.tail)
1551 args = args.prepend(loadFreevar(pos, l.head));
1552 return args;
1553 }
1554 //where
1555 JCExpression loadFreevar(DiagnosticPosition pos, VarSymbol v) {
1556 return access(v, make.at(pos).Ident(v), null, false);
1557 }
1558
1559 /** Construct a tree simulating the expression {@code C.this}.
1702 }
1703
1704 JCStatement exceptionalRethrow = make.Throw(make.Ident(primaryException));
1705 JCBlock exceptionalCloseBlock = make.Block(0L, List.of(exceptionalCloseStatement, exceptionalRethrow));
1706 JCCatch exceptionalCatchClause = make.Catch(primaryExceptionDecl, exceptionalCloseBlock);
1707
1708 //create the main try statement with the close:
1709 JCTry outerTry = make.Try(makeTwrBlock(resources.tail, block, depth + 1),
1710 List.of(exceptionalCatchClause),
1711 finallyClause);
1712
1713 outerTry.finallyCanCompleteNormally = true;
1714 stats.add(outerTry);
1715
1716 JCBlock newBlock = make.Block(0L, stats.toList());
1717 return newBlock;
1718 }
1719
1720 private JCStatement makeResourceCloseInvocation(JCExpression resource) {
1721 // convert to AutoCloseable if needed
1722 if (types.asSuper(resource.type.referenceProjectionOrSelf(), syms.autoCloseableType.tsym) == null) {
1723 resource = convert(resource, syms.autoCloseableType);
1724 }
1725
1726 // create resource.close() method invocation
1727 JCExpression resourceClose = makeCall(resource,
1728 names.close,
1729 List.nil());
1730 return make.Exec(resourceClose);
1731 }
1732
1733 private JCExpression makeNonNullCheck(JCExpression expression) {
1734 return makeBinary(NE, expression, makeNull());
1735 }
1736
1737 /** Construct a tree that represents the outer instance
1738 * {@code C.this}. Never pick the current `this'.
1739 * @param pos The source code position to be used for the tree.
1740 * @param c The qualifier class.
1741 */
1742 JCExpression makeOuterThis(DiagnosticPosition pos, TypeSymbol c) {
2086 /** Visitor method: Translate a single node.
2087 * Attach the source position from the old tree to its replacement tree.
2088 */
2089 @Override
2090 public <T extends JCTree> T translate(T tree) {
2091 if (tree == null) {
2092 return null;
2093 } else {
2094 make_at(tree.pos());
2095 T result = super.translate(tree);
2096 if (endPosTable != null && result != tree) {
2097 endPosTable.replaceTree(tree, result);
2098 }
2099 return result;
2100 }
2101 }
2102
2103 /** Visitor method: Translate a single node, boxing or unboxing if needed.
2104 */
2105 public <T extends JCExpression> T translate(T tree, Type type) {
2106 return (tree == null) ? null :
2107 applyPrimitiveConversionsAsNeeded(boxIfNeeded(translate(tree), type), type);
2108 }
2109
2110 /** Visitor method: Translate tree.
2111 */
2112 public <T extends JCTree> T translate(T tree, JCExpression enclOp) {
2113 JCExpression prevEnclOp = this.enclOp;
2114 this.enclOp = enclOp;
2115 T res = translate(tree);
2116 this.enclOp = prevEnclOp;
2117 return res;
2118 }
2119
2120 /** Visitor method: Translate list of trees.
2121 */
2122 public <T extends JCExpression> List<T> translate(List<T> trees, Type type) {
2123 if (trees == null) return null;
2124 for (List<T> l = trees; l.nonEmpty(); l = l.tail)
2125 l.head = translate(l.head, type);
2126 return trees;
2127 }
2226 encl.trans_local = encl.trans_local.prepend(currentClass);
2227 }
2228
2229 // Recursively translate members, taking into account that new members
2230 // might be created during the translation and prepended to the member
2231 // list `tree.defs'.
2232 List<JCTree> seen = List.nil();
2233 while (tree.defs != seen) {
2234 List<JCTree> unseen = tree.defs;
2235 for (List<JCTree> l = unseen; l.nonEmpty() && l != seen; l = l.tail) {
2236 JCTree outermostMemberDefPrev = outermostMemberDef;
2237 if (outermostMemberDefPrev == null) outermostMemberDef = l.head;
2238 l.head = translate(l.head);
2239 outermostMemberDef = outermostMemberDefPrev;
2240 }
2241 seen = unseen;
2242 }
2243
2244 // Convert a protected modifier to public, mask static modifier.
2245 if ((tree.mods.flags & PROTECTED) != 0) tree.mods.flags |= PUBLIC;
2246 tree.mods.flags &= AdjustedClassFlags;
2247
2248 // Convert name to flat representation, replacing '.' by '$'.
2249 tree.name = Convert.shortName(currentClass.flatName());
2250
2251 // Add free variables proxy definitions to class.
2252
2253 for (List<JCVariableDecl> l = fvdefs; l.nonEmpty(); l = l.tail) {
2254 tree.defs = tree.defs.prepend(l.head);
2255 enterSynthetic(tree.pos(), l.head.sym, currentClass.members());
2256 }
2257 // If this$n was accessed, add the field definition and
2258 // update initial constructors to initialize it
2259 if (currentClass.hasOuterInstance() && shouldEmitOuterThis(currentClass)) {
2260 tree.defs = tree.defs.prepend(otdef);
2261 enterSynthetic(tree.pos(), otdef.sym, currentClass.members());
2262
2263 for (JCTree def : tree.defs) {
2264 if (TreeInfo.isInitialConstructor(def)) {
2265 JCMethodDecl mdef = (JCMethodDecl) def;
2266 mdef.body.stats = mdef.body.stats.prepend(
3105 while (args.nonEmpty()) {
3106 JCExpression arg = translate(args.head, varargsElement);
3107 elems.append(arg);
3108 args = args.tail;
3109 }
3110 JCNewArray boxedArgs = make.NewArray(make.Type(varargsElement),
3111 List.nil(),
3112 elems.toList());
3113 boxedArgs.type = new ArrayType(varargsElement, syms.arrayClass);
3114 result.append(boxedArgs);
3115 } else {
3116 if (args.length() != 1) throw new AssertionError(args);
3117 JCExpression arg = translate(args.head, parameter);
3118 anyChanges |= (arg != args.head);
3119 result.append(arg);
3120 if (!anyChanges) return _args;
3121 }
3122 return result.toList();
3123 }
3124
3125 /** Apply primitive value/reference conversions as needed */
3126 @SuppressWarnings("unchecked")
3127 <T extends JCExpression> T applyPrimitiveConversionsAsNeeded(T tree, Type type) {
3128 boolean haveValue = tree.type.isPrimitiveClass();
3129 if (haveValue == type.isPrimitiveClass())
3130 return tree;
3131 // For narrowing conversion, insert a cast which should trigger a null check
3132 // For widening conversions, insert a cast if emitting a unified class file.
3133 return (T) make.TypeCast(type, tree);
3134
3135 }
3136
3137
3138
3139 /** Expand a boxing or unboxing conversion if needed. */
3140 @SuppressWarnings("unchecked") // XXX unchecked
3141 <T extends JCExpression> T boxIfNeeded(T tree, Type type) {
3142 boolean havePrimitive = tree.type.isPrimitive();
3143 if (havePrimitive == type.isPrimitive())
3144 return tree;
3145 if (havePrimitive) {
3146 Type unboxedTarget = types.unboxedType(type);
3147 if (!unboxedTarget.hasTag(NONE)) {
3148 if (!types.isSubtype(tree.type, unboxedTarget)) //e.g. Character c = 89;
3149 tree.type = unboxedTarget.constType(tree.type.constValue());
3150 return (T)boxPrimitive(tree, types.erasure(type));
3151 } else {
3152 tree = (T)boxPrimitive(tree);
3153 }
3154 } else {
3155 tree = (T)unbox(tree, type);
3156 }
3157 return tree;
3158 }
3517 * A statement of the form
3518 *
3519 * <pre>
3520 * for ( T v : coll ) stmt ;
3521 * </pre>
3522 *
3523 * (where coll implements {@code Iterable<? extends T>}) gets translated to
3524 *
3525 * <pre>{@code
3526 * for ( Iterator<? extends T> #i = coll.iterator(); #i.hasNext(); ) {
3527 * T v = (T) #i.next();
3528 * stmt;
3529 * }
3530 * }</pre>
3531 *
3532 * where #i is a freshly named synthetic local variable.
3533 */
3534 private void visitIterableForeachLoop(JCEnhancedForLoop tree) {
3535 make_at(tree.expr.pos());
3536 Type iteratorTarget = syms.objectType;
3537 Type iterableType = types.asSuper(types.cvarUpperBound(tree.expr.type.referenceProjectionOrSelf()),
3538 syms.iterableType.tsym);
3539 if (iterableType.getTypeArguments().nonEmpty())
3540 iteratorTarget = types.erasure(iterableType.getTypeArguments().head);
3541 Type eType = types.skipTypeVars(tree.expr.type, false);
3542 tree.expr.type = types.erasure(eType);
3543 if (eType.isCompound())
3544 tree.expr = make.TypeCast(types.erasure(iterableType), tree.expr);
3545 Symbol iterator = lookupMethod(tree.expr.pos(),
3546 names.iterator,
3547 eType,
3548 List.nil());
3549 VarSymbol itvar = new VarSymbol(SYNTHETIC, names.fromString("i" + target.syntheticNameChar()),
3550 types.erasure(types.asSuper(iterator.type.getReturnType().referenceProjectionOrSelf(), syms.iteratorType.tsym)),
3551 currentMethodSym);
3552
3553 JCStatement init = make.
3554 VarDef(itvar, make.App(make.Select(tree.expr, iterator)
3555 .setType(types.erasure(iterator.type))));
3556
3557 Symbol hasNext = lookupMethod(tree.expr.pos(),
3558 names.hasNext,
3559 itvar.type,
3560 List.nil());
3561 JCMethodInvocation cond = make.App(make.Select(make.Ident(itvar), hasNext));
3562 Symbol next = lookupMethod(tree.expr.pos(),
3563 names.next,
3564 itvar.type,
3565 List.nil());
3566 JCExpression vardefinit = make.App(make.Select(make.Ident(itvar), next));
3567 if (tree.var.type.isPrimitive())
3568 vardefinit = make.TypeCast(types.cvarUpperBound(iteratorTarget), vardefinit);
3569 else
3570 vardefinit = make.TypeCast(tree.var.type, vardefinit);
3607 new MethodSymbol(tree.flags | BLOCK,
3608 names.empty, null,
3609 currentClass);
3610 }
3611 super.visitBlock(tree);
3612 currentMethodSym = oldMethodSym;
3613 }
3614
3615 public void visitDoLoop(JCDoWhileLoop tree) {
3616 tree.body = translate(tree.body);
3617 tree.cond = translate(tree.cond, syms.booleanType);
3618 result = tree;
3619 }
3620
3621 public void visitWhileLoop(JCWhileLoop tree) {
3622 tree.cond = translate(tree.cond, syms.booleanType);
3623 tree.body = translate(tree.body);
3624 result = tree;
3625 }
3626
3627 public void visitWithField(JCWithField tree) {
3628 Type fieldType = tree.field.type;
3629 tree.field = translate(tree.field, tree);
3630 tree.value = translate(tree.value, fieldType); // important to use pre-translation type.
3631
3632 // If translated field is an Apply, we are
3633 // seeing an access method invocation. In this case, append
3634 // right hand side as last argument of the access method.
3635 if (tree.field.hasTag(APPLY)) {
3636 JCMethodInvocation app = (JCMethodInvocation) tree.field;
3637 app.args = List.of(tree.value).prependList(app.args);
3638 result = app;
3639 } else {
3640 result = tree;
3641 }
3642 }
3643
3644 public void visitForLoop(JCForLoop tree) {
3645 tree.init = translate(tree.init);
3646 if (tree.cond != null)
3647 tree.cond = translate(tree.cond, syms.booleanType);
3648 tree.step = translate(tree.step);
3649 tree.body = translate(tree.body);
3650 result = tree;
3651 }
3652
3653 public void visitReturn(JCReturn tree) {
3654 if (tree.expr != null)
3655 tree.expr = translate(tree.expr,
3656 types.erasure(currentMethodDef
3657 .restype.type));
3658 result = tree;
3659 }
3660
3661 public void visitSwitch(JCSwitch tree) {
3662 List<JCCase> cases = tree.patternSwitch ? addDefaultIfNeeded(tree.cases) : tree.cases;
3663 handleSwitch(tree, tree.selector, cases);
4102 tree.value = translate(tree.value, tree.target.type);
4103 result = tree;
4104 }
4105
4106 public void visitNewArray(JCNewArray tree) {
4107 tree.elemtype = translate(tree.elemtype);
4108 for (List<JCExpression> t = tree.dims; t.tail != null; t = t.tail)
4109 if (t.head != null) t.head = translate(t.head, syms.intType);
4110 tree.elems = translate(tree.elems, types.elemtype(tree.type));
4111 result = tree;
4112 }
4113
4114 public void visitSelect(JCFieldAccess tree) {
4115 // need to special case-access of the form C.super.x
4116 // these will always need an access method, unless C
4117 // is a default interface subclassed by the current class.
4118 boolean qualifiedSuperAccess =
4119 tree.selected.hasTag(SELECT) &&
4120 TreeInfo.name(tree.selected) == names._super &&
4121 !types.isDirectSuperInterface(((JCFieldAccess)tree.selected).selected.type.tsym, currentClass);
4122 /* JDK-8269956: Where a reflective (class) literal is needed, the unqualified Point.class is
4123 * always the "primary" mirror - representing the primitive reference runtime type - thereby
4124 * always matching the behavior of Object::getClass
4125 */
4126 boolean needPrimaryMirror = tree.name == names._class && tree.selected.type.isReferenceProjection();
4127 tree.selected = translate(tree.selected);
4128 if (needPrimaryMirror && tree.selected.type.isPrimitiveClass()) {
4129 tree.selected.setType(tree.selected.type.referenceProjection());
4130 }
4131 if (tree.name == names._class) {
4132 result = classOf(tree.selected);
4133 }
4134 else if (tree.name == names._super &&
4135 types.isDirectSuperInterface(tree.selected.type.tsym, currentClass)) {
4136 //default super call!! Not a classic qualified super call
4137 TypeSymbol supSym = tree.selected.type.tsym;
4138 Assert.checkNonNull(types.asSuper(currentClass.type.referenceProjectionOrSelf(), supSym));
4139 result = tree;
4140 }
4141 else if (tree.name == names._this || tree.name == names._super) {
4142 result = makeThis(tree.pos(), tree.selected.type.tsym);
4143 }
4144 else
4145 result = access(tree.sym, tree, enclOp, qualifiedSuperAccess);
4146 }
4147
4148 public void visitLetExpr(LetExpr tree) {
4149 tree.defs = translate(tree.defs);
4150 tree.expr = translate(tree.expr, tree.type);
4151 result = tree;
4152 }
4153
4154 // There ought to be nothing to rewrite here;
4155 // we don't generate code.
4156 public void visitAnnotation(JCAnnotation tree) {
4157 result = tree;
4158 }
|