Search in sources :

Example 26 with JCStatement

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

the class ExpressionTransformer method transformSuperInvocation.

// 
// Invocations
public void transformSuperInvocation(Tree.ExtendedType extendedType, ClassDefinitionBuilder classBuilder) {
    HasErrorException error = errors().getFirstExpressionErrorAndMarkBrokenness(extendedType);
    if (error != null) {
        classBuilder.getInitBuilder().delegateCall(this.makeThrowUnresolvedCompilationError(error));
        return;
    }
    if (extendedType.getInvocationExpression() != null && extendedType.getInvocationExpression().getPositionalArgumentList() != null) {
        Declaration primaryDeclaration = ((Tree.MemberOrTypeExpression) extendedType.getInvocationExpression().getPrimary()).getDeclaration();
        java.util.List<ParameterList> paramLists = ((Functional) primaryDeclaration).getParameterLists();
        if (paramLists.isEmpty()) {
            classBuilder.getInitBuilder().delegateCall(at(extendedType).Exec(makeErroneous(extendedType, "compiler bug: missing parameter list in extends clause: " + primaryDeclaration.getName() + " must be invoked")));
        } else {
            boolean prevFnCall = withinInvocation(true);
            try {
                JCStatement superExpr = transformConstructorDelegation(extendedType, new CtorDelegation(null, primaryDeclaration), extendedType.getInvocationExpression(), classBuilder, false);
                classBuilder.getInitBuilder().delegateCall(superExpr);
            } finally {
                withinInvocation(prevFnCall);
            }
        }
    }
}
Also used : Functional(org.eclipse.ceylon.model.typechecker.model.Functional) HasErrorException(org.eclipse.ceylon.compiler.java.codegen.recovery.HasErrorException) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement)

Example 27 with JCStatement

use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement 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 28 with JCStatement

use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement 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 29 with JCStatement

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

the class ExpressionTransformer method transform.

public JCStatement transform(Tree.SpecifierStatement op) {
    // SpecifierStatement do not return any value, therefore we don't care about the type of the expressions.
    inStatement = true;
    JCStatement result;
    HasErrorException error = errors().getFirstExpressionErrorAndMarkBrokenness(op.getBaseMemberExpression());
    if (error != null) {
        result = this.makeThrowUnresolvedCompilationError(error);
    } else if ((error = errors().getFirstExpressionErrorAndMarkBrokenness(op.getSpecifierExpression().getExpression())) != null) {
        result = this.makeThrowUnresolvedCompilationError(error);
    } else {
        result = at(op).Exec(transformAssignment(op, op.getBaseMemberExpression(), op.getSpecifierExpression().getExpression()));
    }
    inStatement = false;
    return result;
}
Also used : HasErrorException(org.eclipse.ceylon.compiler.java.codegen.recovery.HasErrorException) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement)

Example 30 with JCStatement

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

the class StatementTransformer method openOuterSubstitutionIfNeeded.

JCStatement openOuterSubstitutionIfNeeded(Value value, Type t, int modifiers) {
    JCStatement result = null;
    if (value.isSpecifiedInForElse()) {
        DeferredSpecification d = new DeferredSpecification(value, modifiers, t);
        deferredSpecifications.put(value, d);
        result = d.openOuterSubstitution();
    }
    return result;
}
Also used : JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement)

Aggregations

JCStatement (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement)73 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)52 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)38 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)31 Type (org.eclipse.ceylon.model.typechecker.model.Type)29 SyntheticName (org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName)25 ListBuffer (org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer)21 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)18 JCVariableDecl (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl)16 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)15 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)13 Value (org.eclipse.ceylon.model.typechecker.model.Value)13 Function (org.eclipse.ceylon.model.typechecker.model.Function)12 HasErrorException (org.eclipse.ceylon.compiler.java.codegen.recovery.HasErrorException)11 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)11 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)10 Expression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression)10 JCBlock (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCBlock)10 JCPrimitiveTypeTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCPrimitiveTypeTree)10 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)10