Search in sources :

Example 6 with JCVariableDecl

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

the class ExpressionTransformer method transform.

public JCExpression transform(Tree.ScaleOp op) {
    OperatorTranslation operator = Operators.getOperator(Tree.ScaleOp.class);
    Tree.Term scalableTerm = op.getRightTerm();
    Type scalableTermType = getSupertype(scalableTerm, typeFact().getScalableDeclaration());
    SyntheticName scaleableName = naming.alias("scalable");
    JCVariableDecl scaleable = makeVar(scaleableName, makeJavaType(scalableTermType, JT_NO_PRIMITIVES), transformExpression(scalableTerm, BoxingStrategy.BOXED, scalableTermType));
    Tree.Term scaleTerm = op.getLeftTerm();
    SyntheticName scaleName = naming.alias("scale");
    Type scaleType = getTypeArgument(scalableTermType, 0);
    JCExpression scaleValue;
    if (isCeylonInteger(scaleTerm.getTypeModel()) && isCeylonFloat(scaleType)) {
        // Disgusting coercion
        scaleValue = transformExpression(scaleTerm, BoxingStrategy.UNBOXED, scalableTerm.getTypeModel());
        scaleValue = boxType(scaleValue, typeFact().getFloatType());
    } else {
        scaleValue = transformExpression(scaleTerm, BoxingStrategy.BOXED, scaleType);
    }
    JCVariableDecl scale = makeVar(scaleName, makeJavaType(scaleType, JT_NO_PRIMITIVES), scaleValue);
    at(op);
    return make().LetExpr(List.<JCStatement>of(scale, scaleable), transformOverridableBinaryOperator(op, operator, OptimisationStrategy.NONE, scaleableName.makeIdent(), scaleName.makeIdent(), null, null, op.getTypeModel()).build());
}
Also used : UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) Term(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName) JCVariableDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl) OperatorTranslation(org.eclipse.ceylon.compiler.java.codegen.Operators.OperatorTranslation) AssignmentOperatorTranslation(org.eclipse.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation)

Example 7 with JCVariableDecl

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

the class ExpressionTransformer method transform.

