Search in sources :

Example 21 with Term

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term in project ceylon by eclipse.

the class ExpressionTransformer method transformSpreadArgument.

private ExpressionAndType transformSpreadArgument(SimpleInvocation invocation, int numArguments, int argIndex, BoxingStrategy boxingStrategy, Type parameterType) {
    ExpressionAndType exprAndType;
    final Type iteratedType = typeFact().getIteratedType(parameterType);
    final JCExpression expr;
    final JCExpression type;
    // optimise "*javaArray.iterable" into "javaArray" for java variadic parameters, since we can pass them just along
    if (invocation.isJavaVariadicMethod() && numArguments == argIndex + 1 && !invocation.isArgumentComprehension(argIndex)) {
        Expression argumentExpression = invocation.getArgumentExpression(argIndex);
        Term argument = Decl.unwrapExpressionsUntilTerm(argumentExpression);
        if (argument instanceof Tree.QualifiedMemberExpression) {
            Tree.QualifiedMemberExpression qualifiedMemberArgument = (Tree.QualifiedMemberExpression) argument;
            if ("iterable".equals(qualifiedMemberArgument.getIdentifier().getText()) && isJavaArray(qualifiedMemberArgument.getPrimary().getTypeModel())) {
                // just pass the array as-is
                // we don't care at all about unboxing or casting since we can't be dealing with boxing
                // and we generate our own cast, at least for non-primitive arrays where it may be ambiguous,
                // we could avoid the cast for non-type-parameter and non-Object arrays, but that's more expensive
                // to check for
                JCExpression primary = transformExpression(qualifiedMemberArgument.getPrimary());
                type = makeJavaType(typeFact().getSequenceType(iteratedType).getType());
                if (isJavaObjectArray(qualifiedMemberArgument.getPrimary().getTypeModel())) {
                    expr = make().TypeCast(makeJavaType(qualifiedMemberArgument.getPrimary().getTypeModel()), primary);
                } else {
                    expr = primary;
                }
                return new ExpressionAndType(expr, type);
            }
        }
    }
    // invoking f(a, *b), where declared f(A a, B* b)
    // we can have several remaining arguments and the last one is spread
    List<JCExpression> x = List.<JCExpression>nil();
    for (int ii = argIndex; ii < numArguments; ii++) {
        JCExpression argExpr = invocation.getTransformedArgumentExpression(ii);
        // the last parameter is spread and must be put first
        if (ii < numArguments - 1) {
            x = x.append(argExpr);
        } else {
            // convert to a Sequential if required
            Type argType = invocation.getArgumentType(ii);
            if (typeFact().isJavaArrayType(argType)) {
                String methodName;
                if (typeFact().getJavaIntArrayDeclaration().equals(argType.getDeclaration())) {
                    methodName = "org.eclipse.ceylon.compiler.java.language.IntArray.getIterable";
                } else if (typeFact().getJavaShortArrayDeclaration().equals(argType.getDeclaration())) {
                    methodName = "org.eclipse.ceylon.compiler.java.language.ShortArray.getIterable";
                } else if (typeFact().getJavaLongArrayDeclaration().equals(argType.getDeclaration())) {
                    methodName = "org.eclipse.ceylon.compiler.java.language.LongArray.getIterable";
                } else if (typeFact().getJavaByteArrayDeclaration().equals(argType.getDeclaration())) {
                    methodName = "org.eclipse.ceylon.compiler.java.language.ByteArray.getIterable";
                } else if (typeFact().getJavaBooleanArrayDeclaration().equals(argType.getDeclaration())) {
                    methodName = "org.eclipse.ceylon.compiler.java.language.BooleanArray.getIterable";
                } else if (typeFact().getJavaCharArrayDeclaration().equals(argType.getDeclaration())) {
                    methodName = "org.eclipse.ceylon.compiler.java.language.CharArray.getIterable";
                } else if (typeFact().getJavaFloatArrayDeclaration().equals(argType.getDeclaration())) {
                    methodName = "org.eclipse.ceylon.compiler.java.language.FloatArray.getIterable";
                } else if (typeFact().getJavaDoubleArrayDeclaration().equals(argType.getDeclaration())) {
                    methodName = "org.eclipse.ceylon.compiler.java.language.DoubleArray.getIterable";
                } else {
                    methodName = "org.eclipse.ceylon.compiler.java.language.ObjectArray.getIterable";
                }
                argExpr = make().Apply(null, naming.makeQuotedQualIdentFromString(methodName), List.<JCExpression>of(argExpr));
                argExpr = iterableToSequential(argExpr);
            } else if (typeFact().isSequentialType(argType)) {
            // we're good
            } else if (typeFact().isIterableType(argType)) {
                argExpr = iterableToSequential(argExpr);
            } else if (typeFact().isJavaIterableType(argType)) {
                argExpr = utilInvocation().toIterable(makeJavaType(iteratedType, JT_TYPE_ARGUMENT), makeReifiedTypeArgument(iteratedType), argExpr);
                argExpr = iterableToSequential(argExpr);
            }
            x = x.prepend(argExpr);
        }
    }
    if (invocation.isJavaVariadicMethod()) {
        // collect all the initial arguments and wrap into a Java array
        // first arg is the spread part
        JCExpression last = x.head;
        // remove it from x
        x = x.tail;
        Type lastType = invocation.getArgumentType(numArguments - 1);
        // must translate it into a Util call
        expr = sequenceToJavaArray(invocation, last, parameterType, boxingStrategy, lastType, x);
    } else {
        JCExpression typeExpr = makeJavaType(iteratedType, JT_TYPE_ARGUMENT);
        JCExpression sequentialExpr = utilInvocation().sequentialInstance(typeExpr, makeReifiedTypeArgument(iteratedType), x.head, x.tail);
        if (invocation.isParameterVariadicPlus(argIndex)) {
            expr = utilInvocation().castSequentialToSequence(sequentialExpr, iteratedType);
        } else {
            expr = sequentialExpr;
        }
    }
    type = makeJavaType(typeFact().getSequenceType(iteratedType).getType());
    exprAndType = new ExpressionAndType(expr, type);
    return exprAndType;
}
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) Expression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression) LetExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.LetExpression) 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) Term(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term) TreeUtil.unwrapExpressionUntilTerm(org.eclipse.ceylon.compiler.typechecker.tree.TreeUtil.unwrapExpressionUntilTerm)

