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

changeset 1571
af8417e590f4
parent 1565
d04960f05593
child 1612
69cd2bfd4a31
equal deleted inserted replaced
1570:f91144b7da75 1571:af8417e590f4
568 * its symbol. Return the class definition's symbol. 568 * its symbol. Return the class definition's symbol.
569 * and create 569 * and create
570 * @param flags The class symbol's flags 570 * @param flags The class symbol's flags
571 * @param owner The class symbol's owner 571 * @param owner The class symbol's owner
572 */ 572 */
573 ClassSymbol makeEmptyClass(long flags, ClassSymbol owner) { 573 JCClassDecl makeEmptyClass(long flags, ClassSymbol owner) {
574 return makeEmptyClass(flags, owner, null, true);
575 }
576
577 JCClassDecl makeEmptyClass(long flags, ClassSymbol owner, Name flatname,
578 boolean addToDefs) {
574 // Create class symbol. 579 // Create class symbol.
575 ClassSymbol c = reader.defineClass(names.empty, owner); 580 ClassSymbol c = reader.defineClass(names.empty, owner);
576 c.flatname = chk.localClassName(c); 581 if (flatname != null) {
582 c.flatname = flatname;
583 } else {
584 c.flatname = chk.localClassName(c);
585 }
577 c.sourcefile = owner.sourcefile; 586 c.sourcefile = owner.sourcefile;
578 c.completer = null; 587 c.completer = null;
579 c.members_field = new Scope(c); 588 c.members_field = new Scope(c);
580 c.flags_field = flags; 589 c.flags_field = flags;
581 ClassType ctype = (ClassType) c.type; 590 ClassType ctype = (ClassType) c.type;
595 null, List.<JCExpression>nil(), List.<JCTree>nil()); 604 null, List.<JCExpression>nil(), List.<JCTree>nil());
596 cdef.sym = c; 605 cdef.sym = c;
597 cdef.type = c.type; 606 cdef.type = c.type;
598 607
599 // Append class definition tree to owner's definitions. 608 // Append class definition tree to owner's definitions.
600 odef.defs = odef.defs.prepend(cdef); 609 if (addToDefs) odef.defs = odef.defs.prepend(cdef);
601 610 return cdef;
602 return c;
603 } 611 }
604 612
605 /************************************************************************** 613 /**************************************************************************
606 * Symbol manipulation utilities 614 * Symbol manipulation utilities
607 *************************************************************************/ 615 *************************************************************************/
704 /** Anon inner classes are used as access constructor tags. 712 /** Anon inner classes are used as access constructor tags.
705 * accessConstructorTag will use an existing anon class if one is available, 713 * accessConstructorTag will use an existing anon class if one is available,
706 * and synthethise a class (with makeEmptyClass) if one is not available. 714 * and synthethise a class (with makeEmptyClass) if one is not available.
707 * However, there is a small possibility that an existing class will not 715 * However, there is a small possibility that an existing class will not
708 * be generated as expected if it is inside a conditional with a constant 716 * be generated as expected if it is inside a conditional with a constant
709 * expression. If that is found to be the case, create an empty class here. 717 * expression. If that is found to be the case, create an empty class tree here.
710 */ 718 */
711 private void checkAccessConstructorTags() { 719 private void checkAccessConstructorTags() {
712 for (List<ClassSymbol> l = accessConstrTags; l.nonEmpty(); l = l.tail) { 720 for (List<ClassSymbol> l = accessConstrTags; l.nonEmpty(); l = l.tail) {
713 ClassSymbol c = l.head; 721 ClassSymbol c = l.head;
714 if (isTranslatedClassAvailable(c)) 722 if (isTranslatedClassAvailable(c))
715 continue; 723 continue;
716 // Create class definition tree. 724 // Create class definition tree.
717 JCClassDecl cdef = make.ClassDef( 725 JCClassDecl cdec = makeEmptyClass(STATIC | SYNTHETIC,
718 make.Modifiers(STATIC | SYNTHETIC), names.empty, 726 c.outermostClass(), c.flatname, false);
719 List.<JCTypeParameter>nil(), 727 swapAccessConstructorTag(c, cdec.sym);
720 null, List.<JCExpression>nil(), List.<JCTree>nil()); 728 translated.append(cdec);
721 cdef.sym = c;
722 cdef.type = c.type;
723 // add it to the list of classes to be generated
724 translated.append(cdef);
725 } 729 }
726 } 730 }
727 // where 731 // where
728 private boolean isTranslatedClassAvailable(ClassSymbol c) { 732 private boolean isTranslatedClassAvailable(ClassSymbol c) {
729 for (JCTree tree: translated) { 733 for (JCTree tree: translated) {
731 && ((JCClassDecl) tree).sym == c) { 735 && ((JCClassDecl) tree).sym == c) {
732 return true; 736 return true;
733 } 737 }
734 } 738 }
735 return false; 739 return false;
740 }
741
742 void swapAccessConstructorTag(ClassSymbol oldCTag, ClassSymbol newCTag) {
743 for (MethodSymbol methodSymbol : accessConstrs.values()) {
744 Assert.check(methodSymbol.type.hasTag(METHOD));
745 MethodType oldMethodType =
746 (MethodType)methodSymbol.type;
747 if (oldMethodType.argtypes.head.tsym == oldCTag)
748 methodSymbol.type =
749 types.createMethodTypeWithParameters(oldMethodType,
750 oldMethodType.getParameterTypes().tail
751 .prepend(newCTag.erasure(types)));
752 }
736 } 753 }
737 754
738 /************************************************************************** 755 /**************************************************************************
739 * Access methods 756 * Access methods
740 *************************************************************************/ 757 *************************************************************************/
1209 Name flatname = names.fromString("" + topClass.getQualifiedName() + 1226 Name flatname = names.fromString("" + topClass.getQualifiedName() +
1210 target.syntheticNameChar() + 1227 target.syntheticNameChar() +
1211 "1"); 1228 "1");
1212 ClassSymbol ctag = chk.compiled.get(flatname); 1229 ClassSymbol ctag = chk.compiled.get(flatname);
1213 if (ctag == null) 1230 if (ctag == null)
1214 ctag = makeEmptyClass(STATIC | SYNTHETIC, topClass); 1231 ctag = makeEmptyClass(STATIC | SYNTHETIC, topClass).sym;
1215 // keep a record of all tags, to verify that all are generated as required 1232 // keep a record of all tags, to verify that all are generated as required
1216 accessConstrTags = accessConstrTags.prepend(ctag); 1233 accessConstrTags = accessConstrTags.prepend(ctag);
1217 return ctag; 1234 return ctag;
1218 } 1235 }
1219 1236
1426 while (owner.kind == TYP && ((ClassSymbol)owner).members().lookup(result).scope != null) 1443 while (owner.kind == TYP && ((ClassSymbol)owner).members().lookup(result).scope != null)
1427 result = names.fromString(result.toString() + target.syntheticNameChar()); 1444 result = names.fromString(result.toString() + target.syntheticNameChar());
1428 return result; 1445 return result;
1429 } 1446 }
1430 1447
1431 /** Definition for this$n field. 1448 private VarSymbol makeOuterThisVarSymbol(Symbol owner, long flags) {
1432 * @param pos The source code position of the definition.
1433 * @param owner The class in which the definition goes.
1434 */
1435 JCVariableDecl outerThisDef(int pos, Symbol owner) {
1436 long flags = FINAL | SYNTHETIC;
1437 if (owner.kind == TYP && 1449 if (owner.kind == TYP &&
1438 target.usePrivateSyntheticFields()) 1450 target.usePrivateSyntheticFields())
1439 flags |= PRIVATE; 1451 flags |= PRIVATE;
1440 Type target = types.erasure(owner.enclClass().type.getEnclosingType()); 1452 Type target = types.erasure(owner.enclClass().type.getEnclosingType());
1441 VarSymbol outerThis = new VarSymbol( 1453 VarSymbol outerThis =
1442 flags, outerThisName(target, owner), target, owner); 1454 new VarSymbol(flags, outerThisName(target, owner), target, owner);
1443 outerThisStack = outerThisStack.prepend(outerThis); 1455 outerThisStack = outerThisStack.prepend(outerThis);
1444 JCVariableDecl vd = make.at(pos).VarDef(outerThis, null); 1456 return outerThis;
1457 }
1458
1459 private JCVariableDecl makeOuterThisVarDecl(int pos, VarSymbol sym) {
1460 JCVariableDecl vd = make.at(pos).VarDef(sym, null);
1445 vd.vartype = access(vd.vartype); 1461 vd.vartype = access(vd.vartype);
1446 return vd; 1462 return vd;
1463 }
1464
1465 /** Definition for this$n field.
1466 * @param pos The source code position of the definition.
1467 * @param owner The method in which the definition goes.
1468 */
1469 JCVariableDecl outerThisDef(int pos, MethodSymbol owner) {
1470 ClassSymbol c = owner.enclClass();
1471 boolean isMandated =
1472 // Anonymous constructors
1473 (owner.isConstructor() && owner.isAnonymous()) ||
1474 // Constructors of non-private inner member classes
1475 (owner.isConstructor() && c.isInner() &&
1476 !c.isPrivate() && !c.isStatic());
1477 long flags =
1478 FINAL | (isMandated ? MANDATED : SYNTHETIC);
1479 VarSymbol outerThis = makeOuterThisVarSymbol(owner, flags);
1480 owner.extraParams = owner.extraParams.prepend(outerThis);
1481 return makeOuterThisVarDecl(pos, outerThis);
1482 }
1483
1484 /** Definition for this$n field.
1485 * @param pos The source code position of the definition.
1486 * @param owner The class in which the definition goes.
1487 */
1488 JCVariableDecl outerThisDef(int pos, ClassSymbol owner) {
1489 VarSymbol outerThis = makeOuterThisVarSymbol(owner, FINAL | SYNTHETIC);
1490 return makeOuterThisVarDecl(pos, outerThis);
1447 } 1491 }
1448 1492
1449 /** Return a list of trees that load the free variables in given list, 1493 /** Return a list of trees that load the free variables in given list,
1450 * in reverse order. 1494 * in reverse order.
1451 * @param pos The source code position to be used for the trees. 1495 * @param pos The source code position to be used for the trees.
1776 Scope s = clazz.members(); 1820 Scope s = clazz.members();
1777 for (Scope.Entry e = s.elems; e != null; e = e.sibling) 1821 for (Scope.Entry e = s.elems; e != null; e = e.sibling)
1778 if (e.sym.kind == TYP && 1822 if (e.sym.kind == TYP &&
1779 e.sym.name == names.empty && 1823 e.sym.name == names.empty &&
1780 (e.sym.flags() & INTERFACE) == 0) return (ClassSymbol) e.sym; 1824 (e.sym.flags() & INTERFACE) == 0) return (ClassSymbol) e.sym;
1781 return makeEmptyClass(STATIC | SYNTHETIC, clazz); 1825 return makeEmptyClass(STATIC | SYNTHETIC, clazz).sym;
1782 } 1826 }
1783 1827
1784 /** Return symbol for "class$" method. If there is no method definition 1828 /** Return symbol for "class$" method. If there is no method definition
1785 * for class$, construct one as follows: 1829 * for class$, construct one as follows:
1786 * 1830 *
2549 JCVariableDecl nameParam = make_at(tree.pos()). 2593 JCVariableDecl nameParam = make_at(tree.pos()).
2550 Param(names.fromString(target.syntheticNameChar() + 2594 Param(names.fromString(target.syntheticNameChar() +
2551 "enum" + target.syntheticNameChar() + "name"), 2595 "enum" + target.syntheticNameChar() + "name"),
2552 syms.stringType, tree.sym); 2596 syms.stringType, tree.sym);
2553 nameParam.mods.flags |= SYNTHETIC; nameParam.sym.flags_field |= SYNTHETIC; 2597 nameParam.mods.flags |= SYNTHETIC; nameParam.sym.flags_field |= SYNTHETIC;
2554
2555 JCVariableDecl ordParam = make. 2598 JCVariableDecl ordParam = make.
2556 Param(names.fromString(target.syntheticNameChar() + 2599 Param(names.fromString(target.syntheticNameChar() +
2557 "enum" + target.syntheticNameChar() + 2600 "enum" + target.syntheticNameChar() +
2558 "ordinal"), 2601 "ordinal"),
2559 syms.intType, tree.sym); 2602 syms.intType, tree.sym);
2560 ordParam.mods.flags |= SYNTHETIC; ordParam.sym.flags_field |= SYNTHETIC; 2603 ordParam.mods.flags |= SYNTHETIC; ordParam.sym.flags_field |= SYNTHETIC;
2561 2604
2562 tree.params = tree.params.prepend(ordParam).prepend(nameParam); 2605 tree.params = tree.params.prepend(ordParam).prepend(nameParam);
2563 2606
2564 MethodSymbol m = tree.sym; 2607 MethodSymbol m = tree.sym;
2608 m.extraParams = m.extraParams.prepend(ordParam.sym);
2609 m.extraParams = m.extraParams.prepend(nameParam.sym);
2565 Type olderasure = m.erasure(types); 2610 Type olderasure = m.erasure(types);
2566 m.erasure_field = new MethodType( 2611 m.erasure_field = new MethodType(
2567 olderasure.getParameterTypes().prepend(syms.intType).prepend(syms.stringType), 2612 olderasure.getParameterTypes().prepend(syms.intType).prepend(syms.stringType),
2568 olderasure.getReturnType(), 2613 olderasure.getReturnType(),
2569 olderasure.getThrownTypes(), 2614 olderasure.getThrownTypes(),
3047 result = tree; 3092 result = tree;
3048 } 3093 }
3049 } 3094 }
3050 3095
3051 public void visitAssignop(final JCAssignOp tree) { 3096 public void visitAssignop(final JCAssignOp tree) {
3052 if (!tree.lhs.type.isPrimitive() && 3097 final boolean boxingReq = !tree.lhs.type.isPrimitive() &&
3053 tree.operator.type.getReturnType().isPrimitive()) { 3098 tree.operator.type.getReturnType().isPrimitive();
3054 // boxing required; need to rewrite as x = (unbox typeof x)(x op y); 3099
3055 // or if x == (typeof x)z then z = (unbox typeof x)((typeof x)z op y) 3100 // boxing required; need to rewrite as x = (unbox typeof x)(x op y);
3056 // (but without recomputing x) 3101 // or if x == (typeof x)z then z = (unbox typeof x)((typeof x)z op y)
3057 JCTree newTree = abstractLval(tree.lhs, new TreeBuilder() { 3102 // (but without recomputing x)
3058 public JCTree build(final JCTree lhs) { 3103 JCTree newTree = abstractLval(tree.lhs, new TreeBuilder() {
3059 JCTree.Tag newTag = tree.getTag().noAssignOp(); 3104 public JCTree build(final JCTree lhs) {
3060 // Erasure (TransTypes) can change the type of 3105 JCTree.Tag newTag = tree.getTag().noAssignOp();
3061 // tree.lhs. However, we can still get the 3106 // Erasure (TransTypes) can change the type of
3062 // unerased type of tree.lhs as it is stored 3107 // tree.lhs. However, we can still get the
3063 // in tree.type in Attr. 3108 // unerased type of tree.lhs as it is stored
3064 Symbol newOperator = rs.resolveBinaryOperator(tree.pos(), 3109 // in tree.type in Attr.
3065 newTag, 3110 Symbol newOperator = rs.resolveBinaryOperator(tree.pos(),
3066 attrEnv, 3111 newTag,
3067 tree.type, 3112 attrEnv,
3068 tree.rhs.type); 3113 tree.type,
3069 JCExpression expr = (JCExpression)lhs; 3114 tree.rhs.type);
3070 if (expr.type != tree.type) 3115 JCExpression expr = (JCExpression)lhs;
3071 expr = make.TypeCast(tree.type, expr); 3116 if (expr.type != tree.type)
3072 JCBinary opResult = make.Binary(newTag, expr, tree.rhs); 3117 expr = make.TypeCast(tree.type, expr);
3073 opResult.operator = newOperator; 3118 JCBinary opResult = make.Binary(newTag, expr, tree.rhs);
3074 opResult.type = newOperator.type.getReturnType(); 3119 opResult.operator = newOperator;
3075 JCTypeCast newRhs = make.TypeCast(types.unboxedType(tree.type), 3120 opResult.type = newOperator.type.getReturnType();
3076 opResult); 3121 JCExpression newRhs = boxingReq ?
3077 return make.Assign((JCExpression)lhs, newRhs).setType(tree.type); 3122 make.TypeCast(types.unboxedType(tree.type),
3078 } 3123 opResult) :
3079 }); 3124 opResult;
3080 result = translate(newTree); 3125 return make.Assign((JCExpression)lhs, newRhs).setType(tree.type);
3081 return; 3126 }
3082 } 3127 });
3083 tree.lhs = translate(tree.lhs, tree); 3128 result = translate(newTree);
3084 tree.rhs = translate(tree.rhs, tree.operator.type.getParameterTypes().tail.head);
3085
3086 // If translated left hand side is an Apply, we are
3087 // seeing an access method invocation. In this case, append
3088 // right hand side as last argument of the access method.
3089 if (tree.lhs.hasTag(APPLY)) {
3090 JCMethodInvocation app = (JCMethodInvocation)tree.lhs;
3091 // if operation is a += on strings,
3092 // make sure to convert argument to string
3093 JCExpression rhs = (((OperatorSymbol)tree.operator).opcode == string_add)
3094 ? makeString(tree.rhs)
3095 : tree.rhs;
3096 app.args = List.of(rhs).prependList(app.args);
3097 result = app;
3098 } else {
3099 result = tree;
3100 }
3101 } 3129 }
3102 3130
3103 /** Lower a tree of the form e++ or e-- where e is an object type */ 3131 /** Lower a tree of the form e++ or e-- where e is an object type */
3104 JCTree lowerBoxedPostop(final JCUnary tree) { 3132 JCTree lowerBoxedPostop(final JCUnary tree) {
3105 // translate to tmp1=lval(e); tmp2=tmp1; tmp1 OP 1; tmp2 3133 // translate to tmp1=lval(e); tmp2=tmp1; tmp1 OP 1; tmp2

mercurial