use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree in project ceylon by eclipse.
the class Lower method lowerBoxedPostop.
/**
* Lower a tree of the form e++ or e-- where e is an object type
*/
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, make.Literal(1));
return makeComma(update, tmp2);
}
});
}
});
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree in project ceylon by eclipse.
the class Lower method visitClassDef.
public void visitClassDef(JCClassDecl tree) {
Env<AttrContext> prevEnv = attrEnv;
ClassSymbol currentClassPrev = currentClass;
MethodSymbol currentMethodSymPrev = currentMethodSym;
currentClass = tree.sym;
currentMethodSym = null;
attrEnv = typeEnvs.remove(currentClass);
if (attrEnv == null)
attrEnv = prevEnv;
classdefs.put(currentClass, tree);
proxies = proxies.dup(currentClass);
List<VarSymbol> prevOuterThisStack = outerThisStack;
// If this is an enum definition
if ((tree.mods.flags & ENUM) != 0 && (types.supertype(currentClass.type).tsym.flags() & ENUM) == 0)
visitEnumDef(tree);
// If this is a nested class, define a this$n field for
// it and add to proxies.
JCVariableDecl otdef = null;
if (currentClass.hasOuterInstance())
otdef = outerThisDef(tree.pos, currentClass);
// If this is a local class, define proxies for all its free variables.
List<JCVariableDecl> fvdefs = freevarDefs(tree.pos, freevars(currentClass), currentClass);
// Recursively translate superclass, interfaces.
tree.extending = translate(tree.extending);
tree.implementing = translate(tree.implementing);
if (currentClass.isLocal()) {
ClassSymbol encl = currentClass.owner.enclClass();
if (encl.trans_local == null) {
encl.trans_local = List.nil();
}
encl.trans_local = encl.trans_local.prepend(currentClass);
}
// Recursively translate members, taking into account that new members
// might be created during the translation and prepended to the member
// list `tree.defs'.
List<JCTree> seen = List.nil();
while (tree.defs != seen) {
List<JCTree> unseen = tree.defs;
for (List<JCTree> l = unseen; l.nonEmpty() && l != seen; l = l.tail) {
JCTree outermostMemberDefPrev = outermostMemberDef;
if (outermostMemberDefPrev == null)
outermostMemberDef = l.head;
l.head = translate(l.head);
outermostMemberDef = outermostMemberDefPrev;
}
seen = unseen;
}
// Convert a protected modifier to public, mask static modifier.
if ((tree.mods.flags & PROTECTED) != 0)
tree.mods.flags |= PUBLIC;
tree.mods.flags &= ClassFlags;
// Convert name to flat representation, replacing '.' by '$'.
tree.name = Convert.shortName(currentClass.flatName());
for (List<JCVariableDecl> l = fvdefs; l.nonEmpty(); l = l.tail) {
tree.defs = tree.defs.prepend(l.head);
enterSynthetic(tree.pos(), l.head.sym, currentClass.members());
}
if (currentClass.hasOuterInstance()) {
tree.defs = tree.defs.prepend(otdef);
enterSynthetic(tree.pos(), otdef.sym, currentClass.members());
}
proxies = proxies.leave();
outerThisStack = prevOuterThisStack;
// Append translated tree to `translated' queue.
translated.append(tree);
attrEnv = prevEnv;
currentClass = currentClassPrev;
currentMethodSym = currentMethodSymPrev;
// Return empty block {} as a placeholder for an inner class.
result = make_at(tree.pos()).Block(SYNTHETIC, List.<JCStatement>nil());
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree in project ceylon by eclipse.
the class Lower method makeTwrBlock.
private JCBlock makeTwrBlock(List<JCTree> resources, JCBlock block, boolean finallyCanCompleteNormally, int depth) {
if (resources.isEmpty())
return block;
// Add resource declaration or expression to block statements
ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
JCTree resource = resources.head;
JCExpression expr = null;
if (resource instanceof JCVariableDecl) {
JCVariableDecl var = (JCVariableDecl) resource;
expr = make.Ident(var.sym).setType(resource.type);
stats.add(var);
} else {
Assert.check(resource instanceof JCExpression);
VarSymbol syntheticTwrVar = new VarSymbol(SYNTHETIC | FINAL, makeSyntheticName(names.fromString("twrVar" + depth), twrVars), (resource.type.hasTag(BOT)) ? syms.autoCloseableType : resource.type, currentMethodSym);
twrVars.enter(syntheticTwrVar);
JCVariableDecl syntheticTwrVarDecl = make.VarDef(syntheticTwrVar, (JCExpression) resource);
expr = (JCExpression) make.Ident(syntheticTwrVar);
stats.add(syntheticTwrVarDecl);
}
// Add primaryException declaration
VarSymbol primaryException = new VarSymbol(SYNTHETIC, makeSyntheticName(names.fromString("primaryException" + depth), twrVars), syms.throwableType, currentMethodSym);
twrVars.enter(primaryException);
JCVariableDecl primaryExceptionTreeDecl = make.VarDef(primaryException, makeNull());
stats.add(primaryExceptionTreeDecl);
// Create catch clause that saves exception and then rethrows it
VarSymbol param = new VarSymbol(FINAL | SYNTHETIC, names.fromString("t" + target.syntheticNameChar()), syms.throwableType, currentMethodSym);
JCVariableDecl paramTree = make.VarDef(param, null);
JCStatement assign = make.Assignment(primaryException, make.Ident(param));
JCStatement rethrowStat = make.Throw(make.Ident(param));
JCBlock catchBlock = make.Block(0L, List.<JCStatement>of(assign, rethrowStat));
JCCatch catchClause = make.Catch(paramTree, catchBlock);
int oldPos = make.pos;
make.at(TreeInfo.endPos(block));
JCBlock finallyClause = makeTwrFinallyClause(primaryException, expr);
make.at(oldPos);
JCTry outerTry = make.Try(makeTwrBlock(resources.tail, block, finallyCanCompleteNormally, depth + 1), List.<JCCatch>of(catchClause), finallyClause);
outerTry.finallyCanCompleteNormally = finallyCanCompleteNormally;
stats.add(outerTry);
JCBlock newBlock = make.Block(0L, stats.toList());
return newBlock;
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree in project ceylon by eclipse.
the class Lower method visitBinary.
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()) {
result = translate(tree.rhs, formals.tail.head);
return;
}
break;
}
tree.rhs = translate(tree.rhs, formals.tail.head);
result = tree;
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree in project ceylon by eclipse.
the class Lower method abstractRval.
/**
* Construct an expression using the builder, with the given rval
* expression as an argument to the builder. However, the rval
* expression must be computed only once, even if used multiple
* times in the result of the builder. We do that by
* constructing a "let" expression that saves the rvalue into a
* temporary variable and then uses the temporary variable in
* place of the expression built by the builder. The complete
* resulting expression is of the form
* <pre>
* (let <b>TYPE</b> <b>TEMP</b> = <b>RVAL</b>;
* in (<b>BUILDER</b>(<b>TEMP</b>)))
* </pre>
* where <code><b>TEMP</b></code> is a newly declared variable
* 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 = new VarSymbol(FINAL | SYNTHETIC, names.fromString(target.syntheticNameChar() + "" + rval.hashCode()), type, currentMethodSym);
rval = convert(rval, type);
// XXX cast
JCVariableDecl def = make.VarDef(var, (JCExpression) rval);
JCTree built = builder.build(make.Ident(var));
JCTree res = make.LetExpr(def, built);
res.type = built.type;
return res;
}
Aggregations