Search in sources :

Example 31 with TypeParameter

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

the class AbstractTransformer method hasSubstitutedBounds.

boolean hasSubstitutedBounds(Type pt) {
    TypeDeclaration declaration = pt.getDeclaration();
    java.util.List<TypeParameter> tps = declaration.getTypeParameters();
    final Map<TypeParameter, Type> tas = pt.getTypeArguments();
    boolean isCallable = isCeylonCallable(pt);
    for (TypeParameter tp : tps) {
        Type ta = tas.get(tp);
        // error recovery
        if (ta == null)
            continue;
        if (!tp.getSatisfiedTypes().isEmpty()) {
            for (Type bound : tp.getSatisfiedTypes()) {
                bound = bound.substitute(pt);
                if (expressionGen().needsCast(ta, bound, false, false, false))
                    return true;
            }
        }
        if (hasSubstitutedBounds(ta))
            return true;
        // Callable ignores type parameters after the first
        if (isCallable)
            break;
    }
    return false;
}
Also used : TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) Type(com.redhat.ceylon.model.typechecker.model.Type) ModelUtil.appliedType(com.redhat.ceylon.model.typechecker.model.ModelUtil.appliedType) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration)

Example 32 with TypeParameter

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

the class AbstractTransformer method getTypeArguments.

private java.util.List<Type> getTypeArguments(Function method) {
    java.util.List<TypeParameter> typeParameters = method.getTypeParameters();
    java.util.List<Type> typeArguments = new ArrayList<Type>(typeParameters.size());
    for (TypeParameter tp : typeParameters) typeArguments.add(tp.getType());
    return typeArguments;
}
Also used : TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) Type(com.redhat.ceylon.model.typechecker.model.Type) ModelUtil.appliedType(com.redhat.ceylon.model.typechecker.model.ModelUtil.appliedType) ArrayList(java.util.ArrayList)

Example 33 with TypeParameter

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

the class AbstractTransformer method makeReifiedTypeArgumentResolved.

