< prev index next >

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

Print this page

 853 
 854     /** A list of all class symbols used for access constructor tags.
 855      */
 856     private List<ClassSymbol> accessConstrTags;
 857 
 858     /** A queue for all accessed symbols.
 859      */
 860     private ListBuffer<Symbol> accessed;
 861 
 862     /** return access code for identifier,
 863      *  @param tree     The tree representing the identifier use.
 864      *  @param enclOp   The closest enclosing operation node of tree,
 865      *                  null if tree is not a subtree of an operation.
 866      */
 867     private static int accessCode(JCTree tree, JCTree enclOp) {
 868         if (enclOp == null)
 869             return AccessCode.DEREF.code;
 870         else if (enclOp.hasTag(ASSIGN) &&
 871                  tree == TreeInfo.skipParens(((JCAssign) enclOp).lhs))
 872             return AccessCode.ASSIGN.code;



 873         else if ((enclOp.getTag().isIncOrDecUnaryOp() || enclOp.getTag().isAssignop()) &&
 874                 tree == TreeInfo.skipParens(((JCOperatorExpression) enclOp).getOperand(LEFT)))
 875             return (((JCOperatorExpression) enclOp).operator).getAccessCode(enclOp.getTag());
 876         else
 877             return AccessCode.DEREF.code;
 878     }
 879 
 880     /** Return binary operator that corresponds to given access code.
 881      */
 882     private OperatorSymbol binaryAccessOperator(int acode, Tag tag) {
 883         return operators.lookupBinaryOp(op -> op.getAccessCode(tag) == acode);
 884     }
 885 
 886     /** Return tree tag for assignment operation corresponding
 887      *  to given binary operator.
 888      */
 889     private static JCTree.Tag treeTag(OperatorSymbol operator) {
 890         switch (operator.opcode) {
 891         case ByteCodes.ior: case ByteCodes.lor:
 892             return BITOR_ASG;

 963             anum = accessed.length();
 964             accessNums.put(vsym, anum);
 965             accessSyms.put(vsym, new MethodSymbol[AccessCode.numberOfAccessCodes]);
 966             accessed.append(vsym);
 967             // System.out.println("accessing " + vsym + " in " + vsym.location());
 968         }
 969 
 970         int acode;                // The access code of the access method.
 971         List<Type> argtypes;      // The argument types of the access method.
 972         Type restype;             // The result type of the access method.
 973         List<Type> thrown;        // The thrown exceptions of the access method.
 974         switch (vsym.kind) {
 975         case VAR:
 976             acode = accessCode(tree, enclOp);
 977             if (acode >= AccessCode.FIRSTASGOP.code) {
 978                 OperatorSymbol operator = binaryAccessOperator(acode, enclOp.getTag());
 979                 if (operator.opcode == string_add)
 980                     argtypes = List.of(syms.objectType);
 981                 else
 982                     argtypes = operator.type.getParameterTypes().tail;
 983             } else if (acode == AccessCode.ASSIGN.code)
 984                 argtypes = List.of(vsym.erasure(types));
 985             else
 986                 argtypes = List.nil();
 987             restype = vsym.erasure(types);
 988             thrown = List.nil();
 989             break;
 990         case MTH:
 991             acode = AccessCode.DEREF.code;
 992             argtypes = vsym.erasure(types).getParameterTypes();
 993             restype = vsym.erasure(types).getReturnType();
 994             thrown = vsym.type.getThrownTypes();
 995             break;
 996         default:
 997             throw new AssertionError();
 998         }
 999 
1000         // For references via qualified super, increment acode by one,
1001         // making it odd.
1002         if (protAccess && refSuper) acode++;
1003 
1004         // Instance access methods get instance as first parameter.
1005         // For protected symbols this needs to be the instance as a member
1006         // of the type containing the accessed symbol, not the class
1007         // containing the access method.

1113             sym.owner.enclClass() != currentClass) {
1114             // A constant is replaced by its constant value.
1115             Object cv = ((VarSymbol)sym).getConstValue();
1116             if (cv != null) {
1117                 make.at(tree.pos);
1118                 return makeLit(sym.type, cv);
1119             }
1120             if (lambdaTranslationMap != null && lambdaTranslationMap.get(sym) != null) {
1121                 return make.at(tree.pos).Ident(lambdaTranslationMap.get(sym));
1122             } else {
1123                 // Otherwise replace the variable by its proxy.
1124                 sym = proxies.get(sym);
1125                 Assert.check(sym != null && (sym.flags_field & FINAL) != 0);
1126                 tree = make.at(tree.pos).Ident(sym);
1127             }
1128         }
1129         JCExpression base = (tree.hasTag(SELECT)) ? ((JCFieldAccess) tree).selected : null;
1130         switch (sym.kind) {
1131         case TYP:
1132             if (sym.owner.kind != PCK) {





1133                 // Convert type idents to
1134                 // <flat name> or <package name> . <flat name>
1135                 Name flatname = Convert.shortName(sym.flatName());
1136                 while (base != null &&
1137                        TreeInfo.symbol(base) != null &&
1138                        TreeInfo.symbol(base).kind != PCK) {
1139                     base = (base.hasTag(SELECT))
1140                         ? ((JCFieldAccess) base).selected
1141                         : null;
1142                 }
1143                 if (tree.hasTag(IDENT)) {
1144                     ((JCIdent) tree).name = flatname;
1145                 } else if (base == null) {
1146                     tree = make.at(tree.pos).Ident(sym);
1147                     ((JCIdent) tree).name = flatname;





1148                 } else {
1149                     ((JCFieldAccess) tree).selected = base;
1150                     ((JCFieldAccess) tree).name = flatname;





1151                 }
1152             }
1153             break;
1154         case MTH: case VAR:
1155             if (sym.owner.kind == TYP) {
1156 
1157                 // Access methods are required for
1158                 //  - private members,
1159                 //  - protected members in a superclass of an
1160                 //    enclosing class contained in another package.
1161                 //  - all non-private members accessed via a qualified super.
1162                 boolean protAccess = refSuper && !needsPrivateAccess(sym)
1163                     || needsProtectedAccess(sym, tree);
1164                 boolean accReq = protAccess || needsPrivateAccess(sym);
1165 
1166                 // A base has to be supplied for
1167                 //  - simple identifiers accessing variables in outer classes.
1168                 boolean baseReq =
1169                     base == null &&
1170                     sym.owner != syms.predefClass &&

1336             ref = make.Select(site, sym);
1337             args = make.Idents(md.params.tail);
1338         }
1339         JCStatement stat;          // The statement accessing the private symbol.
1340         if (sym.kind == VAR) {
1341             // Normalize out all odd access codes by taking floor modulo 2:
1342             int acode1 = acode - (acode & 1);
1343 
1344             JCExpression expr;      // The access method's return value.
1345             AccessCode aCode = AccessCode.getFromCode(acode1);
1346             switch (aCode) {
1347             case DEREF:
1348                 expr = ref;
1349                 break;
1350             case ASSIGN:
1351                 expr = make.Assign(ref, args.head);
1352                 break;
1353             case PREINC: case POSTINC: case PREDEC: case POSTDEC:
1354                 expr = makeUnary(aCode.tag, ref);
1355                 break;



1356             default:
1357                 expr = make.Assignop(
1358                     treeTag(binaryAccessOperator(acode1, JCTree.Tag.NO_TAG)), ref, args.head);
1359                 ((JCAssignOp) expr).operator = binaryAccessOperator(acode1, JCTree.Tag.NO_TAG);
1360             }
1361             stat = make.Return(expr.setType(sym.type));
1362         } else {
1363             stat = make.Call(make.App(ref, args));
1364         }
1365         md.body = make.Block(0, List.of(stat));
1366 
1367         // Make sure all parameters, result types and thrown exceptions
1368         // are accessible.
1369         for (List<JCVariableDecl> l = md.params; l.nonEmpty(); l = l.tail)
1370             l.head.vartype = access(l.head.vartype);
1371         md.restype = access(md.restype);
1372         for (List<JCExpression> l = md.thrown; l.nonEmpty(); l = l.tail)
1373             l.head = access(l.head);
1374 
1375         return md;
1376     }
1377 
1378     /** Construct definition of an access constructor.
1379      *  @param pos        The source code position of the definition.
1380      *  @param constr     The private constructor.
1381      *  @param accessor   The access method for the constructor.

1435      *  @param pos        The source code position of the definition.
1436      *  @param freevars   The free variables.
1437      *  @param owner      The class in which the definitions go.
1438      */
1439     List<JCVariableDecl> freevarDefs(int pos, List<VarSymbol> freevars, Symbol owner) {
1440         return freevarDefs(pos, freevars, owner, 0);
1441     }
1442 
1443     List<JCVariableDecl> freevarDefs(int pos, List<VarSymbol> freevars, Symbol owner,
1444             long additionalFlags) {
1445         long flags = FINAL | SYNTHETIC | additionalFlags;
1446         List<JCVariableDecl> defs = List.nil();
1447         Set<Name> proxyNames = new HashSet<>();
1448         for (List<VarSymbol> l = freevars; l.nonEmpty(); l = l.tail) {
1449             VarSymbol v = l.head;
1450             int index = 0;
1451             Name proxyName;
1452             do {
1453                 proxyName = proxyName(v.name, index++);
1454             } while (!proxyNames.add(proxyName));

1455             VarSymbol proxy = new VarSymbol(
1456                 flags, proxyName, v.erasure(types), owner);
1457             proxies.put(v, proxy);
1458             JCVariableDecl vd = make.at(pos).VarDef(proxy, null);
1459             vd.vartype = access(vd.vartype);
1460             defs = defs.prepend(vd);
1461         }
1462         return defs;
1463     }
1464 
1465     /** The name of a this$n field
1466      *  @param type   The class referenced by the this$n field
1467      */
1468     Name outerThisName(Type type, Symbol owner) {
1469         Type t = type.getEnclosingType();
1470         int nestingLevel = 0;
1471         while (t.hasTag(CLASS)) {
1472             t = t.getEnclosingType();
1473             nestingLevel++;
1474         }
1475         Name result = names.fromString("this" + target.syntheticNameChar() + nestingLevel);
1476         while (owner.kind == TYP && ((ClassSymbol)owner).members().findFirst(result) != null)

1499     JCVariableDecl outerThisDef(int pos, MethodSymbol owner) {
1500         ClassSymbol c = owner.enclClass();
1501         boolean isMandated =
1502             // Anonymous constructors
1503             (owner.isConstructor() && owner.isAnonymous()) ||
1504             // Constructors of non-private inner member classes
1505             (owner.isConstructor() && c.isInner() &&
1506              !c.isPrivate() && !c.isStatic());
1507         long flags =
1508             FINAL | (isMandated ? MANDATED : SYNTHETIC) | PARAMETER;
1509         VarSymbol outerThis = makeOuterThisVarSymbol(owner, flags);
1510         owner.extraParams = owner.extraParams.prepend(outerThis);
1511         return makeOuterThisVarDecl(pos, outerThis);
1512     }
1513 
1514     /** Definition for this$n field.
1515      *  @param pos        The source code position of the definition.
1516      *  @param owner      The class in which the definition goes.
1517      */
1518     JCVariableDecl outerThisDef(int pos, ClassSymbol owner) {
1519         VarSymbol outerThis = makeOuterThisVarSymbol(owner, FINAL | SYNTHETIC);


1520         return makeOuterThisVarDecl(pos, outerThis);
1521     }
1522 
1523     /** Return a list of trees that load the free variables in given list,
1524      *  in reverse order.
1525      *  @param pos          The source code position to be used for the trees.
1526      *  @param freevars     The list of free variables.
1527      */
1528     List<JCExpression> loadFreevars(DiagnosticPosition pos, List<VarSymbol> freevars) {
1529         List<JCExpression> args = List.nil();
1530         for (List<VarSymbol> l = freevars; l.nonEmpty(); l = l.tail)
1531             args = args.prepend(loadFreevar(pos, l.head));
1532         return args;
1533     }
1534 //where
1535         JCExpression loadFreevar(DiagnosticPosition pos, VarSymbol v) {
1536             return access(v, make.at(pos).Ident(v), null, false);
1537         }
1538 
1539     /** Construct a tree simulating the expression {@code C.this}.

1682         }
1683 
1684         JCStatement exceptionalRethrow = make.Throw(make.Ident(primaryException));
1685         JCBlock exceptionalCloseBlock = make.Block(0L, List.of(exceptionalCloseStatement, exceptionalRethrow));
1686         JCCatch exceptionalCatchClause = make.Catch(primaryExceptionDecl, exceptionalCloseBlock);
1687 
1688         //create the main try statement with the close:
1689         JCTry outerTry = make.Try(makeTwrBlock(resources.tail, block, depth + 1),
1690                                   List.of(exceptionalCatchClause),
1691                                   finallyClause);
1692 
1693         outerTry.finallyCanCompleteNormally = true;
1694         stats.add(outerTry);
1695 
1696         JCBlock newBlock = make.Block(0L, stats.toList());
1697         return newBlock;
1698     }
1699 
1700     private JCStatement makeResourceCloseInvocation(JCExpression resource) {
1701         // convert to AutoCloseable if needed
1702         if (types.asSuper(resource.type, syms.autoCloseableType.tsym) == null) {
1703             resource = convert(resource, syms.autoCloseableType);
1704         }
1705 
1706         // create resource.close() method invocation
1707         JCExpression resourceClose = makeCall(resource,
1708                                               names.close,
1709                                               List.nil());
1710         return make.Exec(resourceClose);
1711     }
1712 
1713     private JCExpression makeNonNullCheck(JCExpression expression) {
1714         return makeBinary(NE, expression, makeNull());
1715     }
1716 
1717     /** Construct a tree that represents the outer instance
1718      *  {@code C.this}. Never pick the current `this'.
1719      *  @param pos           The source code position to be used for the tree.
1720      *  @param c             The qualifier class.
1721      */
1722     JCExpression makeOuterThis(DiagnosticPosition pos, TypeSymbol c) {

2063     /** Visitor method: Translate a single node.
2064      *  Attach the source position from the old tree to its replacement tree.
2065      */
2066     @Override
2067     public <T extends JCTree> T translate(T tree) {
2068         if (tree == null) {
2069             return null;
2070         } else {
2071             make_at(tree.pos());
2072             T result = super.translate(tree);
2073             if (endPosTable != null && result != tree) {
2074                 endPosTable.replaceTree(tree, result);
2075             }
2076             return result;
2077         }
2078     }
2079 
2080     /** Visitor method: Translate a single node, boxing or unboxing if needed.
2081      */
2082     public <T extends JCExpression> T translate(T tree, Type type) {
2083         return (tree == null) ? null : boxIfNeeded(translate(tree), type);

2084     }
2085 
2086     /** Visitor method: Translate tree.
2087      */
2088     public <T extends JCTree> T translate(T tree, JCExpression enclOp) {
2089         JCExpression prevEnclOp = this.enclOp;
2090         this.enclOp = enclOp;
2091         T res = translate(tree);
2092         this.enclOp = prevEnclOp;
2093         return res;
2094     }
2095 
2096     /** Visitor method: Translate list of trees.
2097      */
2098     public <T extends JCExpression> List<T> translate(List<T> trees, Type type) {
2099         if (trees == null) return null;
2100         for (List<T> l = trees; l.nonEmpty(); l = l.tail)
2101             l.head = translate(l.head, type);
2102         return trees;
2103     }

2484             String concatNames = vars.stream()
2485                     .map(v -> v.name)
2486                     .collect(Collectors.joining(";", "", ""));
2487             staticArgsValues[1] = LoadableConstant.String(concatNames);
2488             int index = 2;
2489             for (MethodHandleSymbol mho : getterMethHandles) {
2490                 staticArgsValues[index] = mho;
2491                 index++;
2492             }
2493 
2494             List<Type> staticArgTypes = List.of(syms.classType,
2495                     syms.stringType,
2496                     new ArrayType(syms.methodHandleType, syms.arrayClass));
2497 
2498             JCFieldAccess qualifier = makeIndyQualifier(syms.objectMethodsType, tree, msym,
2499                     List.of(syms.methodHandleLookupType,
2500                             syms.stringType,
2501                             syms.typeDescriptorType).appendList(staticArgTypes),
2502                     staticArgsValues, bootstrapName, name, false);
2503 
2504             VarSymbol _this = new VarSymbol(SYNTHETIC, names._this, tree.sym.type, tree.sym);

2505 
2506             JCMethodInvocation proxyCall;
2507             if (!isEquals) {
2508                 proxyCall = make.Apply(List.nil(), qualifier, List.of(make.Ident(_this)));
2509             } else {
2510                 VarSymbol o = msym.params.head;
2511                 o.adr = 0;
2512                 proxyCall = make.Apply(List.nil(), qualifier, List.of(make.Ident(_this), make.Ident(o)));
2513             }
2514             proxyCall.type = qualifier.type;
2515             return make.MethodDef(msym, make.Block(0, List.of(make.Return(proxyCall))));
2516         } else {
2517             return make.Block(SYNTHETIC, List.nil());
2518         }
2519     }
2520 
2521     private String argsTypeSig(List<Type> typeList) {
2522         LowerSignatureGenerator sg = new LowerSignatureGenerator();
2523         sg.assembleSig(typeList);
2524         return sg.toString();

2568      * @param staticArgValues     the static argument values
2569      * @param bootstrapName       the bootstrap name to look for
2570      * @param argName             normally bootstraps receives a method name as second argument, if you want that name
2571      *                            to be different to that of the bootstrap name pass a different name here
2572      * @param isStatic            is it static or not
2573      * @return                    a field access tree
2574      */
2575     JCFieldAccess makeIndyQualifier(
2576             Type site,
2577             JCClassDecl tree,
2578             MethodSymbol msym,
2579             List<Type> staticArgTypes,
2580             LoadableConstant[] staticArgValues,
2581             Name bootstrapName,
2582             Name argName,
2583             boolean isStatic) {
2584         Symbol bsm = rs.resolveInternalMethod(tree.pos(), attrEnv, site,
2585                 bootstrapName, staticArgTypes, List.nil());
2586 
2587         MethodType indyType = msym.type.asMethodType();

2588         indyType = new MethodType(
2589                 isStatic ? List.nil() : indyType.argtypes.prepend(tree.sym.type),
2590                 indyType.restype,
2591                 indyType.thrown,
2592                 syms.methodClass
2593         );
2594         DynamicMethodSymbol dynSym = new DynamicMethodSymbol(argName,
2595                 syms.noSymbol,
2596                 ((MethodSymbol)bsm).asHandle(),
2597                 indyType,
2598                 staticArgValues);
2599         JCFieldAccess qualifier = make.Select(make.QualIdent(site.tsym), argName);
2600         qualifier.sym = dynSym;
2601         qualifier.type = msym.type.asMethodType().restype;
2602         return qualifier;
2603     }
2604 
2605     public void visitMethodDef(JCMethodDecl tree) {
2606         if (tree.name == names.init && (currentClass.flags_field&ENUM) != 0) {
2607             // Add "String $enum$name, int $enum$ordinal" to the beginning of the
2608             // argument list for each constructor of an enum.
2609             JCVariableDecl nameParam = make_at(tree.pos()).

2814             tree.args = tree.args.prepend(thisArg);
2815         }
2816         tree.encl = null;
2817 
2818         // If we have an anonymous class, create its flat version, rather
2819         // than the class or interface following new.
2820         if (tree.def != null) {
2821             Map<Symbol, Symbol> prevLambdaTranslationMap = lambdaTranslationMap;
2822             try {
2823                 lambdaTranslationMap = null;
2824                 translate(tree.def);
2825             } finally {
2826                 lambdaTranslationMap = prevLambdaTranslationMap;
2827             }
2828 
2829             tree.clazz = access(make_at(tree.clazz.pos()).Ident(tree.def.sym));
2830             tree.def = null;
2831         } else {
2832             tree.clazz = access(c, tree.clazz, enclOp, false);
2833         }
2834         result = tree;





2835     }
2836 
2837     // Simplify conditionals with known constant controlling expressions.
2838     // This allows us to avoid generating supporting declarations for
2839     // the dead code, which will not be eliminated during code generation.
2840     // Note that Flow.isFalse and Flow.isTrue only return true
2841     // for constant expressions in the sense of JLS 15.27, which
2842     // are guaranteed to have no side-effects.  More aggressive
2843     // constant propagation would require that we take care to
2844     // preserve possible side-effects in the condition expression.
2845 
2846     // One common case is equality expressions involving a constant and null.
2847     // Since null is not a constant expression (because null cannot be
2848     // represented in the constant pool), equality checks involving null are
2849     // not captured by Flow.isTrue/isFalse.
2850     // Equality checks involving a constant and null, e.g.
2851     //     "" == null
2852     // are safe to simplify as no side-effects can occur.
2853 
2854     private boolean isTrue(JCTree exp) {

3060             while (args.nonEmpty()) {
3061                 JCExpression arg = translate(args.head, varargsElement);
3062                 elems.append(arg);
3063                 args = args.tail;
3064             }
3065             JCNewArray boxedArgs = make.NewArray(make.Type(varargsElement),
3066                                                List.nil(),
3067                                                elems.toList());
3068             boxedArgs.type = new ArrayType(varargsElement, syms.arrayClass);
3069             result.append(boxedArgs);
3070         } else {
3071             if (args.length() != 1) throw new AssertionError(args);
3072             JCExpression arg = translate(args.head, parameter);
3073             anyChanges |= (arg != args.head);
3074             result.append(arg);
3075             if (!anyChanges) return _args;
3076         }
3077         return result.toList();
3078     }
3079 














