Search in sources :

Example 86 with JCExpression

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

the class ExpressionTransformer method transform.

public JCExpression transform(Tree.Parameter param) {
    // Transform the expression marking that we're inside a defaulted parameter for $this-handling
    // needDollarThis  = true;
    JCExpression expr;
    at(param);
    if (Strategy.hasDefaultParameterValueMethod(param.getParameterModel())) {
        Tree.SpecifierOrInitializerExpression spec = Decl.getDefaultArgument(param);
        Scope container = param.getParameterModel().getModel().getContainer();
        boolean classParameter = container instanceof ClassOrInterface;
        ClassOrInterface oldWithinDefaultParameterExpression = withinDefaultParameterExpression;
        if (classParameter)
            withinDefaultParameterExpression((ClassOrInterface) container);
        if (param instanceof Tree.FunctionalParameterDeclaration) {
            Tree.FunctionalParameterDeclaration fpTree = (Tree.FunctionalParameterDeclaration) param;
            Tree.SpecifierExpression lazy = (Tree.SpecifierExpression) spec;
            Function fp = (Function) fpTree.getParameterModel().getModel();
            expr = CallableBuilder.anonymous(gen(), param, (Function) fpTree.getTypedDeclaration().getDeclarationModel(), lazy.getExpression(), ((Tree.MethodDeclaration) fpTree.getTypedDeclaration()).getParameterLists(), getTypeForFunctionalParameter(fp), true).build();
        } else {
            expr = transformExpression(spec.getExpression(), CodegenUtil.getBoxingStrategy(param.getParameterModel().getModel()), param.getParameterModel().getModel().getTypedReference().getFullType());
        }
        if (classParameter)
            withinDefaultParameterExpression(oldWithinDefaultParameterExpression);
    } else {
        expr = makeErroneous(param, "compiler bug: no default parameter value method");
    }
    // needDollarThis = false;
    return expr;
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) Function(org.eclipse.ceylon.model.typechecker.model.Function) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree)

Example 87 with JCExpression

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

the class ExpressionTransformer method transformArgument.

private ExpressionAndType transformArgument(SimpleInvocation invocation, int argIndex, BoxingStrategy boxingStrategy) {
    ExpressionAndType exprAndType;
    JCExpression expr = invocation.getTransformedArgumentExpression(argIndex);
    Type paramType = invocation.getParameterType(argIndex);
    JCExpression type = makeJavaType(paramType, boxingStrategy == BoxingStrategy.BOXED ? JT_NO_PRIMITIVES : 0);
    Class ctedClass = ModelUtil.getConstructedClass(invocation.getPrimaryDeclaration());
    if (argIndex == 0 && typeFact().isOptionalType(paramType) && invocation.getArgumentType(argIndex).isSubtypeOf(typeFact().getNullType()) && ctedClass != null && (ctedClass.hasConstructors() || ctedClass.isSerializable())) {
        // we've invoking the default constructor, whose first parameter has optional type
        // with a null argument: That will be ambiguous wrt any named constructors
        // with otherwise identical signitures, so we need a typecast to
        // disambiguate
        expr = make().TypeCast(makeJavaType(paramType, boxingStrategy == BoxingStrategy.BOXED ? JT_NO_PRIMITIVES : 0), expr);
    }
    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) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) Class(org.eclipse.ceylon.model.typechecker.model.Class)

Example 88 with JCExpression

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

the class ExpressionTransformer method transformConstructorDelegation.

/**
 * Transform a delegated constructor call ({@code extends XXX()})
 * which may be either a superclass initializer/constructor or a
 * same-class constructor.
 * @param extendedType
 * @param delegation The kind of delegation
 * @param invocation
 * @param classBuilder
 * @return
 */
