Search in sources :

Example 16 with JCVariableDecl

use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl in project ceylon by eclipse.

the class StatementTransformer method transformCaseIs.

/**
 * Transform a "case(is ...)"
 * @param selectorAlias
 * @param caseClause
 * @param isCase
 * @param last
 * @return
 */
private JCStatement transformCaseIs(Naming.SyntheticName selectorAlias, Tree.CaseClause caseClause, String tmpVar, Tree.Term outerExpression, Type expectedType, Tree.IsCase isCase, JCStatement last, Type expressionType) {
    at(isCase);
    // Use the type of the variable, which is more precise than the type we test for.
    Type varType = isCase.getVariable().getDeclarationModel().getType();
    Type caseType = getIsCaseType(isCase);
    // note: There's no point using makeOptimizedTypeTest() because cases are disjoint
    // anyway and the cheap cases get evaluated first.
    JCExpression cond = makeTypeTest(null, selectorAlias, caseType, expressionType);
    String name = isCase.getVariable().getIdentifier().getText();
    TypedDeclaration varDecl = isCase.getVariable().getDeclarationModel();
    Naming.SyntheticName tmpVarName = selectorAlias;
    Name substVarName = naming.aliasName(name);
    // Want raw type for instanceof since it can't be used with generic types
    JCExpression rawToTypeExpr = makeJavaType(varType, JT_NO_PRIMITIVES | JT_RAW);
    // Substitute variable with the correct type to use in the rest of the code block
    JCExpression tmpVarExpr = at(isCase).TypeCast(rawToTypeExpr, tmpVarName.makeIdent());
    JCExpression toTypeExpr;
    if (isCeylonBasicType(varType) && varDecl.getUnboxed() == true) {
        toTypeExpr = makeJavaType(varType);
        tmpVarExpr = unboxType(tmpVarExpr, varType);
    } else {
        toTypeExpr = makeJavaType(varType, JT_NO_PRIMITIVES);
    }
    // The variable holding the result for the code inside the code block
    JCVariableDecl decl2 = at(isCase).VarDef(make().Modifiers(FINAL), substVarName, toTypeExpr, tmpVarExpr);
    // Prepare for variable substitution in the following code block
    Substitution prevSubst = naming.addVariableSubst(varDecl, substVarName.toString());
    List<JCStatement> stats = List.<JCStatement>of(decl2);
    stats = stats.appendList(transformCaseClause(caseClause, tmpVar, outerExpression, expectedType));
    JCBlock block = at(isCase).Block(0, stats);
    // Deactivate the above variable substitution
    prevSubst.close();
    last = make().If(cond, block, last);
    return last;
}
Also used : TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCBlock(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCBlock) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) Substitution(org.eclipse.ceylon.compiler.java.codegen.Naming.Substitution) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) JCVariableDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl) Name(org.eclipse.ceylon.langtools.tools.javac.util.Name) CName(org.eclipse.ceylon.compiler.java.codegen.Naming.CName) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName)

Example 17 with JCVariableDecl

use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl in project ceylon by eclipse.

the class StatementTransformer method transformCatchesIfElseIf.

/**
 * Transforms a list of {@code CatchClause}s to a single {@code JCCatch}
 * containing and if/else if chain for finding the appropriate catch block.
 * @see #transformCatchesPolymorphic(java.util.List)
 */
private List<JCCatch> transformCatchesIfElseIf(java.util.List<Tree.CatchClause> catchClauses) {
    Type supertype = intersectionOfCatchClauseTypes(catchClauses);
    JCExpression exceptionType = makeJavaType(supertype, JT_CATCH | JT_RAW);
    SyntheticName exceptionVar = naming.alias("exception");
    JCVariableDecl param = make().VarDef(make().Modifiers(Flags.FINAL), exceptionVar.asName(), exceptionType, null);
    ArrayList<Tree.CatchClause> reversed = new ArrayList<Tree.CatchClause>(catchClauses);
    Collections.reverse(reversed);
    JCStatement elsePart = make().Throw(exceptionVar.makeIdent());
    for (Tree.CatchClause catchClause : reversed) {
        Tree.Variable caughtVar = catchClause.getCatchVariable().getVariable();
        Type caughtType = caughtVar.getType().getTypeModel();
        List<JCStatement> catchBlock = transformBlock(catchClause.getBlock());
        catchBlock = catchBlock.prepend(makeVar(FINAL, caughtVar.getIdentifier().getText(), makeJavaType(caughtType), expressionGen().applyErasureAndBoxing(exceptionVar.makeIdent(), supertype, true, true, BoxingStrategy.BOXED, caughtType, 0)));
        elsePart = make().If(makeOptimizedTypeTest(null, exceptionVar, caughtType, supertype), make().Block(0, catchBlock), elsePart);
    }
    return List.of(make().Catch(param, make().Block(0, List.<JCStatement>of(elsePart))));
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) Variable(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Variable) ArrayList(java.util.ArrayList) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) JCVariableDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl)

