use of org.eclipse.ceylon.langtools.tools.javac.tree.TreeTranslator in project ceylon by eclipse.
the class LambdaToMethod method makeLambdaStatementBody.
private JCBlock makeLambdaStatementBody(JCBlock block, final JCMethodDecl lambdaMethodDecl, boolean completeNormally) {
final Type restype = lambdaMethodDecl.type.getReturnType();
final boolean isTarget_void = restype.hasTag(VOID);
boolean isTarget_Void = types.isSameType(restype, types.boxedClass(syms.voidType).type);
class LambdaBodyTranslator extends TreeTranslator {
@Override
public void visitClassDef(JCClassDecl tree) {
// do NOT recurse on any inner classes
result = tree;
}
@Override
public void visitLambda(JCLambda tree) {
// do NOT recurse on any nested lambdas
result = tree;
}
@Override
public void visitReturn(JCReturn tree) {
boolean isLambda_void = tree.expr == null;
if (isTarget_void && !isLambda_void) {
// Void to void conversion:
// { TYPE $loc = RET-EXPR; return; }
VarSymbol loc = makeSyntheticVar(0, names.fromString("$loc"), tree.expr.type, lambdaMethodDecl.sym);
JCVariableDecl varDef = make.VarDef(loc, tree.expr);
result = make.Block(0, List.<JCStatement>of(varDef, make.Return(null)));
} else if (!isTarget_void || !isLambda_void) {
// non-void to non-void conversion:
// return (TYPE)RET-EXPR;
tree.expr = transTypes.coerce(attrEnv, tree.expr, restype);
result = tree;
} else {
result = tree;
}
}
}
JCBlock trans_block = new LambdaBodyTranslator().translate(block);
if (completeNormally && isTarget_Void) {
// there's no return statement and the lambda (possibly inferred)
// return type is java.lang.Void; emit a synthetic return statement
trans_block.stats = trans_block.stats.append(make.Return(make.Literal(BOT, null).setType(syms.botType)));
}
return trans_block;
}
Aggregations