// Postfix operator
public JCExpression transform(Tree.PostfixOperatorExpression expr) {
    OperatorTranslation operator = Operators.getOperator(expr.getClass());
    if (operator == null) {
        return makeErroneous(expr, "compiler bug " + expr.getNodeType() + " is not yet supported");
    }
    OptimisationStrategy optimisationStrategy = operator.getUnOpOptimisationStrategy(expr, expr.getTerm(), this);
    boolean canOptimise = optimisationStrategy.useJavaOperator();
    // only fully optimise if we don't have to access the getter/setter
    if (canOptimise && CodegenUtil.isDirectAccessVariable(expr.getTerm())) {
        JCExpression term = transformExpression(expr.getTerm(), BoxingStrategy.UNBOXED, expr.getTypeModel(), EXPR_WIDEN_PRIM);
        return at(expr).Unary(operator.javacOperator, term);
    }
    Tree.Term term = unwrapExpressionUntilTerm(expr.getTerm());
    Type returnType = term.getTypeModel();
    List<JCVariableDecl> decls = List.nil();
    List<JCStatement> stats = List.nil();
    JCExpression result = null;
    // we can optimise that case a bit sometimes
    boolean boxResult = !canOptimise;
    // (let $tmp = attr; attr = $tmp.getSuccessor(); $tmp;)
    if (term instanceof Tree.BaseMemberExpression || // special case for java statics Foo.attr where Foo does not need to be evaluated
    (term instanceof Tree.QualifiedMemberExpression && ((Tree.QualifiedMemberExpression) term).getStaticMethodReference())) {
        JCExpression getter;
        if (term instanceof Tree.BaseMemberExpression)
            getter = transform((Tree.BaseMemberExpression) term, null);
        else
            getter = transformMemberExpression((Tree.QualifiedMemberExpression) term, null, null);
        at(expr);
        // Type $tmp = attr
        JCExpression exprType = makeJavaType(returnType, boxResult ? JT_NO_PRIMITIVES : 0);
        Name varName = naming.tempName("op");
        // make sure we box the results if necessary
        getter = applyErasureAndBoxing(getter, term, boxResult ? BoxingStrategy.BOXED : BoxingStrategy.UNBOXED, returnType);
        JCVariableDecl tmpVar = make().VarDef(make().Modifiers(0), varName, exprType, getter);
        decls = decls.prepend(tmpVar);
        // attr = $tmp.getSuccessor()
        JCExpression successor;
        if (canOptimise) {
            // use +1/-1 if we can optimise a bit
            successor = make().Binary(operator == OperatorTranslation.UNARY_POSTFIX_INCREMENT ? JCTree.Tag.PLUS : JCTree.Tag.MINUS, make().Ident(varName), makeInteger(1));
            successor = unAutoPromote(successor, returnType, expr.getSmall());
        } else {
            successor = make().Apply(null, makeSelect(make().Ident(varName), operator.getCeylonMethodName()), List.<JCExpression>nil());
            // make sure the result is boxed if necessary, the result of successor/predecessor is always boxed
            successor = boxUnboxIfNecessary(successor, true, term.getTypeModel(), CodegenUtil.getBoxingStrategy(term));
        }
        JCExpression assignment = makeAssignment(expr, term, transformAssignmentLhs(expr, term), successor);
        stats = stats.prepend(at(expr).Exec(assignment));
        // $tmp
        result = make().Ident(varName);
    } else if (term instanceof Tree.QualifiedMemberExpression) {
        // e.attr++
        // (let $tmpE = e, $tmpV = $tmpE.attr; $tmpE.attr = $tmpV.getSuccessor(); $tmpV;)
        Tree.QualifiedMemberExpression qualified = (Tree.QualifiedMemberExpression) term;
        boolean isSuper = isSuperOrSuperOf(qualified.getPrimary());
        boolean isPackage = isPackageQualified(qualified);
        // transform the primary, this will get us a boxed primary
        JCExpression e = transformQualifiedMemberPrimary(qualified);
        at(expr);
        // Type $tmpE = e
        JCExpression exprType = makeJavaType(qualified.getTarget().getQualifyingType(), JT_NO_PRIMITIVES);
        Name varEName = naming.tempName("opE");
        JCVariableDecl tmpEVar = make().VarDef(make().Modifiers(0), varEName, exprType, e);
        // Type $tmpV = $tmpE.attr
        JCExpression attrType = makeJavaType(returnType, boxResult ? JT_NO_PRIMITIVES : 0);
        Name varVName = naming.tempName("opV");
        JCExpression getter;
        if (isSuper) {
            getter = transformMemberExpression(qualified, transformSuper(qualified), null);
        } else if (isPackage) {
            getter = transformMemberExpression(qualified, null, null);
        } else {
            getter = transformMemberExpression(qualified, make().Ident(varEName), null);
        }
        // make sure we box the results if necessary
        getter = applyErasureAndBoxing(getter, term, boxResult ? BoxingStrategy.BOXED : BoxingStrategy.UNBOXED, returnType);
        JCVariableDecl tmpVVar = make().VarDef(make().Modifiers(0), varVName, attrType, getter);
        decls = decls.prepend(tmpVVar);
        if (!isSuper && !isPackage) {
            // define all the variables
            decls = decls.prepend(tmpEVar);
        }
        // $tmpE.attr = $tmpV.getSuccessor()
        JCExpression successor;
        if (canOptimise) {
            // use +1/-1 if we can optimise a bit
            successor = make().Binary(operator == OperatorTranslation.UNARY_POSTFIX_INCREMENT ? JCTree.Tag.PLUS : JCTree.Tag.MINUS, make().Ident(varVName), makeInteger(1));
            successor = unAutoPromote(successor, returnType, expr.getSmall());
        } else {
            successor = make().Apply(null, makeSelect(make().Ident(varVName), operator.getCeylonMethodName()), List.<JCExpression>nil());
            // make sure the result is boxed if necessary, the result of successor/predecessor is always boxed
            successor = boxUnboxIfNecessary(successor, true, term.getTypeModel(), CodegenUtil.getBoxingStrategy(term));
        }
        JCExpression assignment = makeAssignment(expr, term, qualifyLhs(expr, term, isSuper ? transformSuper(qualified) : make().Ident(varEName)), successor);
        stats = stats.prepend(at(expr).Exec(assignment));
        // $tmpV
        result = make().Ident(varVName);
    } else {
        return makeErroneous(term, "compiler bug: " + term.getNodeType() + " is not supported yet");
    }
    return make().LetExpr(decls, stats, result);
}
Also used : Term(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) JCVariableDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl) OperatorTranslation(org.eclipse.ceylon.compiler.java.codegen.Operators.OperatorTranslation) AssignmentOperatorTranslation(org.eclipse.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation) Name(org.eclipse.ceylon.langtools.tools.javac.util.Name) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName) UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) OptimisationStrategy(org.eclipse.ceylon.compiler.java.codegen.Operators.OptimisationStrategy)