JCStatement transformConstructorDelegation(Node extendedType, CtorDelegation delegation, Tree.InvocationExpression invocation, ClassDefinitionBuilder classBuilder, boolean forDelegationConstructor) {
    if (delegation != null && delegation.isError()) {
        return delegation.makeThrow(this);
    }
    Declaration primaryDeclaration = ((Tree.MemberOrTypeExpression) invocation.getPrimary()).getDeclaration();
    java.util.List<ParameterList> paramLists = ((Functional) primaryDeclaration).getParameterLists();
    if (paramLists.isEmpty()) {
        classBuilder.getInitBuilder().delegateCall(at(extendedType).Exec(makeErroneous(extendedType, "compiler bug: super class " + primaryDeclaration.getName() + " is missing parameter list")));
        return null;
    }
    SuperInvocation builder = new SuperInvocation(this, classBuilder.getForDefinition(), delegation, invocation, paramLists.get(0), forDelegationConstructor);
    CallBuilder callBuilder = CallBuilder.instance(this);
    boolean prevFnCall = withinInvocation(true);
    try {
        if (invocation.getPrimary() instanceof Tree.StaticMemberOrTypeExpression) {
            transformTypeArguments(callBuilder, (Tree.StaticMemberOrTypeExpression) invocation.getPrimary());
        }
        at(builder.getNode());
        JCExpression expr = null;
        Scope outerDeclaration;
        if (Decl.isConstructor(primaryDeclaration)) {
            outerDeclaration = builder.getPrimaryDeclaration().getContainer().getContainer();
        } else {
            outerDeclaration = builder.getPrimaryDeclaration().getContainer();
        }
        if ((Strategy.generateInstantiator(builder.getPrimaryDeclaration()) || builder.getPrimaryDeclaration() instanceof Class) && outerDeclaration instanceof Interface && !((Interface) outerDeclaration).isJava()) {
            // If the subclass is inner to an interface then it will be
            // generated inner to the companion and we need to qualify the
            // super(), *unless* the subclass is nested within the same
            // interface as it's superclass.
            Scope outer = builder.getSub().getContainer();
            while (!(outer instanceof Package)) {
                if (outer == outerDeclaration) {
                    expr = naming.makeSuper();
                    break;
                }
                outer = outer.getContainer();
            }
            if (expr == null) {
                if (delegation.isSelfDelegation()) {
                    throw new BugException();
                }
                Interface iface = (Interface) outerDeclaration;
                JCExpression superQual;
                if (ModelUtil.getClassOrInterfaceContainer(classBuilder.getForDefinition(), false) instanceof Interface) {
                    superQual = naming.makeCompanionAccessorCall(naming.makeQuotedThis(), iface);
                } else {
                    superQual = naming.makeCompanionFieldName(iface);
                }
                expr = naming.makeQualifiedSuper(superQual);
            }
        } else {
            expr = delegation.isSelfDelegation() ? naming.makeThis() : naming.makeSuper();
        }
        final List<JCExpression> superArguments = transformSuperInvocationArguments(classBuilder, builder, callBuilder);
        JCExpression superExpr = callBuilder.invoke(expr).arguments(superArguments).build();
        return at(extendedType).Exec(superExpr);
    // classBuilder.getInitBuilder().superCall(at(extendedType).Exec(superExpr));
    } finally {
        withinInvocation(prevFnCall);
    }
}
Also used : Functional(org.eclipse.ceylon.model.typechecker.model.Functional) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) Package(org.eclipse.ceylon.model.typechecker.model.Package) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface)

Example 89 with JCExpression

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

the class ExpressionTransformer method makeTuple.