Example 18 with JCVariableDecl

use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl in project ceylon by eclipse.

the class StatementTransformer method transform.

public JCStatement transform(Tree.TryCatchStatement t) {
    Tree.TryClause tryClause = t.getTryClause();
    at(tryClause);
    JCBlock tryBlock = transform(tryClause.getBlock());
    Tree.ResourceList resList = tryClause.getResourceList();
    if (resList != null) {
        ArrayList<Tree.Resource> resources = new ArrayList<Tree.Resource>(resList.getResources());
        Collections.reverse(resources);
        for (Tree.Resource res : resources) {
            List<JCStatement> stats = List.nil();
            Tree.Expression resExpr;
            String resVarName;
            if (res.getExpression() != null) {
                resExpr = res.getExpression();
                resVarName = naming.newTemp("try");
            } else if (res.getVariable() != null) {
                Tree.Variable var = res.getVariable();
                resExpr = var.getSpecifierExpression().getExpression();
                resVarName = var.getIdentifier().getText();
            } else {
                throw new BugException(res, "missing resource expression");
            }
            final TryResourceTransformation resourceTx;
            if (typeFact().getDestroyableType().isSupertypeOf(resExpr.getTypeModel())) {
                resourceTx = destroyableResource;
            } else if (typeFact().getObtainableType().isSupertypeOf(resExpr.getTypeModel())) {
                resourceTx = obtainableResource;
            } else if (javacJavaTypeToProducedType(syms().autoCloseableType).isSupertypeOf(resExpr.getTypeModel())) {
                resourceTx = javaAutoCloseableResource;
            } else {
                throw BugException.unhandledTypeCase(resExpr.getTypeModel());
            }
            Type resVarType = resExpr.getTypeModel();
            Type resVarExpectedType = resourceTx.getType();
            // CloseableType $var = resource-expression
            JCExpression expr = expressionGen().transformExpression(resExpr);
            JCExpression javaType = makeJavaType(resVarType);
            JCVariableDecl var = makeVar(FINAL, resVarName, javaType, expr);
            stats = stats.append(var);
            if (resourceTx.getInitMethodName() != null) {
                JCExpression resVar0 = expressionGen().applyErasureAndBoxing(makeUnquotedIdent(resVarName), resVarType, true, BoxingStrategy.BOXED, resVarExpectedType);
                JCMethodInvocation openCall = make().Apply(null, makeQualIdent(resVar0, resourceTx.getInitMethodName()), List.<JCExpression>nil());
                stats = stats.append(make().Exec(openCall));
            }
            // Exception $tpmex = null;
            String innerExTmpVarName = naming.newTemp("ex");
            JCExpression innerExType = makeJavaType(typeFact().getThrowableType(), JT_CATCH);
            JCVariableDecl innerExTmpVar = makeVar(innerExTmpVarName, innerExType, makeNull());
            stats = stats.append(innerExTmpVar);
            // $tmpex = ex;
            List<JCStatement> innerCatchStats = List.nil();
            Name innerCatchVarName = naming.tempName("ex");
            JCAssign exTmpAssign = make().Assign(makeUnquotedIdent(innerExTmpVarName), make().Ident(innerCatchVarName));
            innerCatchStats = innerCatchStats.append(make().Exec(exTmpAssign));
            // throw ex;
            JCThrow innerCatchThrow = make().Throw(make().Ident(innerCatchVarName));
            innerCatchStats = innerCatchStats.append(innerCatchThrow);
            JCBlock innerCatchBlock = make().Block(0, innerCatchStats);
            // $var.close() /// ((Closeable)$var).close()
            JCExpression exarg = makeUnquotedIdent(innerExTmpVarName);
            JCExpression resVar1 = expressionGen().applyErasureAndBoxing(makeUnquotedIdent(resVarName), resVarType, true, BoxingStrategy.BOXED, resVarExpectedType);
            JCExpression closeCall = resourceTx.makeRecover(resVar1, exarg);
            JCBlock closeTryBlock = make().Block(0, List.<JCStatement>of(make().Exec(closeCall)));
            // try { $var.close() } catch (Exception closex) { $tmpex.addSuppressed(closex); }
            Name closeCatchVarName = naming.tempName("closex");
            JCExpression closeCatchExType = makeJavaType(typeFact().getThrowableType(), JT_CATCH);
            JCVariableDecl closeCatchVar = make().VarDef(make().Modifiers(Flags.FINAL), closeCatchVarName, closeCatchExType, null);
            JCExpression addarg = make().Ident(closeCatchVarName);
            JCMethodInvocation addSuppressedCall = make().Apply(null, makeQualIdent(makeUnquotedIdent(innerExTmpVarName), "addSuppressed"), List.<JCExpression>of(addarg));
            JCStatement catchForClose;
            if (resourceTx != javaAutoCloseableResource) {
                // Obtainable.release() and Destroyable.close() could
                // rethrow the originating exception, so guard against
                // self-supression (which causes addSuppressed() to throw
                catchForClose = make().If(make().Binary(JCTree.Tag.NE, makeUnquotedIdent(innerExTmpVarName), make().Ident(closeCatchVarName)), make().Block(0, List.<JCStatement>of(make().Exec(addSuppressedCall))), null);
            } else {
                // AutoClosable can't rethrow the originating exception,
                // so no need to worry about self suppression
                catchForClose = make().Exec(addSuppressedCall);
            }
            JCCatch closeCatch = make().Catch(closeCatchVar, make().Block(0, List.<JCStatement>of(catchForClose)));
            JCTry closeTry = at(res).Try(closeTryBlock, List.<JCCatch>of(closeCatch), null);
            // $var.close() /// ((Closeable)$var).close()
            JCExpression exarg2 = makeUnquotedIdent(innerExTmpVarName);
            JCExpression resVar2 = expressionGen().applyErasureAndBoxing(makeUnquotedIdent(resVarName), resVarType, true, BoxingStrategy.BOXED, resVarExpectedType);
            JCExpression closeCall2 = resourceTx.makeRecover(resVar1, exarg);
            // if ($tmpex != null) { ... } else { ... }
            JCBinary closeCatchCond = make().Binary(JCTree.Tag.NE, makeUnquotedIdent(innerExTmpVarName), makeNull());
            JCIf closeCatchIf = make().If(closeCatchCond, make().Block(0, List.<JCStatement>of(closeTry)), make().Block(0, List.<JCStatement>of(make().Exec(closeCall2))));
            // try { .... } catch (Exception ex) { $tmpex=ex; throw ex; }
            // finally { try { $var.close() } catch (Exception closex) { } }
            JCExpression innerCatchExType = makeJavaType(typeFact().getThrowableType(), JT_CATCH);
            JCVariableDecl innerCatchVar = make().VarDef(make().Modifiers(Flags.FINAL), innerCatchVarName, innerCatchExType, null);
            JCCatch innerCatch = make().Catch(innerCatchVar, innerCatchBlock);
            JCBlock innerFinallyBlock = make().Block(0, List.<JCStatement>of(closeCatchIf));
            JCTry innerTry = at(res).Try(tryBlock, List.<JCCatch>of(innerCatch), innerFinallyBlock);
            stats = stats.append(innerTry);
            tryBlock = at(res).Block(0, stats);
        }
    }
    final List<JCCatch> catches;
    if (usePolymorphicCatches(t.getCatchClauses())) {
        catches = transformCatchesPolymorphic(t.getCatchClauses());
    } else {
        catches = transformCatchesIfElseIf(t.getCatchClauses());
    }
    final JCBlock finallyBlock;
    Tree.FinallyClause finallyClause = t.getFinallyClause();
    if (finallyClause != null) {
        at(finallyClause);
        finallyBlock = transform(finallyClause.getBlock());
    } else {
        finallyBlock = null;
    }
    if (!catches.isEmpty() || finallyBlock != null) {
        return at(t).Try(tryBlock, catches, finallyBlock);
    } else {
        return tryBlock;
    }
}
Also used : Variable(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Variable) JCAssign(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAssign) ArrayList(java.util.ArrayList) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) Name(org.eclipse.ceylon.langtools.tools.javac.util.Name) CName(org.eclipse.ceylon.compiler.java.codegen.Naming.CName) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName) JCIf(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCIf) Expression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) JCThrow(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCThrow) JCBlock(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCBlock) JCBinary(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCBinary) JCVariableDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl) JCTry(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCTry) JCMethodInvocation(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCMethodInvocation) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) JCCatch(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCCatch)