Example 8 with JCVariableDecl

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

the class ExpressionTransformer method transformAssignAndReturnOperation.

private JCExpression transformAssignAndReturnOperation(Node operator, Tree.Term term, boolean boxResult, Type valueType, Type returnType, AssignAndReturnOperationFactory factory) {
    List<JCVariableDecl> decls = List.nil();
    List<JCStatement> stats = List.nil();
    JCExpression result = null;
    // (let $tmp = OP(attr); attr = $tmp; $tmp)
    if (term instanceof Tree.BaseMemberExpression || (term instanceof Tree.IndexExpression) || // special case for java statics Foo.attr where Foo does not need to be evaluated
    (term instanceof Tree.QualifiedMemberExpression && ((Tree.QualifiedMemberExpression) term).getStaticMethodReference())) {
        JCExpression getter;
        if (term instanceof Tree.BaseMemberExpression)
            getter = transform((Tree.BaseMemberExpression) term, null);
        else if (term instanceof Tree.IndexExpression)
            getter = null;
        else
            getter = transformMemberExpression((Tree.QualifiedMemberExpression) term, null, null);
        at(operator);
        // Type $tmp = OP(attr);
        JCExpression exprType = makeJavaType(returnType, boxResult ? JT_NO_PRIMITIVES : 0);
        Name varName = naming.tempName("op");
        // make sure we box the results if necessary
        getter = applyErasureAndBoxing(getter, term, boxResult ? BoxingStrategy.BOXED : BoxingStrategy.UNBOXED, valueType);
        JCExpression newValue = factory.getNewValue(getter);
        // no need to box/unbox here since newValue and $tmpV share the same boxing type
        JCVariableDecl tmpVar = make().VarDef(make().Modifiers(0), varName, exprType, newValue);
        decls = decls.prepend(tmpVar);
        // attr = $tmp
        // make sure the result is unboxed if necessary, $tmp may be boxed
        JCExpression value = make().Ident(varName);
        BoxingStrategy boxingStrategy = CodegenUtil.getBoxingStrategy(term);
        value = applyErasureAndBoxing(value, returnType, boxResult, boxingStrategy, valueType);
        JCExpression assignment = makeAssignment(operator, term, transformAssignmentLhs(operator, term), value);
        stats = stats.prepend(at(operator).Exec(assignment));
        // $tmp
        // return, with the box type we asked for
        result = make().Ident(varName);
    } else if (term instanceof Tree.QualifiedMemberExpression) {
        // e.attr
        // (let $tmpE = e, $tmpV = OP($tmpE.attr); $tmpE.attr = $tmpV; $tmpV;)
        Tree.QualifiedMemberExpression qualified = (Tree.QualifiedMemberExpression) term;
        boolean isSuper = isSuperOrSuperOf(qualified.getPrimary());
        // transform the primary, this will get us a boxed primary
        JCExpression e = transformQualifiedMemberPrimary(qualified);
        at(operator);
        // Type $tmpE = e
        JCExpression exprType = makeJavaType(qualified.getTarget().getQualifyingType(), JT_NO_PRIMITIVES);
        Name varEName = naming.tempName("opE");
        JCVariableDecl tmpEVar = make().VarDef(make().Modifiers(0), varEName, exprType, e);
        // Type $tmpV = OP($tmpE.attr)
        JCExpression attrType = makeJavaType(returnType, boxResult ? JT_NO_PRIMITIVES : 0);
        Name varVName = naming.tempName("opV");
        JCExpression getter = transformMemberExpression(qualified, isSuper ? transformSuper(qualified) : make().Ident(varEName), null);
        // make sure we box the results if necessary
        getter = applyErasureAndBoxing(getter, term, boxResult ? BoxingStrategy.BOXED : BoxingStrategy.UNBOXED, valueType);
        JCExpression newValue = factory.getNewValue(getter);
        // no need to box/unbox here since newValue and $tmpV share the same boxing type
        JCVariableDecl tmpVVar = make().VarDef(make().Modifiers(0), varVName, attrType, newValue);
        // define all the variables
        decls = decls.prepend(tmpVVar);
        if (!isSuper) {
            decls = decls.prepend(tmpEVar);
        }
        // $tmpE.attr = $tmpV
        // make sure $tmpV is unboxed if necessary
        JCExpression value = make().Ident(varVName);
        BoxingStrategy boxingStrategy = CodegenUtil.getBoxingStrategy(term);
        value = applyErasureAndBoxing(value, returnType, boxResult, boxingStrategy, valueType);
        JCExpression assignment = makeAssignment(operator, term, qualifyLhs(operator, term, isSuper ? transformSuper(qualified) : make().Ident(varEName)), value);
        stats = stats.prepend(at(operator).Exec(assignment));
        // $tmpV
        // return, with the box type we asked for
        result = make().Ident(varVName);
    } else {
        return makeErroneous(operator, "compiler bug: " + term.getNodeType() + " is not a supported assign and return operator");
    }
    return make().LetExpr(decls, stats, result);
}
Also used : JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) 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) Name(org.eclipse.ceylon.langtools.tools.javac.util.Name) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName)

