src/share/classes/com/sun/tools/javac/comp/Lower.java
Print this page
*** 40,52 ****
--- 40,54 ----
import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.jvm.Target;
import static com.sun.tools.javac.code.Flags.*;
+ import static com.sun.tools.javac.code.Flags.BLOCK;
import static com.sun.tools.javac.code.Kinds.*;
import static com.sun.tools.javac.code.TypeTags.*;
import static com.sun.tools.javac.jvm.ByteCodes.*;
+ import static com.sun.tools.javac.tree.JCTree.Tag.*;
/** This pass translates away some syntactic sugar: inner classes,
* class literals, assertions, foreach loops, etc.
*
* <p><b>This is NOT part of any supported API.
*** 301,311 ****
if (TreeInfo.name(tree.meth) == names._super) {
addFreeVars((ClassSymbol) TreeInfo.symbol(tree.meth).owner);
Symbol constructor = TreeInfo.symbol(tree.meth);
ClassSymbol c = (ClassSymbol)constructor.owner;
if (c.hasOuterInstance() &&
! tree.meth.getTag() != JCTree.SELECT &&
outerThisStack.head != null)
visitSymbol(outerThisStack.head);
}
super.visitApply(tree);
}
--- 303,313 ----
if (TreeInfo.name(tree.meth) == names._super) {
addFreeVars((ClassSymbol) TreeInfo.symbol(tree.meth).owner);
Symbol constructor = TreeInfo.symbol(tree.meth);
ClassSymbol c = (ClassSymbol)constructor.owner;
if (c.hasOuterInstance() &&
! !tree.meth.hasTag(SELECT) &&
outerThisStack.head != null)
visitSymbol(outerThisStack.head);
}
super.visitApply(tree);
}
*** 506,516 ****
/** Make an attributed unary expression.
* @param optag The operators tree tag.
* @param arg The operator's argument.
*/
! JCUnary makeUnary(int optag, JCExpression arg) {
JCUnary tree = make.Unary(optag, arg);
tree.operator = rs.resolveUnaryOperator(
make_pos, optag, attrEnv, arg.type);
tree.type = tree.operator.type.getReturnType();
return tree;
--- 508,518 ----
/** Make an attributed unary expression.
* @param optag The operators tree tag.
* @param arg The operator's argument.
*/
! JCUnary makeUnary(JCTree.Tag optag, JCExpression arg) {
JCUnary tree = make.Unary(optag, arg);
tree.operator = rs.resolveUnaryOperator(
make_pos, optag, attrEnv, arg.type);
tree.type = tree.operator.type.getReturnType();
return tree;
*** 519,529 ****
/** Make an attributed binary expression.
* @param optag The operators tree tag.
* @param lhs The operator's left argument.
* @param rhs The operator's right argument.
*/
! JCBinary makeBinary(int optag, JCExpression lhs, JCExpression rhs) {
JCBinary tree = make.Binary(optag, lhs, rhs);
tree.operator = rs.resolveBinaryOperator(
make_pos, optag, attrEnv, lhs.type, rhs.type);
tree.type = tree.operator.type.getReturnType();
return tree;
--- 521,531 ----
/** Make an attributed binary expression.
* @param optag The operators tree tag.
* @param lhs The operator's left argument.
* @param rhs The operator's right argument.
*/
! JCBinary makeBinary(JCTree.Tag optag, JCExpression lhs, JCExpression rhs) {
JCBinary tree = make.Binary(optag, lhs, rhs);
tree.operator = rs.resolveBinaryOperator(
make_pos, optag, attrEnv, lhs.type, rhs.type);
tree.type = tree.operator.type.getReturnType();
return tree;
*** 532,545 ****
/** Make an attributed assignop expression.
* @param optag The operators tree tag.
* @param lhs The operator's left argument.
* @param rhs The operator's right argument.
*/
! JCAssignOp makeAssignop(int optag, JCTree lhs, JCTree rhs) {
JCAssignOp tree = make.Assignop(optag, lhs, rhs);
tree.operator = rs.resolveBinaryOperator(
! make_pos, tree.getTag() - JCTree.ASGOffset, attrEnv, lhs.type, rhs.type);
tree.type = lhs.type;
return tree;
}
/** Convert tree into string object, unless it has already a
--- 534,547 ----
/** Make an attributed assignop expression.
* @param optag The operators tree tag.
* @param lhs The operator's left argument.
* @param rhs The operator's right argument.
*/
! JCAssignOp makeAssignop(JCTree.Tag optag, JCTree lhs, JCTree rhs) {
JCAssignOp tree = make.Assignop(optag, lhs, rhs);
tree.operator = rs.resolveBinaryOperator(
! make_pos, tree.getTag().noAssignOp(), attrEnv, lhs.type, rhs.type);
tree.type = lhs.type;
return tree;
}
/** Convert tree into string object, unless it has already a
*** 718,728 ****
}
}
// where
private boolean isTranslatedClassAvailable(ClassSymbol c) {
for (JCTree tree: translated) {
! if (tree.getTag() == JCTree.CLASSDEF
&& ((JCClassDecl) tree).sym == c) {
return true;
}
}
return false;
--- 720,730 ----
}
}
// where
private boolean isTranslatedClassAvailable(ClassSymbol c) {
for (JCTree tree: translated) {
! if (tree.hasTag(CLASSDEF)
&& ((JCClassDecl) tree).sym == c) {
return true;
}
}
return false;
*** 800,816 ****
* null if tree is not a subtree of an operation.
*/
private static int accessCode(JCTree tree, JCTree enclOp) {
if (enclOp == null)
return DEREFcode;
! else if (enclOp.getTag() == JCTree.ASSIGN &&
tree == TreeInfo.skipParens(((JCAssign) enclOp).lhs))
return ASSIGNcode;
! else if (JCTree.PREINC <= enclOp.getTag() && enclOp.getTag() <= JCTree.POSTDEC &&
tree == TreeInfo.skipParens(((JCUnary) enclOp).arg))
! return (enclOp.getTag() - JCTree.PREINC) * 2 + PREINCcode;
! else if (JCTree.BITOR_ASG <= enclOp.getTag() && enclOp.getTag() <= JCTree.MOD_ASG &&
tree == TreeInfo.skipParens(((JCAssignOp) enclOp).lhs))
return accessCode(((OperatorSymbol) ((JCAssignOp) enclOp).operator).opcode);
else
return DEREFcode;
}
--- 802,820 ----
* null if tree is not a subtree of an operation.
*/
private static int accessCode(JCTree tree, JCTree enclOp) {
if (enclOp == null)
return DEREFcode;
! else if (enclOp.hasTag(ASSIGN) &&
tree == TreeInfo.skipParens(((JCAssign) enclOp).lhs))
return ASSIGNcode;
! else if (PREINC.ordinal() <= enclOp.getTag().ordinal() &&
! enclOp.getTag().ordinal() <= POSTDEC.ordinal() &&
tree == TreeInfo.skipParens(((JCUnary) enclOp).arg))
! return (enclOp.getTag().ordinal() - PREINC.ordinal()) * 2 + PREINCcode;
! else if (BITOR_ASG.ordinal() <= enclOp.getTag().ordinal() &&
! enclOp.getTag().ordinal() <= MOD_ASG.ordinal() &&
tree == TreeInfo.skipParens(((JCAssignOp) enclOp).lhs))
return accessCode(((OperatorSymbol) ((JCAssignOp) enclOp).operator).opcode);
else
return DEREFcode;
}
*** 830,872 ****
}
/** Return tree tag for assignment operation corresponding
* to given binary operator.
*/
! private static int treeTag(OperatorSymbol operator) {
switch (operator.opcode) {
case ByteCodes.ior: case ByteCodes.lor:
! return JCTree.BITOR_ASG;
case ByteCodes.ixor: case ByteCodes.lxor:
! return JCTree.BITXOR_ASG;
case ByteCodes.iand: case ByteCodes.land:
! return JCTree.BITAND_ASG;
case ByteCodes.ishl: case ByteCodes.lshl:
case ByteCodes.ishll: case ByteCodes.lshll:
! return JCTree.SL_ASG;
case ByteCodes.ishr: case ByteCodes.lshr:
case ByteCodes.ishrl: case ByteCodes.lshrl:
! return JCTree.SR_ASG;
case ByteCodes.iushr: case ByteCodes.lushr:
case ByteCodes.iushrl: case ByteCodes.lushrl:
! return JCTree.USR_ASG;
case ByteCodes.iadd: case ByteCodes.ladd:
case ByteCodes.fadd: case ByteCodes.dadd:
case ByteCodes.string_add:
! return JCTree.PLUS_ASG;
case ByteCodes.isub: case ByteCodes.lsub:
case ByteCodes.fsub: case ByteCodes.dsub:
! return JCTree.MINUS_ASG;
case ByteCodes.imul: case ByteCodes.lmul:
case ByteCodes.fmul: case ByteCodes.dmul:
! return JCTree.MUL_ASG;
case ByteCodes.idiv: case ByteCodes.ldiv:
case ByteCodes.fdiv: case ByteCodes.ddiv:
! return JCTree.DIV_ASG;
case ByteCodes.imod: case ByteCodes.lmod:
case ByteCodes.fmod: case ByteCodes.dmod:
! return JCTree.MOD_ASG;
default:
throw new AssertionError();
}
}
--- 834,876 ----
}
/** Return tree tag for assignment operation corresponding
* to given binary operator.
*/
! private static JCTree.Tag treeTag(OperatorSymbol operator) {
switch (operator.opcode) {
case ByteCodes.ior: case ByteCodes.lor:
! return BITOR_ASG;
case ByteCodes.ixor: case ByteCodes.lxor:
! return BITXOR_ASG;
case ByteCodes.iand: case ByteCodes.land:
! return BITAND_ASG;
case ByteCodes.ishl: case ByteCodes.lshl:
case ByteCodes.ishll: case ByteCodes.lshll:
! return SL_ASG;
case ByteCodes.ishr: case ByteCodes.lshr:
case ByteCodes.ishrl: case ByteCodes.lshrl:
! return SR_ASG;
case ByteCodes.iushr: case ByteCodes.lushr:
case ByteCodes.iushrl: case ByteCodes.lushrl:
! return USR_ASG;
case ByteCodes.iadd: case ByteCodes.ladd:
case ByteCodes.fadd: case ByteCodes.dadd:
case ByteCodes.string_add:
! return PLUS_ASG;
case ByteCodes.isub: case ByteCodes.lsub:
case ByteCodes.fsub: case ByteCodes.dsub:
! return MINUS_ASG;
case ByteCodes.imul: case ByteCodes.lmul:
case ByteCodes.fmul: case ByteCodes.dmul:
! return MUL_ASG;
case ByteCodes.idiv: case ByteCodes.ldiv:
case ByteCodes.fdiv: case ByteCodes.ddiv:
! return DIV_ASG;
case ByteCodes.imod: case ByteCodes.lmod:
case ByteCodes.fmod: case ByteCodes.dmod:
! return MOD_ASG;
default:
throw new AssertionError();
}
}
*** 1001,1011 ****
sym.packge() == currentClass.packge())
return false;
if (!currentClass.isSubClass(sym.owner, types))
return true;
if ((sym.flags() & STATIC) != 0 ||
! tree.getTag() != JCTree.SELECT ||
TreeInfo.name(((JCFieldAccess) tree).selected) == names._super)
return false;
return !((JCFieldAccess) tree).selected.type.tsym.isSubClass(currentClass, types);
}
--- 1005,1015 ----
sym.packge() == currentClass.packge())
return false;
if (!currentClass.isSubClass(sym.owner, types))
return true;
if ((sym.flags() & STATIC) != 0 ||
! !tree.hasTag(SELECT) ||
TreeInfo.name(((JCFieldAccess) tree).selected) == names._super)
return false;
return !((JCFieldAccess) tree).selected.type.tsym.isSubClass(currentClass, types);
}
*** 1016,1026 ****
*/
ClassSymbol accessClass(Symbol sym, boolean protAccess, JCTree tree) {
if (protAccess) {
Symbol qualifier = null;
ClassSymbol c = currentClass;
! if (tree.getTag() == JCTree.SELECT && (sym.flags() & STATIC) == 0) {
qualifier = ((JCFieldAccess) tree).selected.type.tsym;
while (!qualifier.isSubClass(c, types)) {
c = c.owner.enclClass();
}
return c;
--- 1020,1030 ----
*/
ClassSymbol accessClass(Symbol sym, boolean protAccess, JCTree tree) {
if (protAccess) {
Symbol qualifier = null;
ClassSymbol c = currentClass;
! if (tree.hasTag(SELECT) && (sym.flags() & STATIC) == 0) {
qualifier = ((JCFieldAccess) tree).selected.type.tsym;
while (!qualifier.isSubClass(c, types)) {
c = c.owner.enclClass();
}
return c;
*** 1056,1080 ****
// Otherwise replace the variable by its proxy.
sym = proxies.lookup(proxyName(sym.name)).sym;
Assert.check(sym != null && (sym.flags_field & FINAL) != 0);
tree = make.at(tree.pos).Ident(sym);
}
! JCExpression base = (tree.getTag() == JCTree.SELECT) ? ((JCFieldAccess) tree).selected : null;
switch (sym.kind) {
case TYP:
if (sym.owner.kind != PCK) {
// Convert type idents to
// <flat name> or <package name> . <flat name>
Name flatname = Convert.shortName(sym.flatName());
while (base != null &&
TreeInfo.symbol(base) != null &&
TreeInfo.symbol(base).kind != PCK) {
! base = (base.getTag() == JCTree.SELECT)
? ((JCFieldAccess) base).selected
: null;
}
! if (tree.getTag() == JCTree.IDENT) {
((JCIdent) tree).name = flatname;
} else if (base == null) {
tree = make.at(tree.pos).Ident(sym);
((JCIdent) tree).name = flatname;
} else {
--- 1060,1084 ----
// Otherwise replace the variable by its proxy.
sym = proxies.lookup(proxyName(sym.name)).sym;
Assert.check(sym != null && (sym.flags_field & FINAL) != 0);
tree = make.at(tree.pos).Ident(sym);
}
! JCExpression base = (tree.hasTag(SELECT)) ? ((JCFieldAccess) tree).selected : null;
switch (sym.kind) {
case TYP:
if (sym.owner.kind != PCK) {
// Convert type idents to
// <flat name> or <package name> . <flat name>
Name flatname = Convert.shortName(sym.flatName());
while (base != null &&
TreeInfo.symbol(base) != null &&
TreeInfo.symbol(base).kind != PCK) {
! base = (base.hasTag(SELECT))
? ((JCFieldAccess) base).selected
: null;
}
! if (tree.hasTag(IDENT)) {
((JCIdent) tree).name = flatname;
} else if (base == null) {
tree = make.at(tree.pos).Ident(sym);
((JCIdent) tree).name = flatname;
} else {
*** 1258,1268 ****
case ASSIGNcode:
expr = make.Assign(ref, args.head);
break;
case PREINCcode: case POSTINCcode: case PREDECcode: case POSTDECcode:
expr = makeUnary(
! ((acode1 - PREINCcode) >> 1) + JCTree.PREINC, ref);
break;
default:
expr = make.Assignop(
treeTag(binaryAccessOperator(acode1)), ref, args.head);
((JCAssignOp) expr).operator = binaryAccessOperator(acode1);
--- 1262,1272 ----
case ASSIGNcode:
expr = make.Assign(ref, args.head);
break;
case PREINCcode: case POSTINCcode: case PREDECcode: case POSTDECcode:
expr = makeUnary(
! values()[((acode1 - PREINCcode) >> 1) + PREINC.ordinal()], ref);
break;
default:
expr = make.Assignop(
treeTag(binaryAccessOperator(acode1)), ref, args.head);
((JCAssignOp) expr).operator = binaryAccessOperator(acode1);
*** 1574,1584 ****
List.<JCExpression>nil());
return make.Exec(resourceClose);
}
private JCExpression makeNonNullCheck(JCExpression expression) {
! return makeBinary(JCTree.NE, expression, makeNull());
}
/** Construct a tree that represents the outer instance
* <C.this>. Never pick the current `this'.
* @param pos The source code position to be used for the tree.
--- 1578,1588 ----
List.<JCExpression>nil());
return make.Exec(resourceClose);
}
private JCExpression makeNonNullCheck(JCExpression expression) {
! return makeBinary(NE, expression, makeNull());
}
/** Construct a tree that represents the outer instance
* <C.this>. Never pick the current `this'.
* @param pos The source code position to be used for the tree.
*** 1806,1816 ****
syms.classLoaderType));
// clvalue := "(cl$ == null) ?
// $newcache.getClass().getComponentType().getClassLoader() : cl$"
JCExpression clvalue =
make.Conditional(
! makeBinary(JCTree.EQ, make.Ident(clsym), makeNull()),
make.Assign(
make.Ident(clsym),
makeCall(
makeCall(makeCall(newcache,
names.getClass,
--- 1810,1820 ----
syms.classLoaderType));
// clvalue := "(cl$ == null) ?
// $newcache.getClass().getComponentType().getClassLoader() : cl$"
JCExpression clvalue =
make.Conditional(
! makeBinary(EQ, make.Ident(clsym), makeNull()),
make.Assign(
make.Ident(clsym),
makeCall(
makeCall(makeCall(newcache,
names.getClass,
*** 1974,1984 ****
// - <cache> is the cache variable for tsig.
String sig =
writer.xClassName(type).toString().replace('/', '.');
Symbol cs = cacheSym(pos, sig);
return make_at(pos).Conditional(
! makeBinary(JCTree.EQ, make.Ident(cs), makeNull()),
make.Assign(
make.Ident(cs),
make.App(
make.Ident(classDollarSym(pos)),
List.<JCExpression>of(make.Literal(CLASS, sig)
--- 1978,1988 ----
// - <cache> is the cache variable for tsig.
String sig =
writer.xClassName(type).toString().replace('/', '.');
Symbol cs = cacheSym(pos, sig);
return make_at(pos).Conditional(
! makeBinary(EQ, make.Ident(cs), makeNull()),
make.Assign(
make.Ident(cs),
make.App(
make.Ident(classDollarSym(pos)),
List.<JCExpression>of(make.Literal(CLASS, sig)
*** 2021,2040 ****
names.desiredAssertionStatus,
types.erasure(syms.classType),
List.<Type>nil());
JCClassDecl containerDef = classDef(container);
make_at(containerDef.pos());
! JCExpression notStatus = makeUnary(JCTree.NOT, make.App(make.Select(
classOfType(types.erasure(outermostClass.type),
containerDef.pos()),
desiredAssertionStatusSym)));
JCVariableDecl assertDisabledDef = make.VarDef(assertDisabledSym,
notStatus);
containerDef.defs = containerDef.defs.prepend(assertDisabledDef);
}
make_at(pos);
! return makeUnary(JCTree.NOT, make.Ident(assertDisabledSym));
}
/**************************************************************************
* Building blocks for let expressions
--- 2025,2044 ----
names.desiredAssertionStatus,
types.erasure(syms.classType),
List.<Type>nil());
JCClassDecl containerDef = classDef(container);
make_at(containerDef.pos());
! JCExpression notStatus = makeUnary(NOT, make.App(make.Select(
classOfType(types.erasure(outermostClass.type),
containerDef.pos()),
desiredAssertionStatusSym)));
JCVariableDecl assertDisabledDef = make.VarDef(assertDisabledSym,
notStatus);
containerDef.defs = containerDef.defs.prepend(assertDisabledDef);
}
make_at(pos);
! return makeUnary(NOT, make.Ident(assertDisabledSym));
}
/**************************************************************************
* Building blocks for let expressions
*** 2060,2072 ****
* in the let expression.
*/
JCTree abstractRval(JCTree rval, Type type, TreeBuilder builder) {
rval = TreeInfo.skipParens(rval);
switch (rval.getTag()) {
! case JCTree.LITERAL:
return builder.build(rval);
! case JCTree.IDENT:
JCIdent id = (JCIdent) rval;
if ((id.sym.flags() & FINAL) != 0 && id.sym.owner.kind == MTH)
return builder.build(rval);
}
VarSymbol var =
--- 2064,2076 ----
* in the let expression.
*/
JCTree abstractRval(JCTree rval, Type type, TreeBuilder builder) {
rval = TreeInfo.skipParens(rval);
switch (rval.getTag()) {
! case LITERAL:
return builder.build(rval);
! case IDENT:
JCIdent id = (JCIdent) rval;
if ((id.sym.flags() & FINAL) != 0 && id.sym.owner.kind == MTH)
return builder.build(rval);
}
VarSymbol var =
*** 2095,2118 ****
// select in a temporary, and for Indexed expressions, where we
// place both the indexed expression and the index value in temps.
JCTree abstractLval(JCTree lval, final TreeBuilder builder) {
lval = TreeInfo.skipParens(lval);
switch (lval.getTag()) {
! case JCTree.IDENT:
return builder.build(lval);
! case JCTree.SELECT: {
final JCFieldAccess s = (JCFieldAccess)lval;
JCTree selected = TreeInfo.skipParens(s.selected);
Symbol lid = TreeInfo.symbol(s.selected);
if (lid != null && lid.kind == TYP) return builder.build(lval);
return abstractRval(s.selected, new TreeBuilder() {
public JCTree build(final JCTree selected) {
return builder.build(make.Select((JCExpression)selected, s.sym));
}
});
}
! case JCTree.INDEXED: {
final JCArrayAccess i = (JCArrayAccess)lval;
return abstractRval(i.indexed, new TreeBuilder() {
public JCTree build(final JCTree indexed) {
return abstractRval(i.index, syms.intType, new TreeBuilder() {
public JCTree build(final JCTree index) {
--- 2099,2122 ----
// select in a temporary, and for Indexed expressions, where we
// place both the indexed expression and the index value in temps.
JCTree abstractLval(JCTree lval, final TreeBuilder builder) {
lval = TreeInfo.skipParens(lval);
switch (lval.getTag()) {
! case IDENT:
return builder.build(lval);
! case SELECT: {
final JCFieldAccess s = (JCFieldAccess)lval;
JCTree selected = TreeInfo.skipParens(s.selected);
Symbol lid = TreeInfo.symbol(s.selected);
if (lid != null && lid.kind == TYP) return builder.build(lval);
return abstractRval(s.selected, new TreeBuilder() {
public JCTree build(final JCTree selected) {
return builder.build(make.Select((JCExpression)selected, s.sym));
}
});
}
! case INDEXED: {
final JCArrayAccess i = (JCArrayAccess)lval;
return abstractRval(i.indexed, new TreeBuilder() {
public JCTree build(final JCTree indexed) {
return abstractRval(i.index, syms.intType, new TreeBuilder() {
public JCTree build(final JCTree index) {
*** 2123,2133 ****
}
});
}
});
}
! case JCTree.TYPECAST: {
return abstractLval(((JCTypeCast)lval).expr, builder);
}
}
throw new AssertionError(lval);
}
--- 2127,2137 ----
}
});
}
});
}
! case TYPECAST: {
return abstractLval(((JCTypeCast)lval).expr, builder);
}
}
throw new AssertionError(lval);
}
*** 2343,2353 ****
ListBuffer<JCTree> enumDefs = new ListBuffer<JCTree>();
ListBuffer<JCTree> otherDefs = new ListBuffer<JCTree>();
for (List<JCTree> defs = tree.defs;
defs.nonEmpty();
defs=defs.tail) {
! if (defs.head.getTag() == JCTree.VARDEF && (((JCVariableDecl) defs.head).mods.flags & ENUM) != 0) {
JCVariableDecl var = (JCVariableDecl)defs.head;
visitEnumConstantDef(var, nextOrdinal++);
values.append(make.QualIdent(var.sym));
enumDefs.append(var);
} else {
--- 2347,2357 ----
ListBuffer<JCTree> enumDefs = new ListBuffer<JCTree>();
ListBuffer<JCTree> otherDefs = new ListBuffer<JCTree>();
for (List<JCTree> defs = tree.defs;
defs.nonEmpty();
defs=defs.tail) {
! if (defs.head.hasTag(VARDEF) && (((JCVariableDecl) defs.head).mods.flags & ENUM) != 0) {
JCVariableDecl var = (JCVariableDecl)defs.head;
visitEnumConstantDef(var, nextOrdinal++);
values.append(make.QualIdent(var.sym));
enumDefs.append(var);
} else {
*** 2755,2767 ****
JCExpression cond = assertFlagTest(tree.pos());
List<JCExpression> exnArgs = (tree.detail == null) ?
List.<JCExpression>nil() : List.of(translate(tree.detail));
if (!tree.cond.type.isFalse()) {
cond = makeBinary
! (JCTree.AND,
cond,
! makeUnary(JCTree.NOT, tree.cond));
}
result =
make.If(cond,
make_at(detailPos).
Throw(makeNewClass(syms.assertionErrorType, exnArgs)),
--- 2759,2771 ----
JCExpression cond = assertFlagTest(tree.pos());
List<JCExpression> exnArgs = (tree.detail == null) ?
List.<JCExpression>nil() : List.of(translate(tree.detail));
if (!tree.cond.type.isFalse()) {
cond = makeBinary
! (AND,
cond,
! makeUnary(NOT, tree.cond));
}
result =
make.If(cond,
make_at(detailPos).
Throw(makeNewClass(syms.assertionErrorType, exnArgs)),
*** 2814,2824 ****
// the explicit constructor arguments. If the call
// is not qualified, pass the correct outer instance as
// first argument.
if (c.hasOuterInstance()) {
JCExpression thisArg;
! if (tree.meth.getTag() == JCTree.SELECT) {
thisArg = attr.
makeNullCheck(translate(((JCFieldAccess) tree.meth).selected));
tree.meth = make.Ident(constructor);
((JCIdent) tree.meth).name = methName;
} else if ((c.owner.kind & (MTH | VAR)) != 0 || methName == names._this){
--- 2818,2828 ----
// the explicit constructor arguments. If the call
// is not qualified, pass the correct outer instance as
// first argument.
if (c.hasOuterInstance()) {
JCExpression thisArg;
! if (tree.meth.hasTag(SELECT)) {
thisArg = attr.
makeNullCheck(translate(((JCFieldAccess) tree.meth).selected));
tree.meth = make.Ident(constructor);
((JCIdent) tree.meth).name = methName;
} else if ((c.owner.kind & (MTH | VAR)) != 0 || methName == names._this){
*** 2835,2845 ****
tree.meth = translate(tree.meth);
// If the translated method itself is an Apply tree, we are
// seeing an access method invocation. In this case, append
// the method arguments to the arguments of the access method.
! if (tree.meth.getTag() == JCTree.APPLY) {
JCMethodInvocation app = (JCMethodInvocation)tree.meth;
app.args = tree.args.prependList(app.args);
result = app;
return;
}
--- 2839,2849 ----
tree.meth = translate(tree.meth);
// If the translated method itself is an Apply tree, we are
// seeing an access method invocation. In this case, append
// the method arguments to the arguments of the access method.
! if (tree.meth.hasTag(APPLY)) {
JCMethodInvocation app = (JCMethodInvocation)tree.meth;
app.args = tree.args.prependList(app.args);
result = app;
return;
}
*** 2969,2979 ****
tree.rhs = translate(tree.rhs, tree.lhs.type);
// If translated left hand side is an Apply, we are
// seeing an access method invocation. In this case, append
// right hand side as last argument of the access method.
! if (tree.lhs.getTag() == JCTree.APPLY) {
JCMethodInvocation app = (JCMethodInvocation)tree.lhs;
app.args = List.of(tree.rhs).prependList(app.args);
result = app;
} else {
result = tree;
--- 2973,2983 ----
tree.rhs = translate(tree.rhs, tree.lhs.type);
// If translated left hand side is an Apply, we are
// seeing an access method invocation. In this case, append
// right hand side as last argument of the access method.
! if (tree.lhs.hasTag(APPLY)) {
JCMethodInvocation app = (JCMethodInvocation)tree.lhs;
app.args = List.of(tree.rhs).prependList(app.args);
result = app;
} else {
result = tree;
*** 2986,2996 ****
// boxing required; need to rewrite as x = (unbox typeof x)(x op y);
// or if x == (typeof x)z then z = (unbox typeof x)((typeof x)z op y)
// (but without recomputing x)
JCTree newTree = abstractLval(tree.lhs, new TreeBuilder() {
public JCTree build(final JCTree lhs) {
! int newTag = tree.getTag() - JCTree.ASGOffset;
// Erasure (TransTypes) can change the type of
// tree.lhs. However, we can still get the
// unerased type of tree.lhs as it is stored
// in tree.type in Attr.
Symbol newOperator = rs.resolveBinaryOperator(tree.pos(),
--- 2990,3000 ----
// boxing required; need to rewrite as x = (unbox typeof x)(x op y);
// or if x == (typeof x)z then z = (unbox typeof x)((typeof x)z op y)
// (but without recomputing x)
JCTree newTree = abstractLval(tree.lhs, new TreeBuilder() {
public JCTree build(final JCTree lhs) {
! JCTree.Tag newTag = tree.getTag().noAssignOp();
// Erasure (TransTypes) can change the type of
// tree.lhs. However, we can still get the
// unerased type of tree.lhs as it is stored
// in tree.type in Attr.
Symbol newOperator = rs.resolveBinaryOperator(tree.pos(),
*** 3016,3026 ****
tree.rhs = translate(tree.rhs, tree.operator.type.getParameterTypes().tail.head);
// If translated left hand side is an Apply, we are
// seeing an access method invocation. In this case, append
// right hand side as last argument of the access method.
! if (tree.lhs.getTag() == JCTree.APPLY) {
JCMethodInvocation app = (JCMethodInvocation)tree.lhs;
// if operation is a += on strings,
// make sure to convert argument to string
JCExpression rhs = (((OperatorSymbol)tree.operator).opcode == string_add)
? makeString(tree.rhs)
--- 3020,3030 ----
tree.rhs = translate(tree.rhs, tree.operator.type.getParameterTypes().tail.head);
// If translated left hand side is an Apply, we are
// seeing an access method invocation. In this case, append
// right hand side as last argument of the access method.
! if (tree.lhs.hasTag(APPLY)) {
JCMethodInvocation app = (JCMethodInvocation)tree.lhs;
// if operation is a += on strings,
// make sure to convert argument to string
JCExpression rhs = (((OperatorSymbol)tree.operator).opcode == string_add)
? makeString(tree.rhs)
*** 3036,3052 ****
JCTree lowerBoxedPostop(final JCUnary tree) {
// translate to tmp1=lval(e); tmp2=tmp1; tmp1 OP 1; tmp2
// or
// translate to tmp1=lval(e); tmp2=tmp1; (typeof tree)tmp1 OP 1; tmp2
// where OP is += or -=
! final boolean cast = TreeInfo.skipParens(tree.arg).getTag() == JCTree.TYPECAST;
return abstractLval(tree.arg, new TreeBuilder() {
public JCTree build(final JCTree tmp1) {
return abstractRval(tmp1, tree.arg.type, new TreeBuilder() {
public JCTree build(final JCTree tmp2) {
! int opcode = (tree.getTag() == JCTree.POSTINC)
! ? JCTree.PLUS_ASG : JCTree.MINUS_ASG;
JCTree lhs = cast
? make.TypeCast(tree.arg.type, (JCExpression)tmp1)
: tmp1;
JCTree update = makeAssignop(opcode,
lhs,
--- 3040,3056 ----
JCTree lowerBoxedPostop(final JCUnary tree) {
// translate to tmp1=lval(e); tmp2=tmp1; tmp1 OP 1; tmp2
// or
// translate to tmp1=lval(e); tmp2=tmp1; (typeof tree)tmp1 OP 1; tmp2
// where OP is += or -=
! final boolean cast = TreeInfo.skipParens(tree.arg).hasTag(TYPECAST);
return abstractLval(tree.arg, new TreeBuilder() {
public JCTree build(final JCTree tmp1) {
return abstractRval(tmp1, tree.arg.type, new TreeBuilder() {
public JCTree build(final JCTree tmp2) {
! JCTree.Tag opcode = (tree.hasTag(POSTINC))
! ? PLUS_ASG : MINUS_ASG;
JCTree lhs = cast
? make.TypeCast(tree.arg.type, (JCExpression)tmp1)
: tmp1;
JCTree update = makeAssignop(opcode,
lhs,
*** 3058,3124 ****
});
}
public void visitUnary(JCUnary tree) {
boolean isUpdateOperator =
! JCTree.PREINC <= tree.getTag() && tree.getTag() <= JCTree.POSTDEC;
if (isUpdateOperator && !tree.arg.type.isPrimitive()) {
switch(tree.getTag()) {
! case JCTree.PREINC: // ++ e
// translate to e += 1
! case JCTree.PREDEC: // -- e
// translate to e -= 1
{
! int opcode = (tree.getTag() == JCTree.PREINC)
! ? JCTree.PLUS_ASG : JCTree.MINUS_ASG;
JCAssignOp newTree = makeAssignop(opcode,
tree.arg,
make.Literal(1));
result = translate(newTree, tree.type);
return;
}
! case JCTree.POSTINC: // e ++
! case JCTree.POSTDEC: // e --
{
result = translate(lowerBoxedPostop(tree), tree.type);
return;
}
}
throw new AssertionError(tree);
}
tree.arg = boxIfNeeded(translate(tree.arg, tree), tree.type);
! if (tree.getTag() == JCTree.NOT && tree.arg.type.constValue() != null) {
tree.type = cfolder.fold1(bool_not, tree.arg.type);
}
// If translated left hand side is an Apply, we are
// seeing an access method invocation. In this case, return
// that access method invocation as result.
! if (isUpdateOperator && tree.arg.getTag() == JCTree.APPLY) {
result = tree.arg;
} else {
result = tree;
}
}
public void visitBinary(JCBinary tree) {
List<Type> formals = tree.operator.type.getParameterTypes();
JCTree lhs = tree.lhs = translate(tree.lhs, formals.head);
switch (tree.getTag()) {
! case JCTree.OR:
if (lhs.type.isTrue()) {
result = lhs;
return;
}
if (lhs.type.isFalse()) {
result = translate(tree.rhs, formals.tail.head);
return;
}
break;
! case JCTree.AND:
if (lhs.type.isFalse()) {
result = lhs;
return;
}
if (lhs.type.isTrue()) {
--- 3062,3128 ----
});
}
public void visitUnary(JCUnary tree) {
boolean isUpdateOperator =
! PREINC.ordinal() <= tree.getTag().ordinal() && tree.getTag().ordinal() <= POSTDEC.ordinal();
if (isUpdateOperator && !tree.arg.type.isPrimitive()) {
switch(tree.getTag()) {
! case PREINC: // ++ e
// translate to e += 1
! case PREDEC: // -- e
// translate to e -= 1
{
! JCTree.Tag opcode = (tree.hasTag(PREINC))
! ? PLUS_ASG : MINUS_ASG;
JCAssignOp newTree = makeAssignop(opcode,
tree.arg,
make.Literal(1));
result = translate(newTree, tree.type);
return;
}
! case POSTINC: // e ++
! case POSTDEC: // e --
{
result = translate(lowerBoxedPostop(tree), tree.type);
return;
}
}
throw new AssertionError(tree);
}
tree.arg = boxIfNeeded(translate(tree.arg, tree), tree.type);
! if (tree.hasTag(NOT) && tree.arg.type.constValue() != null) {
tree.type = cfolder.fold1(bool_not, tree.arg.type);
}
// If translated left hand side is an Apply, we are
// seeing an access method invocation. In this case, return
// that access method invocation as result.
! if (isUpdateOperator && tree.arg.hasTag(APPLY)) {
result = tree.arg;
} else {
result = tree;
}
}
public void visitBinary(JCBinary tree) {
List<Type> formals = tree.operator.type.getParameterTypes();
JCTree lhs = tree.lhs = translate(tree.lhs, formals.head);
switch (tree.getTag()) {
! case OR:
if (lhs.type.isTrue()) {
result = lhs;
return;
}
if (lhs.type.isFalse()) {
result = translate(tree.rhs, formals.tail.head);
return;
}
break;
! case AND:
if (lhs.type.isFalse()) {
result = lhs;
return;
}
if (lhs.type.isTrue()) {
*** 3184,3196 ****
JCVariableDecl indexdef = make.VarDef(index, make.Literal(INT, 0));
indexdef.init.type = indexdef.type = syms.intType.constType(0);
List<JCStatement> loopinit = List.of(arraycachedef, lencachedef, indexdef);
! JCBinary cond = makeBinary(JCTree.LT, make.Ident(index), make.Ident(lencache));
! JCExpressionStatement step = make.Exec(makeUnary(JCTree.PREINC, make.Ident(index)));
Type elemtype = types.elemtype(tree.expr.type);
JCExpression loopvarinit = make.Indexed(make.Ident(arraycache),
make.Ident(index)).setType(elemtype);
JCVariableDecl loopvardef = (JCVariableDecl)make.VarDef(tree.var.mods,
--- 3188,3200 ----
JCVariableDecl indexdef = make.VarDef(index, make.Literal(INT, 0));
indexdef.init.type = indexdef.type = syms.intType.constType(0);
List<JCStatement> loopinit = List.of(arraycachedef, lencachedef, indexdef);
! JCBinary cond = makeBinary(LT, make.Ident(index), make.Ident(lencache));
! JCExpressionStatement step = make.Exec(makeUnary(PREINC, make.Ident(index)));
Type elemtype = types.elemtype(tree.expr.type);
JCExpression loopvarinit = make.Indexed(make.Ident(arraycache),
make.Ident(index)).setType(elemtype);
JCVariableDecl loopvardef = (JCVariableDecl)make.VarDef(tree.var.mods,
*** 3590,3600 ****
public void visitSelect(JCFieldAccess tree) {
// need to special case-access of the form C.super.x
// these will always need an access method.
boolean qualifiedSuperAccess =
! tree.selected.getTag() == JCTree.SELECT &&
TreeInfo.name(tree.selected) == names._super;
tree.selected = translate(tree.selected);
if (tree.name == names._class)
result = classOf(tree.selected);
else if (tree.name == names._this || tree.name == names._super)
--- 3594,3604 ----
public void visitSelect(JCFieldAccess tree) {
// need to special case-access of the form C.super.x
// these will always need an access method.
boolean qualifiedSuperAccess =
! tree.selected.hasTag(SELECT) &&
TreeInfo.name(tree.selected) == names._super;
tree.selected = translate(tree.selected);
if (tree.name == names._class)
result = classOf(tree.selected);
else if (tree.name == names._this || tree.name == names._super)
*** 3640,3650 ****
attrEnv = env;
this.make = make;
endPositions = env.toplevel.endPositions;
currentClass = null;
currentMethodDef = null;
! outermostClassDef = (cdef.getTag() == JCTree.CLASSDEF) ? (JCClassDecl)cdef : null;
outermostMemberDef = null;
this.translated = new ListBuffer<JCTree>();
classdefs = new HashMap<ClassSymbol,JCClassDecl>();
actualSymbols = new HashMap<Symbol,Symbol>();
freevarCache = new HashMap<ClassSymbol,List<VarSymbol>>();
--- 3644,3654 ----
attrEnv = env;
this.make = make;
endPositions = env.toplevel.endPositions;
currentClass = null;
currentMethodDef = null;
! outermostClassDef = (cdef.hasTag(CLASSDEF)) ? (JCClassDecl)cdef : null;
outermostMemberDef = null;
this.translated = new ListBuffer<JCTree>();
classdefs = new HashMap<ClassSymbol,JCClassDecl>();
actualSymbols = new HashMap<Symbol,Symbol>();
freevarCache = new HashMap<ClassSymbol,List<VarSymbol>>();
*** 3836,3846 ****
JCIdent id1 = make.Ident(ordinalSymbol);
JCIdent fLocUsageId = make.Ident(otherVarSym);
JCExpression sel = make.Select(fLocUsageId, ordinalSymbol);
! JCBinary bin = makeBinary(JCTree.MINUS, id1, sel);
JCReturn ret = make.Return(bin);
blockStatements.append(ret);
JCMethodDecl compareToMethod = make.MethodDef((MethodSymbol)compareToSym,
make.Block(0L,
blockStatements.toList()));
--- 3840,3850 ----
JCIdent id1 = make.Ident(ordinalSymbol);
JCIdent fLocUsageId = make.Ident(otherVarSym);
JCExpression sel = make.Select(fLocUsageId, ordinalSymbol);
! JCBinary bin = makeBinary(MINUS, id1, sel);
JCReturn ret = make.Return(bin);
blockStatements.append(ret);
JCMethodDecl compareToMethod = make.MethodDef((MethodSymbol)compareToSym,
make.Block(0L,
blockStatements.toList()));