private JCExpression makeReifiedTypeArgumentResolved(Type pt, boolean qualified) {
    if (pt.isUnion()) {
        // FIXME: refactor this shite
        List<JCExpression> typeTestArguments = List.nil();
        java.util.List<Type> typeParameters = pt.getCaseTypes();
        if (typeParameters.size() == 2) {
            Type alternative = null;
            if (typeParameters.get(0).isEmpty())
                alternative = typeParameters.get(1);
            else if (typeParameters.get(1).isEmpty())
                alternative = typeParameters.get(0);
            if (alternative != null && alternative.isTuple()) {
                JCExpression tupleType = makeTupleTypeDescriptor(alternative, true);
                if (tupleType != null)
                    return tupleType;
            }
        }
        for (int i = typeParameters.size() - 1; i >= 0; i--) {
            typeTestArguments = typeTestArguments.prepend(makeReifiedTypeArgument(typeParameters.get(i)));
        }
        return make().Apply(null, makeSelect(makeTypeDescriptorType(), "union"), typeTestArguments);
    } else if (pt.isIntersection()) {
        List<JCExpression> typeTestArguments = List.nil();
        java.util.List<Type> typeParameters = pt.getSatisfiedTypes();
        for (int i = typeParameters.size() - 1; i >= 0; i--) {
            typeTestArguments = typeTestArguments.prepend(makeReifiedTypeArgument(typeParameters.get(i)));
        }
        return make().Apply(null, makeSelect(makeTypeDescriptorType(), "intersection"), typeTestArguments);
    } else if (pt.isNothing()) {
        return makeNothingTypeDescriptor();
    }
    TypeDeclaration declaration = pt.getDeclaration();
    if (declaration instanceof Constructor) {
        pt = pt.getExtendedType();
        declaration = pt.getDeclaration();
    }
    if (pt.isClassOrInterface()) {
        if (declaration.isJavaEnum()) {
            pt = pt.getExtendedType();
            declaration = pt.getDeclaration();
        }
        // see if we have an alias for it
        if (supportsReifiedAlias((ClassOrInterface) declaration)) {
            JCExpression qualifier = naming.makeDeclarationName(declaration, DeclNameFlag.QUALIFIED);
            return makeSelect(qualifier, naming.getTypeDescriptorAliasName());
        }
        if (pt.isTuple()) {
            JCExpression tupleType = makeTupleTypeDescriptor(pt, false);
            if (tupleType != null)
                return tupleType;
        }
        // no alias, must build it
        List<JCExpression> typeTestArguments = makeReifiedTypeArgumentsResolved(pt.getTypeArgumentList(), qualified);
        JCExpression thisType = makeUnerasedClassLiteral(declaration);
        // do we have variance overrides?
        Map<TypeParameter, SiteVariance> varianceOverrides = pt.getVarianceOverrides();
        if (!varianceOverrides.isEmpty()) {
            // we need to pass them as second argument then, in an array
            ListBuffer<JCExpression> varianceElements = new ListBuffer<JCExpression>();
            for (TypeParameter typeParameter : declaration.getTypeParameters()) {
                SiteVariance useSiteVariance = varianceOverrides.get(typeParameter);
                String selector;
                if (useSiteVariance != null) {
                    switch(useSiteVariance) {
                        case IN:
                            selector = "IN";
                            break;
                        case OUT:
                            selector = "OUT";
                            break;
                        default:
                            selector = "NONE";
                            break;
                    }
                } else {
                    selector = "NONE";
                }
                JCExpression varianceElement = make().Select(makeIdent(syms().ceylonVarianceType), names().fromString(selector));
                varianceElements.append(varianceElement);
            }
            JCNewArray varianceArray = make().NewArray(makeIdent(syms().ceylonVarianceType), List.<JCExpression>nil(), varianceElements.toList());
            typeTestArguments = typeTestArguments.prepend(varianceArray);
        }
        typeTestArguments = typeTestArguments.prepend(thisType);
        JCExpression classDescriptor = make().Apply(null, makeSelect(makeTypeDescriptorType(), "klass"), typeTestArguments);
        Type qualifyingType = pt.getQualifyingType();
        JCExpression containerType = null;
        if (qualifyingType == null && // ignore qualifying types of static java declarations
        (Decl.isCeylon(declaration) || !declaration.isStaticallyImportable())) {
            // it may be contained in a function or value, and we want its type
            Declaration enclosingDeclaration = getDeclarationContainer(declaration);
            if (enclosingDeclaration instanceof TypedDeclaration)
                containerType = makeTypedDeclarationTypeDescriptorResolved((TypedDeclaration) enclosingDeclaration);
            else if (enclosingDeclaration instanceof TypeDeclaration) {
                qualifyingType = ((TypeDeclaration) enclosingDeclaration).getType();
            }
        }
        if (qualifyingType != null && qualifyingType.getDeclaration() instanceof Constructor) {
            qualifyingType = qualifyingType.getQualifyingType();
        }
        if (qualifyingType != null) {
            containerType = makeReifiedTypeArgumentResolved(qualifyingType, true);
        }
        if (containerType == null) {
            return classDescriptor;
        } else {
            return make().Apply(null, makeSelect(makeTypeDescriptorType(), "member"), List.of(containerType, classDescriptor));
        }
    } else if (pt.isTypeParameter()) {
        TypeParameter tp = (TypeParameter) declaration;
        String name = naming.getTypeArgumentDescriptorName(tp);
        if (!qualified || isTypeParameterSubstituted(tp))
            return makeUnquotedIdent(name);
        Scope container = tp.getContainer();
        JCExpression qualifier = null;
        if (container instanceof Class) {
            qualifier = naming.makeQualifiedThis(makeJavaType(((Class) container).getType(), JT_RAW));
        } else if (container instanceof Interface) {
            qualifier = naming.makeQualifiedThis(makeJavaType(((Interface) container).getType(), JT_COMPANION | JT_RAW));
        } else if (container instanceof Function) {
            // name must be a unique name, as returned by getTypeArgumentDescriptorName
            return makeUnquotedIdent(name);
        } else {
            throw BugException.unhandledCase(container);
        }
        return makeSelect(qualifier, name);
    } else {
        throw BugException.unhandledDeclarationCase(declaration);
    }
}
Also used : TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) Constructor(com.redhat.ceylon.model.typechecker.model.Constructor) ListBuffer(com.sun.tools.javac.util.ListBuffer) Function(com.redhat.ceylon.model.typechecker.model.Function) Type(com.redhat.ceylon.model.typechecker.model.Type) ModelUtil.appliedType(com.redhat.ceylon.model.typechecker.model.ModelUtil.appliedType) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) SiteVariance(com.redhat.ceylon.model.typechecker.model.SiteVariance) Scope(com.redhat.ceylon.model.typechecker.model.Scope) ArrayList(java.util.ArrayList) List(com.sun.tools.javac.util.List) LinkedList(java.util.LinkedList) ParameterList(com.redhat.ceylon.model.typechecker.model.ParameterList) Class(com.redhat.ceylon.model.typechecker.model.Class) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) JCNewArray(com.sun.tools.javac.tree.JCTree.JCNewArray) ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) Interface(com.redhat.ceylon.model.typechecker.model.Interface)

Example 34 with TypeParameter

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

the class AbstractTransformer method objectVariadicToJavaArray.

