Search in sources :

Example 26 with Type

use of com.redhat.ceylon.model.typechecker.model.Type in project ceylon-compiler by ceylon.

the class ExpressionTransformer method transformBaseInstantiation.

private JCExpression transformBaseInstantiation(Invocation invocation, CallBuilder callBuilder, TransformedInvocationPrimary transformedPrimary) {
    JCExpression resultExpr;
    Tree.BaseTypeExpression type = (Tree.BaseTypeExpression) invocation.getPrimary();
    Declaration declaration = type.getDeclaration();
    invocation.location(callBuilder);
    if (Strategy.generateInstantiator(declaration)) {
        resultExpr = callBuilder.typeArguments(List.<JCExpression>nil()).invoke(naming.makeInstantiatorMethodName(transformedPrimary.expr, (Class) declaration)).build();
        if (Strategy.isInstantiatorUntyped(declaration)) {
            // $new method declared to return Object, so needs typecast
            resultExpr = make().TypeCast(makeJavaType(((TypeDeclaration) declaration).getType()), resultExpr);
        }
    } else {
        Type classType = (Type) type.getTarget();
        if (isJavaArray(classType)) {
            JCExpression typeExpr = makeJavaType(classType, AbstractTransformer.JT_CLASS_NEW | AbstractTransformer.JT_RAW);
            callBuilder.javaArrayInstance(typeExpr);
            if (isJavaObjectArray(classType)) {
                Type elementType = classType.getTypeArgumentList().get(0);
                MultidimensionalArray multiArray = getMultiDimensionalArrayInfo(elementType);
                if (multiArray != null)
                    elementType = multiArray.type;
                // array of Foo is fine, array of Nothing too
                if (elementType.getDeclaration() instanceof ClassOrInterface || elementType.isNothing()) {
                    if (!elementType.getTypeArgumentList().isEmpty())
                        callBuilder.javaArrayInstanceNeedsCast(makeJavaType(classType, AbstractTransformer.JT_NO_PRIMITIVES));
                } else {
                    // if it's an array of union, intersection or type param we need a runtime allocation
                    callBuilder.javaArrayInstanceIsGeneric(makeReifiedTypeArgument(elementType), multiArray != null ? multiArray.dimension + 1 : 1);
                }
            }
        } else {
            if (Decl.isConstructor(classType.getDeclaration())) {
                classType = classType.getExtendedType();
            }
            JCExpression typeExpr = makeJavaType(classType, AbstractTransformer.JT_CLASS_NEW);
            callBuilder.instantiate(typeExpr);
        }
        resultExpr = callBuilder.build();
    }
    return resultExpr;
}
Also used : ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) Class(com.redhat.ceylon.model.typechecker.model.Class) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration)

Example 27 with Type

use of com.redhat.ceylon.model.typechecker.model.Type in project ceylon-compiler by ceylon.

the class ExpressionTransformer method transform.

// Prefix operator
public JCExpression transform(final Tree.PrefixOperatorExpression expr) {
    final OperatorTranslation operator = Operators.getOperator(expr.getClass());
    if (operator == null) {
        return makeErroneous(expr, "compiler bug: " + expr.getNodeType() + " is not supported yet");
    }
    OptimisationStrategy optimisationStrategy = operator.getUnOpOptimisationStrategy(expr, expr.getTerm(), this);
    final boolean canOptimise = optimisationStrategy.useJavaOperator();
    Tree.Term term = expr.getTerm();
    // only fully optimise if we don't have to access the getter/setter
    if (canOptimise && CodegenUtil.isDirectAccessVariable(term)) {
        JCExpression jcTerm = transformExpression(term, BoxingStrategy.UNBOXED, expr.getTypeModel(), EXPR_WIDEN_PRIM);
        return at(expr).Unary(operator.javacOperator, jcTerm);
    }
    Interface compoundType = expr.getUnit().getOrdinalDeclaration();
    Type valueType = getSupertype(term, compoundType);
    final Type returnType = getMostPreciseType(term, getTypeArgument(valueType, 0));
    // we work on boxed types unless we could have optimised
    return transformAssignAndReturnOperation(expr, term, !canOptimise, valueType, returnType, new AssignAndReturnOperationFactory() {

        @Override
        public JCExpression getNewValue(JCExpression previousValue) {
            // use +1/-1 if we can optimise a bit
            if (canOptimise) {
                JCExpression ret = make().Binary(operator == OperatorTranslation.UNARY_PREFIX_INCREMENT ? JCTree.PLUS : JCTree.MINUS, previousValue, makeInteger(1));
                ret = unAutoPromote(ret, returnType);
                return ret;
            }
            // make this call: previousValue.getSuccessor() or previousValue.getPredecessor()
            return make().Apply(null, makeSelect(previousValue, operator.ceylonMethod), List.<JCExpression>nil());
        }
    });
}
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) OptimisationStrategy(com.redhat.ceylon.compiler.java.codegen.Operators.OptimisationStrategy) Interface(com.redhat.ceylon.model.typechecker.model.Interface) ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) AssignmentOperatorTranslation(com.redhat.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation) OperatorTranslation(com.redhat.ceylon.compiler.java.codegen.Operators.OperatorTranslation)

