Search in sources :

Example 91 with JCExpression

use of com.sun.tools.javac.tree.JCTree.JCExpression in project ceylon-compiler by ceylon.

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.isJavaMethod() && 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().isSequentialType(argType))
                argExpr = iterableToSequential(argExpr);
            x = x.prepend(argExpr);
        }
    }
    if (invocation.isJavaMethod()) {
        // 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 : Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) LetExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.LetExpression) Expression(com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) TreeUtil.unwrapExpressionUntilTerm(com.redhat.ceylon.compiler.typechecker.tree.TreeUtil.unwrapExpressionUntilTerm) Term(com.redhat.ceylon.compiler.typechecker.tree.Tree.Term)

Example 92 with JCExpression

use of com.sun.tools.javac.tree.JCTree.JCExpression in project ceylon-compiler by ceylon.

the class ExpressionTransformer method transformArg.

protected final JCExpression transformArg(SimpleInvocation invocation, int argIndex) {
    final Tree.Term expr = invocation.getArgumentExpression(argIndex);
    if (invocation.hasParameter(argIndex)) {
        Type type = invocation.getParameterType(argIndex);
        if (invocation.isParameterSequenced(argIndex) && // Java methods need their underlying type preserved
        !invocation.isJavaMethod()) {
            if (!invocation.isArgumentSpread(argIndex)) {
                // If the parameter is sequenced and the argument is not ...
                // then the expected type of the *argument* is the type arg to Iterator
                type = typeFact().getIteratedType(type);
            } else if (invocation.getArgumentType(argIndex).getSupertype(typeFact().getSequentialDeclaration()) == null) {
                // On the other hand, if the parameter is sequenced and the argument is spread,
                // but not sequential, then transformArguments() will use getSequence(),
                // so we only need to expect an Iterable type
                type = com.redhat.ceylon.model.typechecker.model.ModelUtil.appliedType(typeFact().getIterableDeclaration(), typeFact().getIteratedType(type), typeFact().getIteratedAbsentType(type));
            }
        }
        BoxingStrategy boxingStrategy = invocation.getParameterBoxingStrategy(argIndex);
        int flags = 0;
        if (!invocation.isParameterRaw(argIndex))
            flags |= ExpressionTransformer.EXPR_EXPECTED_TYPE_NOT_RAW;
        if (invocation.isParameterWithConstrainedTypeParameters(argIndex))
            flags |= ExpressionTransformer.EXPR_EXPECTED_TYPE_HAS_CONSTRAINED_TYPE_PARAMETERS;
        if (invocation.isParameterWithDependentCovariantTypeParameters(argIndex))
            flags |= ExpressionTransformer.EXPR_EXPECTED_TYPE_HAS_DEPENDENT_COVARIANT_TYPE_PARAMETERS;
        if (invocation.erasedArgument(unwrapExpressionUntilTerm(expr))) {
            flags |= EXPR_DOWN_CAST;
        }
        JCExpression ret = transformExpression(expr, boxingStrategy, type, flags);
        return ret;
    } else {
        // Overloaded methods don't have a reference to a parameter
        // so we have to treat them differently. Also knowing it's
        // overloaded we know we're dealing with Java code so we unbox
        Type type = expr.getTypeModel();
        return expressionGen().transformExpression(expr, BoxingStrategy.UNBOXED, type);
    }
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) Term(com.redhat.ceylon.compiler.typechecker.tree.Tree.Term) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree)

Example 93 with JCExpression

use of com.sun.tools.javac.tree.JCTree.JCExpression in project ceylon-compiler by ceylon.

the class NamedArgumentInvocation method appendVarsForReifiedTypeArguments.

private void appendVarsForReifiedTypeArguments() {
    java.util.List<JCExpression> reifiedTypeArgs = gen.makeReifiedTypeArguments(producedReference);
    int index = 0;
    for (JCExpression reifiedTypeArg : reifiedTypeArgs) {
        Naming.SyntheticName argName = reifiedTypeArgName(index);
        JCVariableDecl varDecl = gen.makeVar(argName, gen.makeTypeDescriptorType(), reifiedTypeArg);
        this.vars.append(varDecl);
        index++;
    }
}
Also used : JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl)

Example 94 with JCExpression

use of com.sun.tools.javac.tree.JCTree.JCExpression in project ceylon-compiler by ceylon.

the class NamedArgumentInvocation method appendDefaulted.

private final void appendDefaulted(Parameter param, JCExpression argExpr) {
    // we can't just generate types like Foo<?> if the target type param is not raw because the bounds will
    // not match, so we go raw
    int flags = JT_RAW;
    if (getNamedParameterBoxingStrategy(param) == BoxingStrategy.BOXED) {
        flags |= JT_TYPE_ARGUMENT;
    }
    Type type = gen.getTypeForParameter(param, producedReference, gen.TP_TO_BOUND);
    Naming.SyntheticName argName = argName(param);
    JCExpression typeExpr = gen.makeJavaType(type, flags);
    JCVariableDecl varDecl = gen.makeVar(argName, typeExpr, argExpr);
    bind(param, argName, gen.makeJavaType(type, flags), List.<JCStatement>of(varDecl));
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl)

Example 95 with JCExpression

use of com.sun.tools.javac.tree.JCTree.JCExpression in project ceylon-compiler by ceylon.

the class ImportScanner method visitClassDef.

@Override
public void visitClassDef(JCClassDecl that) {
    // we have to do field types, method signatures, type parameters and extends/implements, that's all
    visit(that.defs);
    visitType(that.extending);
    for (JCExpression impl : that.implementing) {
        visitType(impl);
    }
    visitTypeParameters(that.typarams);
}
Also used : JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression)

Aggregations

JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)311 JCTree (com.sun.tools.javac.tree.JCTree)95 Type (com.redhat.ceylon.model.typechecker.model.Type)85 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)81 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)67 JCVariableDecl (com.sun.tools.javac.tree.JCTree.JCVariableDecl)59 ListBuffer (com.sun.tools.javac.util.ListBuffer)54 JCTypeParameter (com.sun.tools.javac.tree.JCTree.JCTypeParameter)39 Name (com.sun.tools.javac.util.Name)39 SyntheticName (com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName)37 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)35 TypedDeclaration (com.redhat.ceylon.model.typechecker.model.TypedDeclaration)34 JCBlock (com.sun.tools.javac.tree.JCTree.JCBlock)34 JavacTreeMaker (lombok.javac.JavacTreeMaker)33 JCAnnotation (com.sun.tools.javac.tree.JCTree.JCAnnotation)30 TypeParameter (com.redhat.ceylon.model.typechecker.model.TypeParameter)29 Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)27 Function (com.redhat.ceylon.model.typechecker.model.Function)26 Parameter (com.redhat.ceylon.model.typechecker.model.Parameter)26 JCNewClass (com.sun.tools.javac.tree.JCTree.JCNewClass)26