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

changeset 1127
ca49d50318dc
parent 1086
f595d8bc0599
child 1138
7375d4979bd3
equal deleted inserted replaced
1126:11c184155128 1127:ca49d50318dc
40 import com.sun.tools.javac.code.Type.*; 40 import com.sun.tools.javac.code.Type.*;
41 41
42 import com.sun.tools.javac.jvm.Target; 42 import com.sun.tools.javac.jvm.Target;
43 43
44 import static com.sun.tools.javac.code.Flags.*; 44 import static com.sun.tools.javac.code.Flags.*;
45 import static com.sun.tools.javac.code.Flags.BLOCK;
45 import static com.sun.tools.javac.code.Kinds.*; 46 import static com.sun.tools.javac.code.Kinds.*;
46 import static com.sun.tools.javac.code.TypeTags.*; 47 import static com.sun.tools.javac.code.TypeTags.*;
47 import static com.sun.tools.javac.jvm.ByteCodes.*; 48 import static com.sun.tools.javac.jvm.ByteCodes.*;
49 import static com.sun.tools.javac.tree.JCTree.Tag.*;
48 50
49 /** This pass translates away some syntactic sugar: inner classes, 51 /** This pass translates away some syntactic sugar: inner classes,
50 * class literals, assertions, foreach loops, etc. 52 * class literals, assertions, foreach loops, etc.
51 * 53 *
52 * <p><b>This is NOT part of any supported API. 54 * <p><b>This is NOT part of any supported API.
301 if (TreeInfo.name(tree.meth) == names._super) { 303 if (TreeInfo.name(tree.meth) == names._super) {
302 addFreeVars((ClassSymbol) TreeInfo.symbol(tree.meth).owner); 304 addFreeVars((ClassSymbol) TreeInfo.symbol(tree.meth).owner);
303 Symbol constructor = TreeInfo.symbol(tree.meth); 305 Symbol constructor = TreeInfo.symbol(tree.meth);
304 ClassSymbol c = (ClassSymbol)constructor.owner; 306 ClassSymbol c = (ClassSymbol)constructor.owner;
305 if (c.hasOuterInstance() && 307 if (c.hasOuterInstance() &&
306 tree.meth.getTag() != JCTree.SELECT && 308 !tree.meth.hasTag(SELECT) &&
307 outerThisStack.head != null) 309 outerThisStack.head != null)
308 visitSymbol(outerThisStack.head); 310 visitSymbol(outerThisStack.head);
309 } 311 }
310 super.visitApply(tree); 312 super.visitApply(tree);
311 } 313 }
506 508
507 /** Make an attributed unary expression. 509 /** Make an attributed unary expression.
508 * @param optag The operators tree tag. 510 * @param optag The operators tree tag.
509 * @param arg The operator's argument. 511 * @param arg The operator's argument.
510 */ 512 */
511 JCUnary makeUnary(int optag, JCExpression arg) { 513 JCUnary makeUnary(JCTree.Tag optag, JCExpression arg) {
512 JCUnary tree = make.Unary(optag, arg); 514 JCUnary tree = make.Unary(optag, arg);
513 tree.operator = rs.resolveUnaryOperator( 515 tree.operator = rs.resolveUnaryOperator(
514 make_pos, optag, attrEnv, arg.type); 516 make_pos, optag, attrEnv, arg.type);
515 tree.type = tree.operator.type.getReturnType(); 517 tree.type = tree.operator.type.getReturnType();
516 return tree; 518 return tree;
519 /** Make an attributed binary expression. 521 /** Make an attributed binary expression.
520 * @param optag The operators tree tag. 522 * @param optag The operators tree tag.
521 * @param lhs The operator's left argument. 523 * @param lhs The operator's left argument.
522 * @param rhs The operator's right argument. 524 * @param rhs The operator's right argument.
523 */ 525 */
524 JCBinary makeBinary(int optag, JCExpression lhs, JCExpression rhs) { 526 JCBinary makeBinary(JCTree.Tag optag, JCExpression lhs, JCExpression rhs) {
525 JCBinary tree = make.Binary(optag, lhs, rhs); 527 JCBinary tree = make.Binary(optag, lhs, rhs);
526 tree.operator = rs.resolveBinaryOperator( 528 tree.operator = rs.resolveBinaryOperator(
527 make_pos, optag, attrEnv, lhs.type, rhs.type); 529 make_pos, optag, attrEnv, lhs.type, rhs.type);
528 tree.type = tree.operator.type.getReturnType(); 530 tree.type = tree.operator.type.getReturnType();
529 return tree; 531 return tree;
532 /** Make an attributed assignop expression. 534 /** Make an attributed assignop expression.
533 * @param optag The operators tree tag. 535 * @param optag The operators tree tag.
534 * @param lhs The operator's left argument. 536 * @param lhs The operator's left argument.
535 * @param rhs The operator's right argument. 537 * @param rhs The operator's right argument.
536 */ 538 */
537 JCAssignOp makeAssignop(int optag, JCTree lhs, JCTree rhs) { 539 JCAssignOp makeAssignop(JCTree.Tag optag, JCTree lhs, JCTree rhs) {
538 JCAssignOp tree = make.Assignop(optag, lhs, rhs); 540 JCAssignOp tree = make.Assignop(optag, lhs, rhs);
539 tree.operator = rs.resolveBinaryOperator( 541 tree.operator = rs.resolveBinaryOperator(
540 make_pos, tree.getTag() - JCTree.ASGOffset, attrEnv, lhs.type, rhs.type); 542 make_pos, tree.getTag().noAssignOp(), attrEnv, lhs.type, rhs.type);
541 tree.type = lhs.type; 543 tree.type = lhs.type;
542 return tree; 544 return tree;
543 } 545 }
544 546
545 /** Convert tree into string object, unless it has already a 547 /** Convert tree into string object, unless it has already a
718 } 720 }
719 } 721 }
720 // where 722 // where
721 private boolean isTranslatedClassAvailable(ClassSymbol c) { 723 private boolean isTranslatedClassAvailable(ClassSymbol c) {
722 for (JCTree tree: translated) { 724 for (JCTree tree: translated) {
723 if (tree.getTag() == JCTree.CLASSDEF 725 if (tree.hasTag(CLASSDEF)
724 && ((JCClassDecl) tree).sym == c) { 726 && ((JCClassDecl) tree).sym == c) {
725 return true; 727 return true;
726 } 728 }
727 } 729 }
728 return false; 730 return false;
800 * null if tree is not a subtree of an operation. 802 * null if tree is not a subtree of an operation.
801 */ 803 */
802 private static int accessCode(JCTree tree, JCTree enclOp) { 804 private static int accessCode(JCTree tree, JCTree enclOp) {
803 if (enclOp == null) 805 if (enclOp == null)
804 return DEREFcode; 806 return DEREFcode;
805 else if (enclOp.getTag() == JCTree.ASSIGN && 807 else if (enclOp.hasTag(ASSIGN) &&
806 tree == TreeInfo.skipParens(((JCAssign) enclOp).lhs)) 808 tree == TreeInfo.skipParens(((JCAssign) enclOp).lhs))
807 return ASSIGNcode; 809 return ASSIGNcode;
808 else if (JCTree.PREINC <= enclOp.getTag() && enclOp.getTag() <= JCTree.POSTDEC && 810 else if (enclOp.getTag().isIncOrDecUnaryOp() &&
809 tree == TreeInfo.skipParens(((JCUnary) enclOp).arg)) 811 tree == TreeInfo.skipParens(((JCUnary) enclOp).arg))
810 return (enclOp.getTag() - JCTree.PREINC) * 2 + PREINCcode; 812 return mapTagToUnaryOpCode(enclOp.getTag());
811 else if (JCTree.BITOR_ASG <= enclOp.getTag() && enclOp.getTag() <= JCTree.MOD_ASG && 813 else if (enclOp.getTag().isAssignop() &&
812 tree == TreeInfo.skipParens(((JCAssignOp) enclOp).lhs)) 814 tree == TreeInfo.skipParens(((JCAssignOp) enclOp).lhs))
813 return accessCode(((OperatorSymbol) ((JCAssignOp) enclOp).operator).opcode); 815 return accessCode(((OperatorSymbol) ((JCAssignOp) enclOp).operator).opcode);
814 else 816 else
815 return DEREFcode; 817 return DEREFcode;
816 } 818 }
830 } 832 }
831 833
832 /** Return tree tag for assignment operation corresponding 834 /** Return tree tag for assignment operation corresponding
833 * to given binary operator. 835 * to given binary operator.
834 */ 836 */
835 private static int treeTag(OperatorSymbol operator) { 837 private static JCTree.Tag treeTag(OperatorSymbol operator) {
836 switch (operator.opcode) { 838 switch (operator.opcode) {
837 case ByteCodes.ior: case ByteCodes.lor: 839 case ByteCodes.ior: case ByteCodes.lor:
838 return JCTree.BITOR_ASG; 840 return BITOR_ASG;
839 case ByteCodes.ixor: case ByteCodes.lxor: 841 case ByteCodes.ixor: case ByteCodes.lxor:
840 return JCTree.BITXOR_ASG; 842 return BITXOR_ASG;
841 case ByteCodes.iand: case ByteCodes.land: 843 case ByteCodes.iand: case ByteCodes.land:
842 return JCTree.BITAND_ASG; 844 return BITAND_ASG;
843 case ByteCodes.ishl: case ByteCodes.lshl: 845 case ByteCodes.ishl: case ByteCodes.lshl:
844 case ByteCodes.ishll: case ByteCodes.lshll: 846 case ByteCodes.ishll: case ByteCodes.lshll:
845 return JCTree.SL_ASG; 847 return SL_ASG;
846 case ByteCodes.ishr: case ByteCodes.lshr: 848 case ByteCodes.ishr: case ByteCodes.lshr:
847 case ByteCodes.ishrl: case ByteCodes.lshrl: 849 case ByteCodes.ishrl: case ByteCodes.lshrl:
848 return JCTree.SR_ASG; 850 return SR_ASG;
849 case ByteCodes.iushr: case ByteCodes.lushr: 851 case ByteCodes.iushr: case ByteCodes.lushr:
850 case ByteCodes.iushrl: case ByteCodes.lushrl: 852 case ByteCodes.iushrl: case ByteCodes.lushrl:
851 return JCTree.USR_ASG; 853 return USR_ASG;
852 case ByteCodes.iadd: case ByteCodes.ladd: 854 case ByteCodes.iadd: case ByteCodes.ladd:
853 case ByteCodes.fadd: case ByteCodes.dadd: 855 case ByteCodes.fadd: case ByteCodes.dadd:
854 case ByteCodes.string_add: 856 case ByteCodes.string_add:
855 return JCTree.PLUS_ASG; 857 return PLUS_ASG;
856 case ByteCodes.isub: case ByteCodes.lsub: 858 case ByteCodes.isub: case ByteCodes.lsub:
857 case ByteCodes.fsub: case ByteCodes.dsub: 859 case ByteCodes.fsub: case ByteCodes.dsub:
858 return JCTree.MINUS_ASG; 860 return MINUS_ASG;
859 case ByteCodes.imul: case ByteCodes.lmul: 861 case ByteCodes.imul: case ByteCodes.lmul:
860 case ByteCodes.fmul: case ByteCodes.dmul: 862 case ByteCodes.fmul: case ByteCodes.dmul:
861 return JCTree.MUL_ASG; 863 return MUL_ASG;
862 case ByteCodes.idiv: case ByteCodes.ldiv: 864 case ByteCodes.idiv: case ByteCodes.ldiv:
863 case ByteCodes.fdiv: case ByteCodes.ddiv: 865 case ByteCodes.fdiv: case ByteCodes.ddiv:
864 return JCTree.DIV_ASG; 866 return DIV_ASG;
865 case ByteCodes.imod: case ByteCodes.lmod: 867 case ByteCodes.imod: case ByteCodes.lmod:
866 case ByteCodes.fmod: case ByteCodes.dmod: 868 case ByteCodes.fmod: case ByteCodes.dmod:
867 return JCTree.MOD_ASG; 869 return MOD_ASG;
868 default: 870 default:
869 throw new AssertionError(); 871 throw new AssertionError();
870 } 872 }
871 } 873 }
872 874
1001 sym.packge() == currentClass.packge()) 1003 sym.packge() == currentClass.packge())
1002 return false; 1004 return false;
1003 if (!currentClass.isSubClass(sym.owner, types)) 1005 if (!currentClass.isSubClass(sym.owner, types))
1004 return true; 1006 return true;
1005 if ((sym.flags() & STATIC) != 0 || 1007 if ((sym.flags() & STATIC) != 0 ||
1006 tree.getTag() != JCTree.SELECT || 1008 !tree.hasTag(SELECT) ||
1007 TreeInfo.name(((JCFieldAccess) tree).selected) == names._super) 1009 TreeInfo.name(((JCFieldAccess) tree).selected) == names._super)
1008 return false; 1010 return false;
1009 return !((JCFieldAccess) tree).selected.type.tsym.isSubClass(currentClass, types); 1011 return !((JCFieldAccess) tree).selected.type.tsym.isSubClass(currentClass, types);
1010 } 1012 }
1011 1013
1016 */ 1018 */
1017 ClassSymbol accessClass(Symbol sym, boolean protAccess, JCTree tree) { 1019 ClassSymbol accessClass(Symbol sym, boolean protAccess, JCTree tree) {
1018 if (protAccess) { 1020 if (protAccess) {
1019 Symbol qualifier = null; 1021 Symbol qualifier = null;
1020 ClassSymbol c = currentClass; 1022 ClassSymbol c = currentClass;
1021 if (tree.getTag() == JCTree.SELECT && (sym.flags() & STATIC) == 0) { 1023 if (tree.hasTag(SELECT) && (sym.flags() & STATIC) == 0) {
1022 qualifier = ((JCFieldAccess) tree).selected.type.tsym; 1024 qualifier = ((JCFieldAccess) tree).selected.type.tsym;
1023 while (!qualifier.isSubClass(c, types)) { 1025 while (!qualifier.isSubClass(c, types)) {
1024 c = c.owner.enclClass(); 1026 c = c.owner.enclClass();
1025 } 1027 }
1026 return c; 1028 return c;
1056 // Otherwise replace the variable by its proxy. 1058 // Otherwise replace the variable by its proxy.
1057 sym = proxies.lookup(proxyName(sym.name)).sym; 1059 sym = proxies.lookup(proxyName(sym.name)).sym;
1058 Assert.check(sym != null && (sym.flags_field & FINAL) != 0); 1060 Assert.check(sym != null && (sym.flags_field & FINAL) != 0);
1059 tree = make.at(tree.pos).Ident(sym); 1061 tree = make.at(tree.pos).Ident(sym);
1060 } 1062 }
1061 JCExpression base = (tree.getTag() == JCTree.SELECT) ? ((JCFieldAccess) tree).selected : null; 1063 JCExpression base = (tree.hasTag(SELECT)) ? ((JCFieldAccess) tree).selected : null;
1062 switch (sym.kind) { 1064 switch (sym.kind) {
1063 case TYP: 1065 case TYP:
1064 if (sym.owner.kind != PCK) { 1066 if (sym.owner.kind != PCK) {
1065 // Convert type idents to 1067 // Convert type idents to
1066 // <flat name> or <package name> . <flat name> 1068 // <flat name> or <package name> . <flat name>
1067 Name flatname = Convert.shortName(sym.flatName()); 1069 Name flatname = Convert.shortName(sym.flatName());
1068 while (base != null && 1070 while (base != null &&
1069 TreeInfo.symbol(base) != null && 1071 TreeInfo.symbol(base) != null &&
1070 TreeInfo.symbol(base).kind != PCK) { 1072 TreeInfo.symbol(base).kind != PCK) {
1071 base = (base.getTag() == JCTree.SELECT) 1073 base = (base.hasTag(SELECT))
1072 ? ((JCFieldAccess) base).selected 1074 ? ((JCFieldAccess) base).selected
1073 : null; 1075 : null;
1074 } 1076 }
1075 if (tree.getTag() == JCTree.IDENT) { 1077 if (tree.hasTag(IDENT)) {
1076 ((JCIdent) tree).name = flatname; 1078 ((JCIdent) tree).name = flatname;
1077 } else if (base == null) { 1079 } else if (base == null) {
1078 tree = make.at(tree.pos).Ident(sym); 1080 tree = make.at(tree.pos).Ident(sym);
1079 ((JCIdent) tree).name = flatname; 1081 ((JCIdent) tree).name = flatname;
1080 } else { 1082 } else {
1218 accessDef(cdef.pos, sym, accessors[i], i)); 1220 accessDef(cdef.pos, sym, accessors[i], i));
1219 } 1221 }
1220 } 1222 }
1221 } 1223 }
1222 1224
1225 /** Maps unary operator integer codes to JCTree.Tag objects
1226 * @param unaryOpCode the unary operator code
1227 */
1228 private static Tag mapUnaryOpCodeToTag(int unaryOpCode){
1229 switch (unaryOpCode){
1230 case PREINCcode:
1231 return PREINC;
1232 case PREDECcode:
1233 return PREDEC;
1234 case POSTINCcode:
1235 return POSTINC;
1236 case POSTDECcode:
1237 return POSTDEC;
1238 default:
1239 return NO_TAG;
1240 }
1241 }
1242
1243 /** Maps JCTree.Tag objects to unary operator integer codes
1244 * @param tag the JCTree.Tag
1245 */
1246 private static int mapTagToUnaryOpCode(Tag tag){
1247 switch (tag){
1248 case PREINC:
1249 return PREINCcode;
1250 case PREDEC:
1251 return PREDECcode;
1252 case POSTINC:
1253 return POSTINCcode;
1254 case POSTDEC:
1255 return POSTDECcode;
1256 default:
1257 return -1;
1258 }
1259 }
1260
1223 /** Construct definition of an access method. 1261 /** Construct definition of an access method.
1224 * @param pos The source code position of the definition. 1262 * @param pos The source code position of the definition.
1225 * @param vsym The private or protected symbol. 1263 * @param vsym The private or protected symbol.
1226 * @param accessor The access method for the symbol. 1264 * @param accessor The access method for the symbol.
1227 * @param acode The access code. 1265 * @param acode The access code.
1257 break; 1295 break;
1258 case ASSIGNcode: 1296 case ASSIGNcode:
1259 expr = make.Assign(ref, args.head); 1297 expr = make.Assign(ref, args.head);
1260 break; 1298 break;
1261 case PREINCcode: case POSTINCcode: case PREDECcode: case POSTDECcode: 1299 case PREINCcode: case POSTINCcode: case PREDECcode: case POSTDECcode:
1262 expr = makeUnary( 1300 expr = makeUnary(mapUnaryOpCodeToTag(acode1), ref);
1263 ((acode1 - PREINCcode) >> 1) + JCTree.PREINC, ref);
1264 break; 1301 break;
1265 default: 1302 default:
1266 expr = make.Assignop( 1303 expr = make.Assignop(
1267 treeTag(binaryAccessOperator(acode1)), ref, args.head); 1304 treeTag(binaryAccessOperator(acode1)), ref, args.head);
1268 ((JCAssignOp) expr).operator = binaryAccessOperator(acode1); 1305 ((JCAssignOp) expr).operator = binaryAccessOperator(acode1);
1574 List.<JCExpression>nil()); 1611 List.<JCExpression>nil());
1575 return make.Exec(resourceClose); 1612 return make.Exec(resourceClose);
1576 } 1613 }
1577 1614
1578 private JCExpression makeNonNullCheck(JCExpression expression) { 1615 private JCExpression makeNonNullCheck(JCExpression expression) {
1579 return makeBinary(JCTree.NE, expression, makeNull()); 1616 return makeBinary(NE, expression, makeNull());
1580 } 1617 }
1581 1618
1582 /** Construct a tree that represents the outer instance 1619 /** Construct a tree that represents the outer instance
1583 * <C.this>. Never pick the current `this'. 1620 * <C.this>. Never pick the current `this'.
1584 * @param pos The source code position to be used for the tree. 1621 * @param pos The source code position to be used for the tree.
1806 syms.classLoaderType)); 1843 syms.classLoaderType));
1807 // clvalue := "(cl$ == null) ? 1844 // clvalue := "(cl$ == null) ?
1808 // $newcache.getClass().getComponentType().getClassLoader() : cl$" 1845 // $newcache.getClass().getComponentType().getClassLoader() : cl$"
1809 JCExpression clvalue = 1846 JCExpression clvalue =
1810 make.Conditional( 1847 make.Conditional(
1811 makeBinary(JCTree.EQ, make.Ident(clsym), makeNull()), 1848 makeBinary(EQ, make.Ident(clsym), makeNull()),
1812 make.Assign( 1849 make.Assign(
1813 make.Ident(clsym), 1850 make.Ident(clsym),
1814 makeCall( 1851 makeCall(
1815 makeCall(makeCall(newcache, 1852 makeCall(makeCall(newcache,
1816 names.getClass, 1853 names.getClass,
1974 // - <cache> is the cache variable for tsig. 2011 // - <cache> is the cache variable for tsig.
1975 String sig = 2012 String sig =
1976 writer.xClassName(type).toString().replace('/', '.'); 2013 writer.xClassName(type).toString().replace('/', '.');
1977 Symbol cs = cacheSym(pos, sig); 2014 Symbol cs = cacheSym(pos, sig);
1978 return make_at(pos).Conditional( 2015 return make_at(pos).Conditional(
1979 makeBinary(JCTree.EQ, make.Ident(cs), makeNull()), 2016 makeBinary(EQ, make.Ident(cs), makeNull()),
1980 make.Assign( 2017 make.Assign(
1981 make.Ident(cs), 2018 make.Ident(cs),
1982 make.App( 2019 make.App(
1983 make.Ident(classDollarSym(pos)), 2020 make.Ident(classDollarSym(pos)),
1984 List.<JCExpression>of(make.Literal(CLASS, sig) 2021 List.<JCExpression>of(make.Literal(CLASS, sig)
2021 names.desiredAssertionStatus, 2058 names.desiredAssertionStatus,
2022 types.erasure(syms.classType), 2059 types.erasure(syms.classType),
2023 List.<Type>nil()); 2060 List.<Type>nil());
2024 JCClassDecl containerDef = classDef(container); 2061 JCClassDecl containerDef = classDef(container);
2025 make_at(containerDef.pos()); 2062 make_at(containerDef.pos());
2026 JCExpression notStatus = makeUnary(JCTree.NOT, make.App(make.Select( 2063 JCExpression notStatus = makeUnary(NOT, make.App(make.Select(
2027 classOfType(types.erasure(outermostClass.type), 2064 classOfType(types.erasure(outermostClass.type),
2028 containerDef.pos()), 2065 containerDef.pos()),
2029 desiredAssertionStatusSym))); 2066 desiredAssertionStatusSym)));
2030 JCVariableDecl assertDisabledDef = make.VarDef(assertDisabledSym, 2067 JCVariableDecl assertDisabledDef = make.VarDef(assertDisabledSym,
2031 notStatus); 2068 notStatus);
2032 containerDef.defs = containerDef.defs.prepend(assertDisabledDef); 2069 containerDef.defs = containerDef.defs.prepend(assertDisabledDef);
2033 } 2070 }
2034 make_at(pos); 2071 make_at(pos);
2035 return makeUnary(JCTree.NOT, make.Ident(assertDisabledSym)); 2072 return makeUnary(NOT, make.Ident(assertDisabledSym));
2036 } 2073 }
2037 2074
2038 2075
2039 /************************************************************************** 2076 /**************************************************************************
2040 * Building blocks for let expressions 2077 * Building blocks for let expressions
2060 * in the let expression. 2097 * in the let expression.
2061 */ 2098 */
2062 JCTree abstractRval(JCTree rval, Type type, TreeBuilder builder) { 2099 JCTree abstractRval(JCTree rval, Type type, TreeBuilder builder) {
2063 rval = TreeInfo.skipParens(rval); 2100 rval = TreeInfo.skipParens(rval);
2064 switch (rval.getTag()) { 2101 switch (rval.getTag()) {
2065 case JCTree.LITERAL: 2102 case LITERAL:
2066 return builder.build(rval); 2103 return builder.build(rval);
2067 case JCTree.IDENT: 2104 case IDENT:
2068 JCIdent id = (JCIdent) rval; 2105 JCIdent id = (JCIdent) rval;
2069 if ((id.sym.flags() & FINAL) != 0 && id.sym.owner.kind == MTH) 2106 if ((id.sym.flags() & FINAL) != 0 && id.sym.owner.kind == MTH)
2070 return builder.build(rval); 2107 return builder.build(rval);
2071 } 2108 }
2072 VarSymbol var = 2109 VarSymbol var =
2095 // select in a temporary, and for Indexed expressions, where we 2132 // select in a temporary, and for Indexed expressions, where we
2096 // place both the indexed expression and the index value in temps. 2133 // place both the indexed expression and the index value in temps.
2097 JCTree abstractLval(JCTree lval, final TreeBuilder builder) { 2134 JCTree abstractLval(JCTree lval, final TreeBuilder builder) {
2098 lval = TreeInfo.skipParens(lval); 2135 lval = TreeInfo.skipParens(lval);
2099 switch (lval.getTag()) { 2136 switch (lval.getTag()) {
2100 case JCTree.IDENT: 2137 case IDENT:
2101 return builder.build(lval); 2138 return builder.build(lval);
2102 case JCTree.SELECT: { 2139 case SELECT: {
2103 final JCFieldAccess s = (JCFieldAccess)lval; 2140 final JCFieldAccess s = (JCFieldAccess)lval;
2104 JCTree selected = TreeInfo.skipParens(s.selected); 2141 JCTree selected = TreeInfo.skipParens(s.selected);
2105 Symbol lid = TreeInfo.symbol(s.selected); 2142 Symbol lid = TreeInfo.symbol(s.selected);
2106 if (lid != null && lid.kind == TYP) return builder.build(lval); 2143 if (lid != null && lid.kind == TYP) return builder.build(lval);
2107 return abstractRval(s.selected, new TreeBuilder() { 2144 return abstractRval(s.selected, new TreeBuilder() {
2108 public JCTree build(final JCTree selected) { 2145 public JCTree build(final JCTree selected) {
2109 return builder.build(make.Select((JCExpression)selected, s.sym)); 2146 return builder.build(make.Select((JCExpression)selected, s.sym));
2110 } 2147 }
2111 }); 2148 });
2112 } 2149 }
2113 case JCTree.INDEXED: { 2150 case INDEXED: {
2114 final JCArrayAccess i = (JCArrayAccess)lval; 2151 final JCArrayAccess i = (JCArrayAccess)lval;
2115 return abstractRval(i.indexed, new TreeBuilder() { 2152 return abstractRval(i.indexed, new TreeBuilder() {
2116 public JCTree build(final JCTree indexed) { 2153 public JCTree build(final JCTree indexed) {
2117 return abstractRval(i.index, syms.intType, new TreeBuilder() { 2154 return abstractRval(i.index, syms.intType, new TreeBuilder() {
2118 public JCTree build(final JCTree index) { 2155 public JCTree build(final JCTree index) {
2123 } 2160 }
2124 }); 2161 });
2125 } 2162 }
2126 }); 2163 });
2127 } 2164 }
2128 case JCTree.TYPECAST: { 2165 case TYPECAST: {
2129 return abstractLval(((JCTypeCast)lval).expr, builder); 2166 return abstractLval(((JCTypeCast)lval).expr, builder);
2130 } 2167 }
2131 } 2168 }
2132 throw new AssertionError(lval); 2169 throw new AssertionError(lval);
2133 } 2170 }
2343 ListBuffer<JCTree> enumDefs = new ListBuffer<JCTree>(); 2380 ListBuffer<JCTree> enumDefs = new ListBuffer<JCTree>();
2344 ListBuffer<JCTree> otherDefs = new ListBuffer<JCTree>(); 2381 ListBuffer<JCTree> otherDefs = new ListBuffer<JCTree>();
2345 for (List<JCTree> defs = tree.defs; 2382 for (List<JCTree> defs = tree.defs;
2346 defs.nonEmpty(); 2383 defs.nonEmpty();
2347 defs=defs.tail) { 2384 defs=defs.tail) {
2348 if (defs.head.getTag() == JCTree.VARDEF && (((JCVariableDecl) defs.head).mods.flags & ENUM) != 0) { 2385 if (defs.head.hasTag(VARDEF) && (((JCVariableDecl) defs.head).mods.flags & ENUM) != 0) {
2349 JCVariableDecl var = (JCVariableDecl)defs.head; 2386 JCVariableDecl var = (JCVariableDecl)defs.head;
2350 visitEnumConstantDef(var, nextOrdinal++); 2387 visitEnumConstantDef(var, nextOrdinal++);
2351 values.append(make.QualIdent(var.sym)); 2388 values.append(make.QualIdent(var.sym));
2352 enumDefs.append(var); 2389 enumDefs.append(var);
2353 } else { 2390 } else {
2755 JCExpression cond = assertFlagTest(tree.pos()); 2792 JCExpression cond = assertFlagTest(tree.pos());
2756 List<JCExpression> exnArgs = (tree.detail == null) ? 2793 List<JCExpression> exnArgs = (tree.detail == null) ?
2757 List.<JCExpression>nil() : List.of(translate(tree.detail)); 2794 List.<JCExpression>nil() : List.of(translate(tree.detail));
2758 if (!tree.cond.type.isFalse()) { 2795 if (!tree.cond.type.isFalse()) {
2759 cond = makeBinary 2796 cond = makeBinary
2760 (JCTree.AND, 2797 (AND,
2761 cond, 2798 cond,
2762 makeUnary(JCTree.NOT, tree.cond)); 2799 makeUnary(NOT, tree.cond));
2763 } 2800 }
2764 result = 2801 result =
2765 make.If(cond, 2802 make.If(cond,
2766 make_at(detailPos). 2803 make_at(detailPos).
2767 Throw(makeNewClass(syms.assertionErrorType, exnArgs)), 2804 Throw(makeNewClass(syms.assertionErrorType, exnArgs)),
2814 // the explicit constructor arguments. If the call 2851 // the explicit constructor arguments. If the call
2815 // is not qualified, pass the correct outer instance as 2852 // is not qualified, pass the correct outer instance as
2816 // first argument. 2853 // first argument.
2817 if (c.hasOuterInstance()) { 2854 if (c.hasOuterInstance()) {
2818 JCExpression thisArg; 2855 JCExpression thisArg;
2819 if (tree.meth.getTag() == JCTree.SELECT) { 2856 if (tree.meth.hasTag(SELECT)) {
2820 thisArg = attr. 2857 thisArg = attr.
2821 makeNullCheck(translate(((JCFieldAccess) tree.meth).selected)); 2858 makeNullCheck(translate(((JCFieldAccess) tree.meth).selected));
2822 tree.meth = make.Ident(constructor); 2859 tree.meth = make.Ident(constructor);
2823 ((JCIdent) tree.meth).name = methName; 2860 ((JCIdent) tree.meth).name = methName;
2824 } else if ((c.owner.kind & (MTH | VAR)) != 0 || methName == names._this){ 2861 } else if ((c.owner.kind & (MTH | VAR)) != 0 || methName == names._this){
2835 tree.meth = translate(tree.meth); 2872 tree.meth = translate(tree.meth);
2836 2873
2837 // If the translated method itself is an Apply tree, we are 2874 // If the translated method itself is an Apply tree, we are
2838 // seeing an access method invocation. In this case, append 2875 // seeing an access method invocation. In this case, append
2839 // the method arguments to the arguments of the access method. 2876 // the method arguments to the arguments of the access method.
2840 if (tree.meth.getTag() == JCTree.APPLY) { 2877 if (tree.meth.hasTag(APPLY)) {
2841 JCMethodInvocation app = (JCMethodInvocation)tree.meth; 2878 JCMethodInvocation app = (JCMethodInvocation)tree.meth;
2842 app.args = tree.args.prependList(app.args); 2879 app.args = tree.args.prependList(app.args);
2843 result = app; 2880 result = app;
2844 return; 2881 return;
2845 } 2882 }
2969 tree.rhs = translate(tree.rhs, tree.lhs.type); 3006 tree.rhs = translate(tree.rhs, tree.lhs.type);
2970 3007
2971 // If translated left hand side is an Apply, we are 3008 // If translated left hand side is an Apply, we are
2972 // seeing an access method invocation. In this case, append 3009 // seeing an access method invocation. In this case, append
2973 // right hand side as last argument of the access method. 3010 // right hand side as last argument of the access method.
2974 if (tree.lhs.getTag() == JCTree.APPLY) { 3011 if (tree.lhs.hasTag(APPLY)) {
2975 JCMethodInvocation app = (JCMethodInvocation)tree.lhs; 3012 JCMethodInvocation app = (JCMethodInvocation)tree.lhs;
2976 app.args = List.of(tree.rhs).prependList(app.args); 3013 app.args = List.of(tree.rhs).prependList(app.args);
2977 result = app; 3014 result = app;
2978 } else { 3015 } else {
2979 result = tree; 3016 result = tree;
2986 // boxing required; need to rewrite as x = (unbox typeof x)(x op y); 3023 // boxing required; need to rewrite as x = (unbox typeof x)(x op y);
2987 // or if x == (typeof x)z then z = (unbox typeof x)((typeof x)z op y) 3024 // or if x == (typeof x)z then z = (unbox typeof x)((typeof x)z op y)
2988 // (but without recomputing x) 3025 // (but without recomputing x)
2989 JCTree newTree = abstractLval(tree.lhs, new TreeBuilder() { 3026 JCTree newTree = abstractLval(tree.lhs, new TreeBuilder() {
2990 public JCTree build(final JCTree lhs) { 3027 public JCTree build(final JCTree lhs) {
2991 int newTag = tree.getTag() - JCTree.ASGOffset; 3028 JCTree.Tag newTag = tree.getTag().noAssignOp();
2992 // Erasure (TransTypes) can change the type of 3029 // Erasure (TransTypes) can change the type of
2993 // tree.lhs. However, we can still get the 3030 // tree.lhs. However, we can still get the
2994 // unerased type of tree.lhs as it is stored 3031 // unerased type of tree.lhs as it is stored
2995 // in tree.type in Attr. 3032 // in tree.type in Attr.
2996 Symbol newOperator = rs.resolveBinaryOperator(tree.pos(), 3033 Symbol newOperator = rs.resolveBinaryOperator(tree.pos(),
3016 tree.rhs = translate(tree.rhs, tree.operator.type.getParameterTypes().tail.head); 3053 tree.rhs = translate(tree.rhs, tree.operator.type.getParameterTypes().tail.head);
3017 3054
3018 // If translated left hand side is an Apply, we are 3055 // If translated left hand side is an Apply, we are
3019 // seeing an access method invocation. In this case, append 3056 // seeing an access method invocation. In this case, append
3020 // right hand side as last argument of the access method. 3057 // right hand side as last argument of the access method.
3021 if (tree.lhs.getTag() == JCTree.APPLY) { 3058 if (tree.lhs.hasTag(APPLY)) {
3022 JCMethodInvocation app = (JCMethodInvocation)tree.lhs; 3059 JCMethodInvocation app = (JCMethodInvocation)tree.lhs;
3023 // if operation is a += on strings, 3060 // if operation is a += on strings,
3024 // make sure to convert argument to string 3061 // make sure to convert argument to string
3025 JCExpression rhs = (((OperatorSymbol)tree.operator).opcode == string_add) 3062 JCExpression rhs = (((OperatorSymbol)tree.operator).opcode == string_add)
3026 ? makeString(tree.rhs) 3063 ? makeString(tree.rhs)
3036 JCTree lowerBoxedPostop(final JCUnary tree) { 3073 JCTree lowerBoxedPostop(final JCUnary tree) {
3037 // translate to tmp1=lval(e); tmp2=tmp1; tmp1 OP 1; tmp2 3074 // translate to tmp1=lval(e); tmp2=tmp1; tmp1 OP 1; tmp2
3038 // or 3075 // or
3039 // translate to tmp1=lval(e); tmp2=tmp1; (typeof tree)tmp1 OP 1; tmp2 3076 // translate to tmp1=lval(e); tmp2=tmp1; (typeof tree)tmp1 OP 1; tmp2
3040 // where OP is += or -= 3077 // where OP is += or -=
3041 final boolean cast = TreeInfo.skipParens(tree.arg).getTag() == JCTree.TYPECAST; 3078 final boolean cast = TreeInfo.skipParens(tree.arg).hasTag(TYPECAST);
3042 return abstractLval(tree.arg, new TreeBuilder() { 3079 return abstractLval(tree.arg, new TreeBuilder() {
3043 public JCTree build(final JCTree tmp1) { 3080 public JCTree build(final JCTree tmp1) {
3044 return abstractRval(tmp1, tree.arg.type, new TreeBuilder() { 3081 return abstractRval(tmp1, tree.arg.type, new TreeBuilder() {
3045 public JCTree build(final JCTree tmp2) { 3082 public JCTree build(final JCTree tmp2) {
3046 int opcode = (tree.getTag() == JCTree.POSTINC) 3083 JCTree.Tag opcode = (tree.hasTag(POSTINC))
3047 ? JCTree.PLUS_ASG : JCTree.MINUS_ASG; 3084 ? PLUS_ASG : MINUS_ASG;
3048 JCTree lhs = cast 3085 JCTree lhs = cast
3049 ? make.TypeCast(tree.arg.type, (JCExpression)tmp1) 3086 ? make.TypeCast(tree.arg.type, (JCExpression)tmp1)
3050 : tmp1; 3087 : tmp1;
3051 JCTree update = makeAssignop(opcode, 3088 JCTree update = makeAssignop(opcode,
3052 lhs, 3089 lhs,
3057 } 3094 }
3058 }); 3095 });
3059 } 3096 }
3060 3097
3061 public void visitUnary(JCUnary tree) { 3098 public void visitUnary(JCUnary tree) {
3062 boolean isUpdateOperator = 3099 boolean isUpdateOperator = tree.getTag().isIncOrDecUnaryOp();
3063 JCTree.PREINC <= tree.getTag() && tree.getTag() <= JCTree.POSTDEC;
3064 if (isUpdateOperator && !tree.arg.type.isPrimitive()) { 3100 if (isUpdateOperator && !tree.arg.type.isPrimitive()) {
3065 switch(tree.getTag()) { 3101 switch(tree.getTag()) {
3066 case JCTree.PREINC: // ++ e 3102 case PREINC: // ++ e
3067 // translate to e += 1 3103 // translate to e += 1
3068 case JCTree.PREDEC: // -- e 3104 case PREDEC: // -- e
3069 // translate to e -= 1 3105 // translate to e -= 1
3070 { 3106 {
3071 int opcode = (tree.getTag() == JCTree.PREINC) 3107 JCTree.Tag opcode = (tree.hasTag(PREINC))
3072 ? JCTree.PLUS_ASG : JCTree.MINUS_ASG; 3108 ? PLUS_ASG : MINUS_ASG;
3073 JCAssignOp newTree = makeAssignop(opcode, 3109 JCAssignOp newTree = makeAssignop(opcode,
3074 tree.arg, 3110 tree.arg,
3075 make.Literal(1)); 3111 make.Literal(1));
3076 result = translate(newTree, tree.type); 3112 result = translate(newTree, tree.type);
3077 return; 3113 return;
3078 } 3114 }
3079 case JCTree.POSTINC: // e ++ 3115 case POSTINC: // e ++
3080 case JCTree.POSTDEC: // e -- 3116 case POSTDEC: // e --
3081 { 3117 {
3082 result = translate(lowerBoxedPostop(tree), tree.type); 3118 result = translate(lowerBoxedPostop(tree), tree.type);
3083 return; 3119 return;
3084 } 3120 }
3085 } 3121 }
3086 throw new AssertionError(tree); 3122 throw new AssertionError(tree);
3087 } 3123 }
3088 3124
3089 tree.arg = boxIfNeeded(translate(tree.arg, tree), tree.type); 3125 tree.arg = boxIfNeeded(translate(tree.arg, tree), tree.type);
3090 3126
3091 if (tree.getTag() == JCTree.NOT && tree.arg.type.constValue() != null) { 3127 if (tree.hasTag(NOT) && tree.arg.type.constValue() != null) {
3092 tree.type = cfolder.fold1(bool_not, tree.arg.type); 3128 tree.type = cfolder.fold1(bool_not, tree.arg.type);
3093 } 3129 }
3094 3130
3095 // If translated left hand side is an Apply, we are 3131 // If translated left hand side is an Apply, we are
3096 // seeing an access method invocation. In this case, return 3132 // seeing an access method invocation. In this case, return
3097 // that access method invocation as result. 3133 // that access method invocation as result.
3098 if (isUpdateOperator && tree.arg.getTag() == JCTree.APPLY) { 3134 if (isUpdateOperator && tree.arg.hasTag(APPLY)) {
3099 result = tree.arg; 3135 result = tree.arg;
3100 } else { 3136 } else {
3101 result = tree; 3137 result = tree;
3102 } 3138 }
3103 } 3139 }
3104 3140
3105 public void visitBinary(JCBinary tree) { 3141 public void visitBinary(JCBinary tree) {
3106 List<Type> formals = tree.operator.type.getParameterTypes(); 3142 List<Type> formals = tree.operator.type.getParameterTypes();
3107 JCTree lhs = tree.lhs = translate(tree.lhs, formals.head); 3143 JCTree lhs = tree.lhs = translate(tree.lhs, formals.head);
3108 switch (tree.getTag()) { 3144 switch (tree.getTag()) {
3109 case JCTree.OR: 3145 case OR:
3110 if (lhs.type.isTrue()) { 3146 if (lhs.type.isTrue()) {
3111 result = lhs; 3147 result = lhs;
3112 return; 3148 return;
3113 } 3149 }
3114 if (lhs.type.isFalse()) { 3150 if (lhs.type.isFalse()) {
3115 result = translate(tree.rhs, formals.tail.head); 3151 result = translate(tree.rhs, formals.tail.head);
3116 return; 3152 return;
3117 } 3153 }
3118 break; 3154 break;
3119 case JCTree.AND: 3155 case AND:
3120 if (lhs.type.isFalse()) { 3156 if (lhs.type.isFalse()) {
3121 result = lhs; 3157 result = lhs;
3122 return; 3158 return;
3123 } 3159 }
3124 if (lhs.type.isTrue()) { 3160 if (lhs.type.isTrue()) {
3184 3220
3185 JCVariableDecl indexdef = make.VarDef(index, make.Literal(INT, 0)); 3221 JCVariableDecl indexdef = make.VarDef(index, make.Literal(INT, 0));
3186 indexdef.init.type = indexdef.type = syms.intType.constType(0); 3222 indexdef.init.type = indexdef.type = syms.intType.constType(0);
3187 3223
3188 List<JCStatement> loopinit = List.of(arraycachedef, lencachedef, indexdef); 3224 List<JCStatement> loopinit = List.of(arraycachedef, lencachedef, indexdef);
3189 JCBinary cond = makeBinary(JCTree.LT, make.Ident(index), make.Ident(lencache)); 3225 JCBinary cond = makeBinary(LT, make.Ident(index), make.Ident(lencache));
3190 3226
3191 JCExpressionStatement step = make.Exec(makeUnary(JCTree.PREINC, make.Ident(index))); 3227 JCExpressionStatement step = make.Exec(makeUnary(PREINC, make.Ident(index)));
3192 3228
3193 Type elemtype = types.elemtype(tree.expr.type); 3229 Type elemtype = types.elemtype(tree.expr.type);
3194 JCExpression loopvarinit = make.Indexed(make.Ident(arraycache), 3230 JCExpression loopvarinit = make.Indexed(make.Ident(arraycache),
3195 make.Ident(index)).setType(elemtype); 3231 make.Ident(index)).setType(elemtype);
3196 JCVariableDecl loopvardef = (JCVariableDecl)make.VarDef(tree.var.mods, 3232 JCVariableDecl loopvardef = (JCVariableDecl)make.VarDef(tree.var.mods,
3590 3626
3591 public void visitSelect(JCFieldAccess tree) { 3627 public void visitSelect(JCFieldAccess tree) {
3592 // need to special case-access of the form C.super.x 3628 // need to special case-access of the form C.super.x
3593 // these will always need an access method. 3629 // these will always need an access method.
3594 boolean qualifiedSuperAccess = 3630 boolean qualifiedSuperAccess =
3595 tree.selected.getTag() == JCTree.SELECT && 3631 tree.selected.hasTag(SELECT) &&
3596 TreeInfo.name(tree.selected) == names._super; 3632 TreeInfo.name(tree.selected) == names._super;
3597 tree.selected = translate(tree.selected); 3633 tree.selected = translate(tree.selected);
3598 if (tree.name == names._class) 3634 if (tree.name == names._class)
3599 result = classOf(tree.selected); 3635 result = classOf(tree.selected);
3600 else if (tree.name == names._this || tree.name == names._super) 3636 else if (tree.name == names._this || tree.name == names._super)
3640 attrEnv = env; 3676 attrEnv = env;
3641 this.make = make; 3677 this.make = make;
3642 endPositions = env.toplevel.endPositions; 3678 endPositions = env.toplevel.endPositions;
3643 currentClass = null; 3679 currentClass = null;
3644 currentMethodDef = null; 3680 currentMethodDef = null;
3645 outermostClassDef = (cdef.getTag() == JCTree.CLASSDEF) ? (JCClassDecl)cdef : null; 3681 outermostClassDef = (cdef.hasTag(CLASSDEF)) ? (JCClassDecl)cdef : null;
3646 outermostMemberDef = null; 3682 outermostMemberDef = null;
3647 this.translated = new ListBuffer<JCTree>(); 3683 this.translated = new ListBuffer<JCTree>();
3648 classdefs = new HashMap<ClassSymbol,JCClassDecl>(); 3684 classdefs = new HashMap<ClassSymbol,JCClassDecl>();
3649 actualSymbols = new HashMap<Symbol,Symbol>(); 3685 actualSymbols = new HashMap<Symbol,Symbol>();
3650 freevarCache = new HashMap<ClassSymbol,List<VarSymbol>>(); 3686 freevarCache = new HashMap<ClassSymbol,List<VarSymbol>>();
3836 3872
3837 JCIdent id1 = make.Ident(ordinalSymbol); 3873 JCIdent id1 = make.Ident(ordinalSymbol);
3838 3874
3839 JCIdent fLocUsageId = make.Ident(otherVarSym); 3875 JCIdent fLocUsageId = make.Ident(otherVarSym);
3840 JCExpression sel = make.Select(fLocUsageId, ordinalSymbol); 3876 JCExpression sel = make.Select(fLocUsageId, ordinalSymbol);
3841 JCBinary bin = makeBinary(JCTree.MINUS, id1, sel); 3877 JCBinary bin = makeBinary(MINUS, id1, sel);
3842 JCReturn ret = make.Return(bin); 3878 JCReturn ret = make.Return(bin);
3843 blockStatements.append(ret); 3879 blockStatements.append(ret);
3844 JCMethodDecl compareToMethod = make.MethodDef((MethodSymbol)compareToSym, 3880 JCMethodDecl compareToMethod = make.MethodDef((MethodSymbol)compareToSym,
3845 make.Block(0L, 3881 make.Block(0L,
3846 blockStatements.toList())); 3882 blockStatements.toList()));

mercurial