Example 28 with Type

use of com.redhat.ceylon.model.typechecker.model.Type in project ceylon-compiler by ceylon.

the class ExpressionTransformer method getComparableType.

protected Type getComparableType(Tree.Term middleTerm) {
    final Type middleSuper = getSupertype(middleTerm, typeFact().getComparableDeclaration());
    Type middleType = middleSuper;
    Type middleSelf = middleType.getDeclaration().getSelfType();
    if (middleSelf != null) {
        // Simplify Comparable<X> to X
        middleType = middleType.getTypeArguments().get(middleSelf.getDeclaration());
    }
    return middleType;
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type)

Example 29 with Type

use of com.redhat.ceylon.model.typechecker.model.Type in project ceylon-compiler by ceylon.

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 then
                Type iterableSpreadType = spreadType.getSupertype(typeFact().getIterableDeclaration());
                tail = transformExpression(spreadExpr.getExpression(), BoxingStrategy.BOXED, iterableSpreadType);
                tail = utilInvocation().sequentialOf(makeReifiedTypeArgument(typeFact().getIteratedType(iterableSpreadType)), tail);
                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 : Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) PositionalArgument(com.redhat.ceylon.compiler.typechecker.tree.Tree.PositionalArgument)

Example 30 with Type

use of com.redhat.ceylon.model.typechecker.model.Type in project ceylon-compiler by ceylon.

the class ExpressionTransformer method transformComprehension.

JCExpression transformComprehension(Tree.Comprehension comp, Type expectedType) {
    Type elementType = comp.getInitialComprehensionClause().getTypeModel();
    // get rid of anonymous types
    elementType = typeFact().denotableType(elementType);
    elementType = wrapInOptionalForInterop(elementType, expectedType, containsUncheckedNulls(comp));
    return new ComprehensionTransformation(comp, elementType).transformComprehension();
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type)

Aggregations

Type (com.redhat.ceylon.model.typechecker.model.Type)237 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)98 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)87 TypeParameter (com.redhat.ceylon.model.typechecker.model.TypeParameter)56 JCTree (com.sun.tools.javac.tree.JCTree)53 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)51 ModelUtil.appliedType (com.redhat.ceylon.model.typechecker.model.ModelUtil.appliedType)46 Class (com.redhat.ceylon.model.typechecker.model.Class)45 ClassOrInterface (com.redhat.ceylon.model.typechecker.model.ClassOrInterface)43 TypedDeclaration (com.redhat.ceylon.model.typechecker.model.TypedDeclaration)41 IntersectionType (com.redhat.ceylon.model.typechecker.model.IntersectionType)37 UnionType (com.redhat.ceylon.model.typechecker.model.UnionType)37 Test (org.junit.Test)37 TypeParser (com.redhat.ceylon.model.loader.TypeParser)36 Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)34 Function (com.redhat.ceylon.model.typechecker.model.Function)33 Interface (com.redhat.ceylon.model.typechecker.model.Interface)30 JCTypeParameter (com.sun.tools.javac.tree.JCTree.JCTypeParameter)30 TypedReference (com.redhat.ceylon.model.typechecker.model.TypedReference)29 ArrayList (java.util.ArrayList)28