3080     /** Expand a boxing or unboxing conversion if needed. */
3081     @SuppressWarnings("unchecked") // XXX unchecked
3082     <T extends JCExpression> T boxIfNeeded(T tree, Type type) {
3083         boolean havePrimitive = tree.type.isPrimitive();
3084         if (havePrimitive == type.isPrimitive())
3085             return tree;
3086         if (havePrimitive) {
3087             Type unboxedTarget = types.unboxedType(type);
3088             if (!unboxedTarget.hasTag(NONE)) {
3089                 if (!types.isSubtype(tree.type, unboxedTarget)) //e.g. Character c = 89;
3090                     tree.type = unboxedTarget.constType(tree.type.constValue());
3091                 return (T)boxPrimitive(tree, types.erasure(type));
3092             } else {
3093                 tree = (T)boxPrimitive(tree);
3094             }
3095         } else {
3096             tree = (T)unbox(tree, type);
3097         }
3098         return tree;
3099     }

3458          * A statement of the form
3459          *
3460          * <pre>
3461          *     for ( T v : coll ) stmt ;
3462          * </pre>
3463          *
3464          * (where coll implements {@code Iterable<? extends T>}) gets translated to
3465          *
3466          * <pre>{@code
3467          *     for ( Iterator<? extends T> #i = coll.iterator(); #i.hasNext(); ) {
3468          *         T v = (T) #i.next();
3469          *         stmt;
3470          *     }
3471          * }</pre>
3472          *
3473          * where #i is a freshly named synthetic local variable.
3474          */
3475         private void visitIterableForeachLoop(JCEnhancedForLoop tree) {
3476             make_at(tree.expr.pos());
3477             Type iteratorTarget = syms.objectType;
3478             Type iterableType = types.asSuper(types.cvarUpperBound(tree.expr.type),
3479                                               syms.iterableType.tsym);
3480             if (iterableType.getTypeArguments().nonEmpty())
3481                 iteratorTarget = types.erasure(iterableType.getTypeArguments().head);
3482             Type eType = types.skipTypeVars(tree.expr.type, false);
3483             tree.expr.type = types.erasure(eType);
3484             if (eType.isCompound())
3485                 tree.expr = make.TypeCast(types.erasure(iterableType), tree.expr);
3486             Symbol iterator = lookupMethod(tree.expr.pos(),
3487                                            names.iterator,
3488                                            eType,
3489                                            List.nil());
3490             VarSymbol itvar = new VarSymbol(SYNTHETIC, names.fromString("i" + target.syntheticNameChar()),
3491                                             types.erasure(types.asSuper(iterator.type.getReturnType(), syms.iteratorType.tsym)),
3492                                             currentMethodSym);
3493 
3494              JCStatement init = make.
3495                 VarDef(itvar, make.App(make.Select(tree.expr, iterator)
3496                      .setType(types.erasure(iterator.type))));
3497 
3498             Symbol hasNext = lookupMethod(tree.expr.pos(),
3499                                           names.hasNext,
3500                                           itvar.type,
3501                                           List.nil());
3502             JCMethodInvocation cond = make.App(make.Select(make.Ident(itvar), hasNext));
3503             Symbol next = lookupMethod(tree.expr.pos(),
3504                                        names.next,
3505                                        itvar.type,
3506                                        List.nil());
3507             JCExpression vardefinit = make.App(make.Select(make.Ident(itvar), next));
3508             if (tree.var.type.isPrimitive())
3509                 vardefinit = make.TypeCast(types.cvarUpperBound(iteratorTarget), vardefinit);
3510             else
3511                 vardefinit = make.TypeCast(tree.var.type, vardefinit);

3548                 new MethodSymbol(tree.flags | BLOCK,
3549                                  names.empty, null,
3550                                  currentClass);
3551         }
3552         super.visitBlock(tree);
3553         currentMethodSym = oldMethodSym;
3554     }
3555 
3556     public void visitDoLoop(JCDoWhileLoop tree) {
3557         tree.body = translate(tree.body);
3558         tree.cond = translate(tree.cond, syms.booleanType);
3559         result = tree;
3560     }
3561 
3562     public void visitWhileLoop(JCWhileLoop tree) {
3563         tree.cond = translate(tree.cond, syms.booleanType);
3564         tree.body = translate(tree.body);
3565         result = tree;
3566     }
3567 

