private JCExpression objectVariadicToJavaArray(SimpleInvocation invocation, Type type, Type exprType, JCExpression expr, List<JCExpression> initialElements) {
    // The type that the java varargs parameter erases to: 
    // this is the type of the array which we need to construct
    java.util.List<Parameter> pl = ((Functional) invocation.getPrimaryDeclaration()).getFirstParameterList().getParameters();
    Parameter varargsParameter = pl.get(pl.size() - 1);
    Type arrayType = simplifyType(typeFact().getIteratedType(varargsParameter.getType()));
    while (arrayType.getDeclaration() instanceof TypeParameter) {
        TypeParameter tp = (TypeParameter) arrayType.getDeclaration();
        if (tp.getSatisfiedTypes().isEmpty()) {
            arrayType = typeFact().getObjectType();
            break;
        } else {
            arrayType = tp.getSatisfiedTypes().get(0);
        }
    }
    // we could have a <X>variadic(X&Object), so we need to pick a type which satisfies the bound
    Type castType = simplifyType(type);
    if (typeFact().isIntersection(castType)) {
        for (Type t : castType.getSatisfiedTypes()) {
            if (t.isSubtypeOf(arrayType)) {
                castType = t;
                break;
            }
        }
    }
    Naming.SyntheticName seqName = naming.temp().suffixedBy(0);
    Type sequentialType = typeFact().getSequentialDeclaration().appliedType(null, Arrays.asList(type));
    JCExpression seqTypeExpr1 = makeJavaType(sequentialType);
    //JCExpression seqTypeExpr2 = makeJavaType(fixedSizedType);
    JCExpression sizeExpr = make().Apply(List.<JCExpression>nil(), make().Select(seqName.makeIdent(), names().fromString("getSize")), List.<JCExpression>nil());
    sizeExpr = utilInvocation().toInt(sizeExpr);
    // add initial elements if required
    if (!initialElements.isEmpty())
        sizeExpr = make().Binary(JCTree.PLUS, sizeExpr, makeInteger(initialElements.size()));
    JCExpression array = make().NewArray(makeJavaType(arrayType, JT_RAW | JT_NO_PRIMITIVES), List.of(sizeExpr), null);
    if (!arrayType.isExactly(castType)) {
        array = make().TypeCast(make().TypeArray(makeJavaType(castType, JT_CLASS_NEW | JT_NO_PRIMITIVES)), array);
    }
    JCExpression sequenceToArrayExpr = utilInvocation().toArray(seqName.makeIdent(), array, initialElements, makeJavaType(castType, JT_CLASS_NEW | JT_NO_PRIMITIVES));
    return //make().TypeArray(makeJavaType(arrayType)),
    makeLetExpr(seqName, List.<JCStatement>nil(), seqTypeExpr1, expr, sequenceToArrayExpr);
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) ModelUtil.appliedType(com.redhat.ceylon.model.typechecker.model.ModelUtil.appliedType) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter) SyntheticName(com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName)

Example 35 with TypeParameter

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

the class ClassOrPackageDoc method writeTypeParametersConstraints.

protected final void writeTypeParametersConstraints(List<TypeParameter> typeParameters, Referenceable scope) throws IOException {
    for (TypeParameter typeParam : typeParameters) {
        if (typeParam.isConstrained()) {
            open("div class='type-parameter-constraint'");
            write("<span class='type-parameter-keyword'>given</span>");
            write(" ");
            around("span class='type-parameter'", typeParam.getName());
            writeSatisfiedTypes(typeParam, scope);
            writeCaseTypes(typeParam, scope);
            close("div");
        }
    }
}
Also used : TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter)

Aggregations

TypeParameter (com.redhat.ceylon.model.typechecker.model.TypeParameter)59 Type (com.redhat.ceylon.model.typechecker.model.Type)40 JCTypeParameter (com.sun.tools.javac.tree.JCTree.JCTypeParameter)24 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)23 ModelUtil.appliedType (com.redhat.ceylon.model.typechecker.model.ModelUtil.appliedType)21 ArrayList (java.util.ArrayList)15 Function (com.redhat.ceylon.model.typechecker.model.Function)14 Class (com.redhat.ceylon.model.typechecker.model.Class)13 ClassOrInterface (com.redhat.ceylon.model.typechecker.model.ClassOrInterface)13 Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)13 TypedDeclaration (com.redhat.ceylon.model.typechecker.model.TypedDeclaration)13 Parameter (com.redhat.ceylon.model.typechecker.model.Parameter)12 TypedReference (com.redhat.ceylon.model.typechecker.model.TypedReference)12 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)12 JCNewClass (com.sun.tools.javac.tree.JCTree.JCNewClass)10 Generic (com.redhat.ceylon.model.typechecker.model.Generic)9 Constructor (com.redhat.ceylon.model.typechecker.model.Constructor)8 Interface (com.redhat.ceylon.model.typechecker.model.Interface)8 ParameterList (com.redhat.ceylon.model.typechecker.model.ParameterList)8 FunctionOrValue (com.redhat.ceylon.model.typechecker.model.FunctionOrValue)7