Example 9 with JCVariableDecl

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

the class StatementTransformer method transformCatchesPolymorphic.

/**
 * Transforms a list of {@code CatchClause}s to a corresponding list
 * of {@code JCCatch}.
 * @see #transformCatchesIfElseIf(java.util.List)
 */
private List<JCCatch> transformCatchesPolymorphic(java.util.List<Tree.CatchClause> catchClauses) {
    final ListBuffer<JCCatch> catches = new ListBuffer<JCCatch>();
    for (Tree.CatchClause catchClause : catchClauses) {
        at(catchClause);
        Tree.Variable variable = catchClause.getCatchVariable().getVariable();
        Type exceptionType = variable.getDeclarationModel().getType();
        JCExpression type = makeJavaType(exceptionType, JT_CATCH);
        JCVariableDecl param = make().VarDef(make().Modifiers(Flags.FINAL), names().fromString(variable.getIdentifier().getText()), type, null);
        catches.add(make().Catch(param, transform(catchClause.getBlock())));
    }
    return catches.toList();
}
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) ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer) 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) JCCatch(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCCatch) JCVariableDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl)

Example 10 with JCVariableDecl

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

the class StatementTransformer method transform.

/**
 * Transforms a Ceylon destructuring assignment to Java code.
 * @param stmt The Ceylon destructure
 * @return The Java tree
 */
List<JCStatement> transform(Tree.Destructure stmt) {
    List<JCStatement> result = List.nil();
    // Create temp var to hold result of expression
    Tree.Pattern pat = stmt.getPattern();
    Naming.SyntheticName tmpVarName = naming.synthetic(pat);
    Expression destExpr = stmt.getSpecifierExpression().getExpression();
    JCExpression typeExpr = makeJavaType(destExpr.getTypeModel());
    JCExpression expr = expressionGen().transformExpression(destExpr);
    at(stmt);
    JCVariableDecl tmpVar = makeVar(Flags.FINAL, tmpVarName, typeExpr, expr);
    result = result.append(tmpVar);
    // Now add the destructured variables
    List<VarDefBuilder> destructured = transformPattern(pat, tmpVarName.makeIdent());
    for (VarDefBuilder vdb : destructured) {
        Value v = vdb.var.getDeclarationModel();
        at(vdb.var);
        if (v.isClassMember() && v.isCaptured()) {
            AttributeDefinitionBuilder adb = AttributeDefinitionBuilder.getter(this, v.getName(), v);
            adb.immutable();
            classGen().current().attribute(adb);
            classGen().current().defs(vdb.buildDefOnly());
            result = result.append(make().Exec(make().Assign(vdb.name().makeIdentWithThis(), vdb.expr())));
        } else {
            result = result.append(vdb.build());
        }
    }
    return result;
}
Also used : JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) JCVariableDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) SpecifierOrInitializerExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression) Expression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) Value(org.eclipse.ceylon.model.typechecker.model.Value) 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) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName)

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