Example 22 with Term

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term in project ceylon by eclipse.

the class ExpressionTransformer method transformLet.

// this one trusts the expected type
private JCExpression transformLet(LetExpression op, Type expectedType) {
    ListBuffer<JCStatement> defs = new ListBuffer<JCStatement>();
    for (Tree.Statement stmt : op.getLetClause().getVariables()) {
        defs.addAll(statementGen().transformVariableOrDestructure(stmt));
    }
    Tree.Term term = op.getLetClause().getExpression().getTerm();
    BoxingStrategy boxingStrategy = CodegenUtil.getBoxingStrategy(term);
    JCExpression expr = transformExpression(term, boxingStrategy, expectedType);
    at(op);
    if (isAnything(op.getTypeModel()) && CodegenUtil.isUnBoxed(term)) {
        defs.add(make().Exec(expr));
        expr = makeNull();
    }
    return make().LetExpr(defs.toList(), expr);
}
Also used : JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) Term(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term) ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer) 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)

Example 23 with Term

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term in project ceylon by eclipse.

the class BoxingDeclarationVisitor method visit.

@Override
public void visit(SpecifierStatement that) {
    TypedDeclaration declaration = that.getDeclaration();
    Function optimisedDeclaration = null;
    // make sure we detect the shortcut refinement inlining cases
    if (declaration instanceof Function) {
        if (that.getSpecifierExpression() != null && that.getSpecifierExpression() instanceof LazySpecifierExpression == false) {
            Tree.Term term = Decl.unwrapExpressionsUntilTerm(that.getSpecifierExpression().getExpression());
            if (term != null && term instanceof Tree.FunctionArgument) {
                optimisedDeclaration = ((Tree.FunctionArgument) term).getDeclarationModel();
                this.optimisedMethodSpecifiersToMethods.put(optimisedDeclaration, (Function) declaration);
            }
        }
    }
    try {
        super.visit(that);
    } finally {
        if (optimisedDeclaration != null)
            this.optimisedMethodSpecifiersToMethods.remove(optimisedDeclaration);
    }
    if (declaration == null)
        return;
    if (declaration instanceof Function) {
        visitMethod((Function) declaration, that);
    } else if (declaration instanceof Value)
        visitAttributeOrParameter(declaration, that);
}
Also used : TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) Function(org.eclipse.ceylon.model.typechecker.model.Function) FunctionArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.FunctionArgument) Term(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Value(org.eclipse.ceylon.model.typechecker.model.Value) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) LazySpecifierExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression)