3568     public void visitForLoop(JCForLoop tree) {
3569         tree.init = translate(tree.init);
3570         if (tree.cond != null)
3571             tree.cond = translate(tree.cond, syms.booleanType);
3572         tree.step = translate(tree.step);
3573         tree.body = translate(tree.body);
3574         result = tree;
3575     }
3576 
3577     public void visitReturn(JCReturn tree) {
3578         if (tree.expr != null)
3579             tree.expr = translate(tree.expr,
3580                                   types.erasure(currentMethodDef
3581                                                 .restype.type));
3582         result = tree;
3583     }
3584 
3585     public void visitSwitch(JCSwitch tree) {
3586         List<JCCase> cases = tree.patternSwitch ? addDefaultIfNeeded(tree.cases) : tree.cases;
3587         handleSwitch(tree, tree.selector, cases);

4026         tree.value = translate(tree.value, tree.target.type);
4027         result = tree;
4028     }
4029 
4030     public void visitNewArray(JCNewArray tree) {
4031         tree.elemtype = translate(tree.elemtype);
4032         for (List<JCExpression> t = tree.dims; t.tail != null; t = t.tail)
4033             if (t.head != null) t.head = translate(t.head, syms.intType);
4034         tree.elems = translate(tree.elems, types.elemtype(tree.type));
4035         result = tree;
4036     }
4037 
4038     public void visitSelect(JCFieldAccess tree) {
4039         // need to special case-access of the form C.super.x
4040         // these will always need an access method, unless C
4041         // is a default interface subclassed by the current class.
4042         boolean qualifiedSuperAccess =
4043             tree.selected.hasTag(SELECT) &&
4044             TreeInfo.name(tree.selected) == names._super &&
4045             !types.isDirectSuperInterface(((JCFieldAccess)tree.selected).selected.type.tsym, currentClass);





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



4047         if (tree.name == names._class) {
4048             result = classOf(tree.selected);
4049         }
4050         else if (tree.name == names._super &&
4051                 types.isDirectSuperInterface(tree.selected.type.tsym, currentClass)) {
4052             //default super call!! Not a classic qualified super call
4053             TypeSymbol supSym = tree.selected.type.tsym;
4054             Assert.checkNonNull(types.asSuper(currentClass.type, supSym));
4055             result = tree;
4056         }
4057         else if (tree.name == names._this || tree.name == names._super) {
4058             result = makeThis(tree.pos(), tree.selected.type.tsym);
4059         }
4060         else
4061             result = access(tree.sym, tree, enclOp, qualifiedSuperAccess);
4062     }
4063 
4064     public void visitLetExpr(LetExpr tree) {
4065         tree.defs = translate(tree.defs);
4066         tree.expr = translate(tree.expr, tree.type);
4067         result = tree;
4068     }
4069 
4070     // There ought to be nothing to rewrite here;
4071     // we don't generate code.
4072     public void visitAnnotation(JCAnnotation tree) {
4073         result = tree;
4074     }

 853 
 854     /** A list of all class symbols used for access constructor tags.
 855      */
 856     private List<ClassSymbol> accessConstrTags;
 857 
 858     /** A queue for all accessed symbols.
 859      */
 860     private ListBuffer<Symbol> accessed;
 861 
 862     /** return access code for identifier,
 863      *  @param tree     The tree representing the identifier use.
 864      *  @param enclOp   The closest enclosing operation node of tree,
 865      *                  null if tree is not a subtree of an operation.
 866      */
 867     private static int accessCode(JCTree tree, JCTree enclOp) {
 868         if (enclOp == null)
 869             return AccessCode.DEREF.code;
 870         else if (enclOp.hasTag(ASSIGN) &&
 871                  tree == TreeInfo.skipParens(((JCAssign) enclOp).lhs))
 872             return AccessCode.ASSIGN.code;
 873         else if (enclOp.hasTag(WITHFIELD) &&
 874                 tree == TreeInfo.skipParens(((JCWithField) enclOp).field))
 875             return AccessCode.WITHFIELD.code;
 876         else if ((enclOp.getTag().isIncOrDecUnaryOp() || enclOp.getTag().isAssignop()) &&
 877                 tree == TreeInfo.skipParens(((JCOperatorExpression) enclOp).getOperand(LEFT)))
 878             return (((JCOperatorExpression) enclOp).operator).getAccessCode(enclOp.getTag());
 879         else
 880             return AccessCode.DEREF.code;
 881     }
 882 
 883     /** Return binary operator that corresponds to given access code.
 884      */
 885     private OperatorSymbol binaryAccessOperator(int acode, Tag tag) {
 886         return operators.lookupBinaryOp(op -> op.getAccessCode(tag) == acode);
 887     }
 888 
 889     /** Return tree tag for assignment operation corresponding
 890      *  to given binary operator.
 891      */
 892     private static JCTree.Tag treeTag(OperatorSymbol operator) {
 893         switch (operator.opcode) {
 894         case ByteCodes.ior: case ByteCodes.lor:
 895             return BITOR_ASG;

 966             anum = accessed.length();
 967             accessNums.put(vsym, anum);
 968             accessSyms.put(vsym, new MethodSymbol[AccessCode.numberOfAccessCodes]);
 969             accessed.append(vsym);
 970             // System.out.println("accessing " + vsym + " in " + vsym.location());
 971         }
 972 
 973         int acode;                // The access code of the access method.
 974         List<Type> argtypes;      // The argument types of the access method.
 975         Type restype;             // The result type of the access method.
 976         List<Type> thrown;        // The thrown exceptions of the access method.
 977         switch (vsym.kind) {
 978         case VAR:
 979             acode = accessCode(tree, enclOp);
 980             if (acode >= AccessCode.FIRSTASGOP.code) {
 981                 OperatorSymbol operator = binaryAccessOperator(acode, enclOp.getTag());
 982                 if (operator.opcode == string_add)
 983                     argtypes = List.of(syms.objectType);
 984                 else
 985                     argtypes = operator.type.getParameterTypes().tail;
 986             } else if (acode == AccessCode.ASSIGN.code || acode == AccessCode.WITHFIELD.code)
 987                 argtypes = List.of(vsym.erasure(types));
 988             else
 989                 argtypes = List.nil();
 990             restype = acode == AccessCode.WITHFIELD.code ? vsym.owner.erasure(types) : vsym.erasure(types);
 991             thrown = List.nil();
 992             break;
 993         case MTH:
 994             acode = AccessCode.DEREF.code;
 995             argtypes = vsym.erasure(types).getParameterTypes();
 996             restype = vsym.erasure(types).getReturnType();
 997             thrown = vsym.type.getThrownTypes();
 998             break;
 999         default:
1000             throw new AssertionError();
1001         }
1002 
1003         // For references via qualified super, increment acode by one,
1004         // making it odd.
1005         if (protAccess && refSuper) acode++;
1006 
1007         // Instance access methods get instance as first parameter.
1008         // For protected symbols this needs to be the instance as a member
1009         // of the type containing the accessed symbol, not the class
1010         // containing the access method.

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

1354             ref = make.Select(site, sym);
1355             args = make.Idents(md.params.tail);
1356         }
1357         JCStatement stat;          // The statement accessing the private symbol.
1358         if (sym.kind == VAR) {
1359             // Normalize out all odd access codes by taking floor modulo 2:
1360             int acode1 = acode - (acode & 1);
1361 
1362             JCExpression expr;      // The access method's return value.
1363             AccessCode aCode = AccessCode.getFromCode(acode1);
1364             switch (aCode) {
1365             case DEREF:
1366                 expr = ref;
1367                 break;
1368             case ASSIGN:
1369                 expr = make.Assign(ref, args.head);
1370                 break;
1371             case PREINC: case POSTINC: case PREDEC: case POSTDEC:
1372                 expr = makeUnary(aCode.tag, ref);
1373                 break;
1374             case WITHFIELD:
1375                 expr = make.WithField(ref, args.head);
1376                 break;
1377             default:
1378                 expr = make.Assignop(
1379                     treeTag(binaryAccessOperator(acode1, JCTree.Tag.NO_TAG)), ref, args.head);
1380                 ((JCAssignOp) expr).operator = binaryAccessOperator(acode1, JCTree.Tag.NO_TAG);
1381             }
1382             stat = make.Return(expr.setType(aCode == AccessCode.WITHFIELD ? sym.owner.type : sym.type));
1383         } else {
1384             stat = make.Call(make.App(ref, args));
1385         }
1386         md.body = make.Block(0, List.of(stat));
1387 
1388         // Make sure all parameters, result types and thrown exceptions
1389         // are accessible.
1390         for (List<JCVariableDecl> l = md.params; l.nonEmpty(); l = l.tail)
1391             l.head.vartype = access(l.head.vartype);
1392         md.restype = access(md.restype);
1393         for (List<JCExpression> l = md.thrown; l.nonEmpty(); l = l.tail)
1394             l.head = access(l.head);
1395 
1396         return md;
1397     }
1398 
1399     /** Construct definition of an access constructor.
1400      *  @param pos        The source code position of the definition.
1401      *  @param constr     The private constructor.
1402      *  @param accessor   The access method for the constructor.

1456      *  @param pos        The source code position of the definition.
1457      *  @param freevars   The free variables.
1458      *  @param owner      The class in which the definitions go.
1459      */
1460     List<JCVariableDecl> freevarDefs(int pos, List<VarSymbol> freevars, Symbol owner) {
1461         return freevarDefs(pos, freevars, owner, 0);
1462     }
1463 
1464     List<JCVariableDecl> freevarDefs(int pos, List<VarSymbol> freevars, Symbol owner,
1465             long additionalFlags) {
1466         long flags = FINAL | SYNTHETIC | additionalFlags;
1467         List<JCVariableDecl> defs = List.nil();
1468         Set<Name> proxyNames = new HashSet<>();
1469         for (List<VarSymbol> l = freevars; l.nonEmpty(); l = l.tail) {
1470             VarSymbol v = l.head;
1471             int index = 0;
1472             Name proxyName;
1473             do {
1474                 proxyName = proxyName(v.name, index++);
1475             } while (!proxyNames.add(proxyName));
1476             final Type type = v.erasure(types);
1477             VarSymbol proxy = new VarSymbol(
1478                 flags, proxyName, type, owner);
1479             proxies.put(v, proxy);
1480             JCVariableDecl vd = make.at(pos).VarDef(proxy, null);
1481             vd.vartype = access(vd.vartype);
1482             defs = defs.prepend(vd);
1483         }
1484         return defs;
1485     }
1486 
1487     /** The name of a this$n field
1488      *  @param type   The class referenced by the this$n field
1489      */
1490     Name outerThisName(Type type, Symbol owner) {
1491         Type t = type.getEnclosingType();
1492         int nestingLevel = 0;
1493         while (t.hasTag(CLASS)) {
1494             t = t.getEnclosingType();
1495             nestingLevel++;
1496         }
1497         Name result = names.fromString("this" + target.syntheticNameChar() + nestingLevel);
1498         while (owner.kind == TYP && ((ClassSymbol)owner).members().findFirst(result) != null)

1521     JCVariableDecl outerThisDef(int pos, MethodSymbol owner) {
1522         ClassSymbol c = owner.enclClass();
1523         boolean isMandated =
1524             // Anonymous constructors
1525             (owner.isConstructor() && owner.isAnonymous()) ||
1526             // Constructors of non-private inner member classes
1527             (owner.isConstructor() && c.isInner() &&
1528              !c.isPrivate() && !c.isStatic());
1529         long flags =
1530             FINAL | (isMandated ? MANDATED : SYNTHETIC) | PARAMETER;
1531         VarSymbol outerThis = makeOuterThisVarSymbol(owner, flags);
1532         owner.extraParams = owner.extraParams.prepend(outerThis);
1533         return makeOuterThisVarDecl(pos, outerThis);
1534     }
1535 
1536     /** Definition for this$n field.
1537      *  @param pos        The source code position of the definition.
1538      *  @param owner      The class in which the definition goes.
1539      */
1540     JCVariableDecl outerThisDef(int pos, ClassSymbol owner) {
1541         Type target = types.erasure(owner.enclClass().type.getEnclosingType());
1542         long flags = FINAL | SYNTHETIC;
1543         VarSymbol outerThis = makeOuterThisVarSymbol(owner, flags);
1544         return makeOuterThisVarDecl(pos, outerThis);
1545     }
1546 
1547     /** Return a list of trees that load the free variables in given list,
1548      *  in reverse order.
1549      *  @param pos          The source code position to be used for the trees.
1550      *  @param freevars     The list of free variables.
1551      */
1552     List<JCExpression> loadFreevars(DiagnosticPosition pos, List<VarSymbol> freevars) {
1553         List<JCExpression> args = List.nil();
1554         for (List<VarSymbol> l = freevars; l.nonEmpty(); l = l.tail)
1555             args = args.prepend(loadFreevar(pos, l.head));
1556         return args;
1557     }
1558 //where
1559         JCExpression loadFreevar(DiagnosticPosition pos, VarSymbol v) {
1560             return access(v, make.at(pos).Ident(v), null, false);
1561         }
1562 
1563     /** Construct a tree simulating the expression {@code C.this}.

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

2087     /** Visitor method: Translate a single node.
2088      *  Attach the source position from the old tree to its replacement tree.
2089      */
2090     @Override
2091     public <T extends JCTree> T translate(T tree) {
2092         if (tree == null) {
2093             return null;
2094         } else {
2095             make_at(tree.pos());
2096             T result = super.translate(tree);
2097             if (endPosTable != null && result != tree) {
2098                 endPosTable.replaceTree(tree, result);
2099             }
2100             return result;
2101         }
2102     }
2103 
2104     /** Visitor method: Translate a single node, boxing or unboxing if needed.
2105      */
2106     public <T extends JCExpression> T translate(T tree, Type type) {
2107         return (tree == null) ? null :
2108                 applyPrimitiveConversionsAsNeeded(boxIfNeeded(translate(tree), type), type);
2109     }
2110 
2111     /** Visitor method: Translate tree.
2112      */
2113     public <T extends JCTree> T translate(T tree, JCExpression enclOp) {
2114         JCExpression prevEnclOp = this.enclOp;
2115         this.enclOp = enclOp;
2116         T res = translate(tree);
2117         this.enclOp = prevEnclOp;
2118         return res;
2119     }
2120 
2121     /** Visitor method: Translate list of trees.
2122      */
2123     public <T extends JCExpression> List<T> translate(List<T> trees, Type type) {
2124         if (trees == null) return null;
2125         for (List<T> l = trees; l.nonEmpty(); l = l.tail)
2126             l.head = translate(l.head, type);
2127         return trees;
2128     }

2509             String concatNames = vars.stream()
2510                     .map(v -> v.name)
2511                     .collect(Collectors.joining(";", "", ""));
2512             staticArgsValues[1] = LoadableConstant.String(concatNames);
2513             int index = 2;
2514             for (MethodHandleSymbol mho : getterMethHandles) {
2515                 staticArgsValues[index] = mho;
2516                 index++;
2517             }
2518 
2519             List<Type> staticArgTypes = List.of(syms.classType,
2520                     syms.stringType,
2521                     new ArrayType(syms.methodHandleType, syms.arrayClass));
2522 
2523             JCFieldAccess qualifier = makeIndyQualifier(syms.objectMethodsType, tree, msym,
2524                     List.of(syms.methodHandleLookupType,
2525                             syms.stringType,
2526                             syms.typeDescriptorType).appendList(staticArgTypes),
2527                     staticArgsValues, bootstrapName, name, false);
2528 
2529             Type receiverType = tree.sym.type.isPrimitiveReferenceType() ? tree.sym.type.asValueType() : tree.sym.type;
2530             VarSymbol _this = new VarSymbol(SYNTHETIC, names._this, receiverType, tree.sym);
2531 
2532             JCMethodInvocation proxyCall;
2533             if (!isEquals) {
2534                 proxyCall = make.Apply(List.nil(), qualifier, List.of(make.Ident(_this)));
2535             } else {
2536                 VarSymbol o = msym.params.head;
2537                 o.adr = 0;
2538                 proxyCall = make.Apply(List.nil(), qualifier, List.of(make.Ident(_this), make.Ident(o)));
2539             }
2540             proxyCall.type = qualifier.type;
2541             return make.MethodDef(msym, make.Block(0, List.of(make.Return(proxyCall))));
2542         } else {
2543             return make.Block(SYNTHETIC, List.nil());
2544         }
2545     }
2546 
2547     private String argsTypeSig(List<Type> typeList) {
2548         LowerSignatureGenerator sg = new LowerSignatureGenerator();
2549         sg.assembleSig(typeList);
2550         return sg.toString();

2594      * @param staticArgValues     the static argument values
2595      * @param bootstrapName       the bootstrap name to look for
2596      * @param argName             normally bootstraps receives a method name as second argument, if you want that name
2597      *                            to be different to that of the bootstrap name pass a different name here
2598      * @param isStatic            is it static or not
2599      * @return                    a field access tree
2600      */
2601     JCFieldAccess makeIndyQualifier(
2602             Type site,
2603             JCClassDecl tree,
2604             MethodSymbol msym,
2605             List<Type> staticArgTypes,
2606             LoadableConstant[] staticArgValues,
2607             Name bootstrapName,
2608             Name argName,
2609             boolean isStatic) {
2610         Symbol bsm = rs.resolveInternalMethod(tree.pos(), attrEnv, site,
2611                 bootstrapName, staticArgTypes, List.nil());
2612 
2613         MethodType indyType = msym.type.asMethodType();
2614         Type receiverType = tree.sym.type.isPrimitiveReferenceType() ? tree.sym.type.asValueType() : tree.sym.type;
2615         indyType = new MethodType(
2616                 isStatic ? List.nil() : indyType.argtypes.prepend(receiverType),
2617                 indyType.restype,
2618                 indyType.thrown,
2619                 syms.methodClass
2620         );
2621         DynamicMethodSymbol dynSym = new DynamicMethodSymbol(argName,
2622                 syms.noSymbol,
2623                 ((MethodSymbol)bsm).asHandle(),
2624                 indyType,
2625                 staticArgValues);
2626         JCFieldAccess qualifier = make.Select(make.QualIdent(site.tsym), argName);
2627         qualifier.sym = dynSym;
2628         qualifier.type = msym.type.asMethodType().restype;
2629         return qualifier;
2630     }
2631 
2632     public void visitMethodDef(JCMethodDecl tree) {
2633         if (tree.name == names.init && (currentClass.flags_field&ENUM) != 0) {
2634             // Add "String $enum$name, int $enum$ordinal" to the beginning of the
2635             // argument list for each constructor of an enum.
2636             JCVariableDecl nameParam = make_at(tree.pos()).

2841             tree.args = tree.args.prepend(thisArg);
2842         }
2843         tree.encl = null;
2844 
2845         // If we have an anonymous class, create its flat version, rather
2846         // than the class or interface following new.
2847         if (tree.def != null) {
2848             Map<Symbol, Symbol> prevLambdaTranslationMap = lambdaTranslationMap;
2849             try {
2850                 lambdaTranslationMap = null;
2851                 translate(tree.def);
2852             } finally {
2853                 lambdaTranslationMap = prevLambdaTranslationMap;
2854             }
2855 
2856             tree.clazz = access(make_at(tree.clazz.pos()).Ident(tree.def.sym));
2857             tree.def = null;
2858         } else {
2859             tree.clazz = access(c, tree.clazz, enclOp, false);
2860         }
2861         if (tree.clazz.type.tsym == syms.objectType.tsym) {
2862             Assert.check(tree.def == null && tree.encl == null);
2863             result = makeCall(make.Ident(syms.objectsType.tsym), names.newIdentity, List.nil());
2864         } else {
2865             result = tree;
2866         }
2867     }
2868 
2869     // Simplify conditionals with known constant controlling expressions.
2870     // This allows us to avoid generating supporting declarations for
2871     // the dead code, which will not be eliminated during code generation.
2872     // Note that Flow.isFalse and Flow.isTrue only return true
2873     // for constant expressions in the sense of JLS 15.27, which
2874     // are guaranteed to have no side-effects.  More aggressive
2875     // constant propagation would require that we take care to
2876     // preserve possible side-effects in the condition expression.
2877 
2878     // One common case is equality expressions involving a constant and null.
2879     // Since null is not a constant expression (because null cannot be
2880     // represented in the constant pool), equality checks involving null are
2881     // not captured by Flow.isTrue/isFalse.
2882     // Equality checks involving a constant and null, e.g.
2883     //     "" == null
2884     // are safe to simplify as no side-effects can occur.
2885 
2886     private boolean isTrue(JCTree exp) {

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     /** Apply primitive value/reference conversions as needed */
3113     @SuppressWarnings("unchecked")
3114     <T extends JCExpression> T applyPrimitiveConversionsAsNeeded(T tree, Type type) {
3115         boolean haveValue = tree.type.isPrimitiveClass();
3116         if (haveValue == type.isPrimitiveClass())
3117             return tree;
3118         // For narrowing conversion, insert a cast which should trigger a null check
3119         // For widening conversions, insert a cast if emitting a unified class file.
3120         return (T) make.TypeCast(type, tree);
3121 
3122     }
3123 
3124 
3125 
3126     /** Expand a boxing or unboxing conversion if needed. */
3127     @SuppressWarnings("unchecked") // XXX unchecked
3128     <T extends JCExpression> T boxIfNeeded(T tree, Type type) {
3129         boolean havePrimitive = tree.type.isPrimitive();
3130         if (havePrimitive == type.isPrimitive())
3131             return tree;
3132         if (havePrimitive) {
3133             Type unboxedTarget = types.unboxedType(type);
3134             if (!unboxedTarget.hasTag(NONE)) {
3135                 if (!types.isSubtype(tree.type, unboxedTarget)) //e.g. Character c = 89;
3136                     tree.type = unboxedTarget.constType(tree.type.constValue());
3137                 return (T)boxPrimitive(tree, types.erasure(type));
3138             } else {
3139                 tree = (T)boxPrimitive(tree);
3140             }
3141         } else {
3142             tree = (T)unbox(tree, type);
3143         }
3144         return tree;
3145     }

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

3594                 new MethodSymbol(tree.flags | BLOCK,
3595                                  names.empty, null,
3596                                  currentClass);
3597         }
3598         super.visitBlock(tree);
3599         currentMethodSym = oldMethodSym;
3600     }
3601 
3602     public void visitDoLoop(JCDoWhileLoop tree) {
3603         tree.body = translate(tree.body);
3604         tree.cond = translate(tree.cond, syms.booleanType);
3605         result = tree;
3606     }
3607 
3608     public void visitWhileLoop(JCWhileLoop tree) {
3609         tree.cond = translate(tree.cond, syms.booleanType);
3610         tree.body = translate(tree.body);
3611         result = tree;
3612     }
3613 
3614     public void visitWithField(JCWithField tree) {
3615         Type fieldType = tree.field.type;
3616         tree.field = translate(tree.field, tree);
3617         tree.value = translate(tree.value, fieldType); // important to use pre-translation type.
3618 
3619         // If translated field is an Apply, we are
3620         // seeing an access method invocation. In this case, append
3621         // right hand side as last argument of the access method.
3622         if (tree.field.hasTag(APPLY)) {
3623             JCMethodInvocation app = (JCMethodInvocation) tree.field;
3624             app.args = List.of(tree.value).prependList(app.args);
3625             result = app;
3626         } else {
3627             result = tree;
3628         }
3629     }
3630 
3631     public void visitForLoop(JCForLoop tree) {
3632         tree.init = translate(tree.init);
3633         if (tree.cond != null)
3634             tree.cond = translate(tree.cond, syms.booleanType);
3635         tree.step = translate(tree.step);
3636         tree.body = translate(tree.body);
3637         result = tree;
3638     }
3639 
3640     public void visitReturn(JCReturn tree) {
3641         if (tree.expr != null)
3642             tree.expr = translate(tree.expr,
3643                                   types.erasure(currentMethodDef
3644                                                 .restype.type));
3645         result = tree;
3646     }
3647 
3648     public void visitSwitch(JCSwitch tree) {
3649         List<JCCase> cases = tree.patternSwitch ? addDefaultIfNeeded(tree.cases) : tree.cases;
3650         handleSwitch(tree, tree.selector, cases);

4089         tree.value = translate(tree.value, tree.target.type);
4090         result = tree;
4091     }
4092 
4093     public void visitNewArray(JCNewArray tree) {
4094         tree.elemtype = translate(tree.elemtype);
4095         for (List<JCExpression> t = tree.dims; t.tail != null; t = t.tail)
4096             if (t.head != null) t.head = translate(t.head, syms.intType);
4097         tree.elems = translate(tree.elems, types.elemtype(tree.type));
4098         result = tree;
4099     }
4100 
4101     public void visitSelect(JCFieldAccess tree) {
4102         // need to special case-access of the form C.super.x
4103         // these will always need an access method, unless C
4104         // is a default interface subclassed by the current class.
4105         boolean qualifiedSuperAccess =
4106             tree.selected.hasTag(SELECT) &&
4107             TreeInfo.name(tree.selected) == names._super &&
4108             !types.isDirectSuperInterface(((JCFieldAccess)tree.selected).selected.type.tsym, currentClass);
4109         /* JDK-8269956: Where a reflective (class) literal is needed, the unqualified Point.class is
4110          * always the "primary" mirror - representing the primitive reference runtime type - thereby
4111          * always matching the behavior of Object::getClass
4112          */
4113         boolean needPrimaryMirror = tree.name == names._class && tree.selected.type.isPrimitiveReferenceType();
4114         tree.selected = translate(tree.selected);
4115         if (needPrimaryMirror && tree.selected.type.isPrimitiveClass()) {
4116             tree.selected.setType(tree.selected.type.referenceProjection());
4117         }
4118         if (tree.name == names._class) {
4119             result = classOf(tree.selected);
4120         }
4121         else if (tree.name == names._super &&
4122                 types.isDirectSuperInterface(tree.selected.type.tsym, currentClass)) {
4123             //default super call!! Not a classic qualified super call
4124             TypeSymbol supSym = tree.selected.type.tsym;
4125             Assert.checkNonNull(types.asSuper(currentClass.type.referenceProjectionOrSelf(), supSym));
4126             result = tree;
4127         }
4128         else if (tree.name == names._this || tree.name == names._super) {
4129             result = makeThis(tree.pos(), tree.selected.type.tsym);
4130         }
4131         else
4132             result = access(tree.sym, tree, enclOp, qualifiedSuperAccess);
4133     }
4134 
4135     public void visitLetExpr(LetExpr tree) {
4136         tree.defs = translate(tree.defs);
4137         tree.expr = translate(tree.expr, tree.type);
4138         result = tree;
4139     }
4140 
4141     // There ought to be nothing to rewrite here;
4142     // we don't generate code.
4143     public void visitAnnotation(JCAnnotation tree) {
4144         result = tree;
4145     }
< prev index next >