Search in sources :

Example 1 with TreeTranslator

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;
}
Also used : MethodType(org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType) Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) TreeTranslator(org.eclipse.ceylon.langtools.tools.javac.tree.TreeTranslator) VarSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.VarSymbol)

Aggregations

VarSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.VarSymbol)1 Type (org.eclipse.ceylon.langtools.tools.javac.code.Type)1 MethodType (org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType)1 TreeTranslator (org.eclipse.ceylon.langtools.tools.javac.tree.TreeTranslator)1