Example 24 with Term

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term in project ceylon by eclipse.

the class BoxingDeclarationVisitor method visit.

@Override
public void visit(Tree.MethodDeclaration that) {
    super.visit(that);
    Function model = that.getDeclarationModel();
    visitMethod(that.getDeclarationModel(), that);
    SpecifierExpression specifierExpression = that.getSpecifierExpression();
    // See ClassTransformer.transformSpecifiedMethodBody for this logic
    if (model != null && model.isMember() && specifierExpression != null && specifierExpression.getExpression() != null) {
        boolean isLazy = specifierExpression instanceof Tree.LazySpecifierExpression;
        Term term = Decl.unwrapExpressionsUntilTerm(specifierExpression.getExpression());
        if (!isLazy && term instanceof Tree.FunctionArgument) {
            // this is inlined for member methods, so the term should inherit our boxing specs
            Function specifierModel = ((Tree.FunctionArgument) term).getDeclarationModel();
            if (specifierModel != null) {
                specifierModel.setUnboxed(model.getUnboxed());
            }
        }
    }
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) FunctionArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.FunctionArgument) SpecifierExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierExpression) LazySpecifierExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Term(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term) FunctionArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.FunctionArgument) LazySpecifierExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression)

Example 25 with Term

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term in project ceylon by eclipse.

the class BoxingVisitor method visit.

@Override
public void visit(Expression that) {
    Stack<Boolean> npebs = setPEB();
    super.visit(that);
    resetPEB(npebs);
    Term term = that.getTerm();
    propagateFromTerm(that, term);
    // which will need to be marked boxed
    if (term instanceof MemberOrTypeExpression) {
        Tree.MemberOrTypeExpression expr = (Tree.MemberOrTypeExpression) term;
        if (expr.getDeclaration() instanceof Function) {
            that.setUnboxed(false);
        }
    }
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) MemberOrTypeExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MemberOrTypeExpression) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Term(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term) TreeUtil.unwrapExpressionUntilTerm(org.eclipse.ceylon.compiler.typechecker.tree.TreeUtil.unwrapExpressionUntilTerm) StaticMemberOrTypeExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.StaticMemberOrTypeExpression) MemberOrTypeExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MemberOrTypeExpression)

Aggregations

Term (org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term)29 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)27 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)14 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)11 Type (org.eclipse.ceylon.model.typechecker.model.Type)11 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)11 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)10 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)10 Expression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression)6 Function (org.eclipse.ceylon.model.typechecker.model.Function)6 UnionType (org.eclipse.ceylon.model.typechecker.model.UnionType)6 AttributeDeclaration (org.eclipse.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration)5 TreeUtil.unwrapExpressionUntilTerm (org.eclipse.ceylon.compiler.typechecker.tree.TreeUtil.unwrapExpressionUntilTerm)5 BaseMemberExpression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.BaseMemberExpression)4 ExtendedType (org.eclipse.ceylon.compiler.typechecker.tree.Tree.ExtendedType)4 LazySpecifierExpression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression)4 IntersectionType (org.eclipse.ceylon.model.typechecker.model.IntersectionType)4 SyntheticName (org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName)3 AssignmentOperatorTranslation (org.eclipse.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation)3 OperatorTranslation (org.eclipse.ceylon.compiler.java.codegen.Operators.OperatorTranslation)3