private JCExpression makeTuple(Type tupleType, java.util.List<Tree.PositionalArgument> expressions) {
    if (typeFact().isEmptyType(tupleType)) {
        // A tuple terminated by empty
        return makeEmpty();
    }
    JCExpression tail = null;
    List<JCExpression> elems = List.<JCExpression>nil();
    for (int i = 0; i < expressions.size(); i++) {
        Tree.PositionalArgument expr = expressions.get(i);
        if (expr instanceof Tree.ListedArgument) {
            JCExpression elem = transformExpression(((Tree.ListedArgument) expr).getExpression());
            elems = elems.append(elem);
        } else if (expr instanceof Tree.SpreadArgument) {
            Tree.SpreadArgument spreadExpr = (Tree.SpreadArgument) expr;
            // make sure we get a spread part of the right type
            Type spreadType = spreadExpr.getExpression().getTypeModel();
            Type sequentialSpreadType = null;
            // try to get a Sequence
            if (typeFact().isNonemptyIterableType(spreadType))
                sequentialSpreadType = spreadType.getSupertype(typeFact().getSequenceDeclaration());
            // failing that, try Sequential
            if (sequentialSpreadType == null)
                sequentialSpreadType = spreadType.getSupertype(typeFact().getSequentialDeclaration());
            if (sequentialSpreadType != null) {
                tail = transformExpression(spreadExpr.getExpression(), BoxingStrategy.BOXED, sequentialSpreadType);
            } else {
                // must at least be an Iterable, Java Iterable, or Java array then
                Type iterableSpreadType;
                Type iteratedType;
                if (typeFact().isIterableType(spreadType)) {
                    iterableSpreadType = spreadType.getSupertype(typeFact().getIterableDeclaration());
                    iteratedType = typeFact().getIteratedType(iterableSpreadType);
                    tail = transformExpression(spreadExpr.getExpression(), BoxingStrategy.BOXED, iterableSpreadType);
                    tail = utilInvocation().sequentialOf(makeReifiedTypeArgument(iteratedType), tail);
                } else if (typeFact().isJavaIterableType(spreadType)) {
                    iterableSpreadType = spreadType.getSupertype(typeFact().getJavaIterableDeclaration());
                    iteratedType = typeFact().getJavaIteratedType(iterableSpreadType);
                    tail = transformExpression(spreadExpr.getExpression(), BoxingStrategy.BOXED, iterableSpreadType);
                    tail = utilInvocation().toIterable(makeJavaType(iteratedType, JT_TYPE_ARGUMENT), makeReifiedTypeArgument(iteratedType), tail);
                    tail = make().Apply(null, makeSelect(tail, "sequence"), List.<JCExpression>nil());
                } else if (typeFact().isJavaArrayType(spreadType)) {
                    if (typeFact().isJavaObjectArrayType(spreadType)) {
                        iterableSpreadType = spreadType.getSupertype(typeFact().getJavaObjectArrayDeclaration());
                    } else {
                        // primitive
                        iterableSpreadType = spreadType;
                    }
                    iteratedType = typeFact().getJavaArrayElementType(iterableSpreadType);
                    tail = transformExpression(spreadExpr.getExpression(), BoxingStrategy.BOXED, iterableSpreadType);
                    if (typeFact().isJavaObjectArrayType(spreadType)) {
                        tail = utilInvocation().toIterable(makeJavaType(iteratedType, JT_TYPE_ARGUMENT), makeReifiedTypeArgument(iteratedType), tail);
                    } else {
                        // primitive
                        tail = utilInvocation().toIterable(tail);
                    }
                    tail = make().Apply(null, makeSelect(tail, "sequence"), List.<JCExpression>nil());
                } else {
                    throw BugException.unhandledTypeCase(spreadType);
                }
                Type elementType = typeFact().getIteratedType(spreadExpr.getTypeModel());
                Type sequentialType = typeFact().getSequentialType(elementType);
                Type expectedType = spreadExpr.getTypeModel();
                if (typeFact().isNonemptyIterableType(spreadExpr.getTypeModel())) {
                    expectedType = typeFact().getSequenceType(elementType);
                } else if (typeFact().isIterableType(spreadExpr.getTypeModel())) {
                    expectedType = typeFact().getSequentialType(elementType);
                }
                tail = sequentialEmptiness(tail, expectedType, sequentialType);
            }
        } else if (expr instanceof Tree.Comprehension) {
            Tree.Comprehension comp = (Tree.Comprehension) expr;
            Type elementType = expr.getTypeModel();
            Type expectedType = comp.getInitialComprehensionClause().getPossiblyEmpty() ? typeFact().getSequentialType(elementType) : typeFact().getSequenceType(elementType);
            tail = comprehensionAsSequential(comp, expectedType);
        } else {
            return makeErroneous(expr, "compiler bug: " + expr.getNodeType() + " is not a supported tuple argument");
        }
    }
    if (!elems.isEmpty()) {
        JCExpression reifiedTypeArg = makeReifiedTypeArgument(tupleType.getTypeArgumentList().get(0));
        List<JCExpression> args = List.<JCExpression>of(reifiedTypeArg);
        args = args.append(make().NewArray(make().Type(syms().objectType), List.<JCExpression>nil(), elems));
        if (tail != null) {
            args = args.append(tail);
        }
        JCExpression typeExpr = makeJavaType(tupleType, JT_TYPE_ARGUMENT);
        /* Tuple.instance(reifiedElement, new Object[]{elem, elem, elem}, tail) */
        return make().TypeCast(typeExpr, make().Apply(List.<JCExpression>nil(), naming.makeQualIdent(make().QualIdent(syms().ceylonTupleType.tsym), "instance"), args));
    } else {
        return tail;
    }
}
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) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) PositionalArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.PositionalArgument)

Example 90 with JCExpression

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

the class ExpressionTransformer method transform.

public JCTree transform(Tree.Exists op) {
    // for the purpose of checking if something is null, we need it boxed and optional, otherwise
    // for some Java calls if we consider it non-optional we will get an unwanted null check
    Type termType = op.getTerm().getTypeModel();
    if (!typeFact().isOptionalType(termType)) {
        termType = typeFact().getOptionalType(termType);
    }
    JCExpression expression = transformExpression(op.getTerm(), BoxingStrategy.BOXED, termType);
    at(op);
    return make().Binary(JCTree.Tag.NE, expression, makeNull());
}
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)

Aggregations

JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)224 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)95 Type (org.eclipse.ceylon.model.typechecker.model.Type)95 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)74 JCStatement (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement)53 ListBuffer (org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer)53 UnionType (org.eclipse.ceylon.model.typechecker.model.UnionType)45 SyntheticName (org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName)41 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)39 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)38 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)33 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)32 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)30 JCVariableDecl (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl)28 Function (org.eclipse.ceylon.model.typechecker.model.Function)26 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)22 Value (org.eclipse.ceylon.model.typechecker.model.Value)22 JCNewClass (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass)21 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)21 Class (org.eclipse.ceylon.model.typechecker.model.Class)17