Example 19 with JCVariableDecl

use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl in project ceylon by eclipse.

the class JavacTrees method getLub.

public TypeMirror getLub(CatchTree tree) {
    JCCatch ct = (JCCatch) tree;
    JCVariableDecl v = ct.param;
    if (v.type != null && v.type.getKind() == TypeKind.UNION) {
        UnionClassType ut = (UnionClassType) v.type;
        return ut.getLub();
    } else {
        return v.type;
    }
}
Also used : UnionClassType(org.eclipse.ceylon.langtools.tools.javac.code.Type.UnionClassType) JCCatch(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCCatch) JCVariableDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl)

Example 20 with JCVariableDecl

use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl in project ceylon by eclipse.

the class JavacTrees method getAttrContext.

private Env<AttrContext> getAttrContext(TreePath path) {
    if (// implicit null-check
    !(path.getLeaf() instanceof JCTree))
        throw new IllegalArgumentException();
    // will already have been entered.
    if (javacTaskImpl != null) {
        try {
            javacTaskImpl.enter(null);
        } catch (IOException e) {
            throw new Error("unexpected error while entering symbols: " + e);
        }
    }
    JCCompilationUnit unit = (JCCompilationUnit) path.getCompilationUnit();
    Copier copier = createCopier(treeMaker.forToplevel(unit));
    Env<AttrContext> env = null;
    JCMethodDecl method = null;
    JCVariableDecl field = null;
    List<Tree> l = List.nil();
    TreePath p = path;
    while (p != null) {
        l = l.prepend(p.getLeaf());
        p = p.getParentPath();
    }
    for (; l.nonEmpty(); l = l.tail) {
        Tree tree = l.head;
        switch(tree.getKind()) {
            case COMPILATION_UNIT:
                // System.err.println("COMP: " + ((JCCompilationUnit)tree).sourcefile);
                env = enter.getTopLevelEnv((JCCompilationUnit) tree);
                break;
            case ANNOTATION_TYPE:
            case CLASS:
            case ENUM:
            case INTERFACE:
                // System.err.println("CLASS: " + ((JCClassDecl)tree).sym.getSimpleName());
                env = enter.getClassEnv(((JCClassDecl) tree).sym);
                break;
            case METHOD:
                // System.err.println("METHOD: " + ((JCMethodDecl)tree).sym.getSimpleName());
                method = (JCMethodDecl) tree;
                env = memberEnter.getMethodEnv(method, env);
                break;
            case VARIABLE:
                // System.err.println("FIELD: " + ((JCVariableDecl)tree).sym.getSimpleName());
                field = (JCVariableDecl) tree;
                break;
            case BLOCK:
                {
                    // System.err.println("BLOCK: ");
                    if (method != null) {
                        try {
                            Assert.check(method.body == tree);
                            method.body = copier.copy((JCBlock) tree, (JCTree) path.getLeaf());
                            env = attribStatToTree(method.body, env, copier.leafCopy);
                        } finally {
                            method.body = (JCBlock) tree;
                        }
                    } else {
                        JCBlock body = copier.copy((JCBlock) tree, (JCTree) path.getLeaf());
                        env = attribStatToTree(body, env, copier.leafCopy);
                    }
                    return env;
                }
            default:
                // System.err.println("DEFAULT: " + tree.getKind());
                if (field != null && field.getInitializer() == tree) {
                    env = memberEnter.getInitEnv(field, env);
                    JCExpression expr = copier.copy((JCExpression) tree, (JCTree) path.getLeaf());
                    env = attribExprToTree(expr, env, copier.leafCopy);
                    return env;
                }
        }
    }
    return (field != null) ? memberEnter.getInitEnv(field, env) : env;
}
Also used : JCCompilationUnit(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCCompilationUnit) JCClassDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCClassDecl) JCBlock(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCBlock) JCMethodDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCMethodDecl) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) IOException(java.io.IOException) AttrContext(org.eclipse.ceylon.langtools.tools.javac.comp.AttrContext) JCVariableDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) TreePath(org.eclipse.ceylon.langtools.source.util.TreePath) TreeCopier(org.eclipse.ceylon.langtools.tools.javac.tree.TreeCopier) CatchTree(org.eclipse.ceylon.langtools.source.tree.CatchTree) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) CompilationUnitTree(org.eclipse.ceylon.langtools.source.tree.CompilationUnitTree) Tree(org.eclipse.ceylon.langtools.source.tree.Tree)

Aggregations

JCVariableDecl (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl)31 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)25 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)21 JCStatement (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement)16 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)14 Type (org.eclipse.ceylon.model.typechecker.model.Type)12 SyntheticName (org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName)10 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)7 JCBlock (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCBlock)6 ListBuffer (org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer)6 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)5 Expression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression)5 JCCatch (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCCatch)5 JCNewClass (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass)5 Name (org.eclipse.ceylon.langtools.tools.javac.util.Name)5 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)4 CName (org.eclipse.ceylon.compiler.java.codegen.Naming.CName)3 Variable (org.eclipse.ceylon.compiler.typechecker.tree.Tree.Variable)3 JCAssign (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAssign)3 JCMethodDecl (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCMethodDecl)3