Search in sources :

Example 16 with TypeParameter

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

the class AbstractTransformer method isWideningTypeArguments.

private boolean isWideningTypeArguments(Type declType, Type refinedDeclType, boolean allowSubtypes) {
    if (declType == null || refinedDeclType == null)
        return false;
    // make sure we work on simplified types, to avoid stuff like optional or size-1 unions
    declType = simplifyType(declType);
    refinedDeclType = simplifyType(refinedDeclType);
    // special case for type parameters
    if (declType.getDeclaration() instanceof TypeParameter && refinedDeclType.getDeclaration() instanceof TypeParameter) {
        // consider them equivalent if they have the same bounds
        TypeParameter tp = (TypeParameter) declType.getDeclaration();
        TypeParameter refinedTP = (TypeParameter) refinedDeclType.getDeclaration();
        if (haveSameBounds(tp, refinedTP))
            return false;
        // if they don't have the same bounds and we don't allow subtypes then we're widening
        if (!allowSubtypes)
            return false;
        // if we allow subtypes, we're widening if tp is not a subtype of refinedTP
        return !tp.getType().isSubtypeOf(refinedTP.getType());
    }
    if (allowSubtypes) {
        if ((willEraseToObject(refinedDeclType))) {
            // - similarly if we both erase to object we're not widening
            return false;
        }
        // if we have exactly the same type don't bother finding a common ancestor
        if (!declType.isExactly(refinedDeclType)) {
            // check if we can form an informed decision
            if (refinedDeclType.getDeclaration() == null)
                return true;
            // find the instantiation of the refined decl type in the decl type
            // special case for optional types: let's find the definite type since
            // in java they are equivalent
            Type definiteType = typeFact().getDefiniteType(refinedDeclType);
            if (definiteType != null)
                refinedDeclType = definiteType;
            declType = declType.getSupertype(refinedDeclType.getDeclaration());
            // could not find common type, we must be widening somehow
            if (declType == null)
                return true;
        }
    }
    Map<TypeParameter, Type> typeArguments = declType.getTypeArguments();
    Map<TypeParameter, Type> refinedTypeArguments = refinedDeclType.getTypeArguments();
    java.util.List<TypeParameter> typeParameters = declType.getDeclaration().getTypeParameters();
    for (TypeParameter tp : typeParameters) {
        Type typeArgument = typeArguments.get(tp);
        if (typeArgument == null)
            // something fishy here
            return true;
        Type refinedTypeArgument = refinedTypeArguments.get(tp);
        if (refinedTypeArgument == null)
            // something fishy here
            return true;
        // check if the type arg is widening due to erasure
        if (isWidening(typeArgument, refinedTypeArgument))
            return true;
        // check if we are refining a covariant param which we must "fix" because it is dependend on, like Tuple's first TP
        if (declType.isCovariant(tp) && hasDependentTypeParameters(typeParameters, tp) && !typeArgument.isExactly(refinedTypeArgument) && // it is not widening if we refine Object with a TP, though
        !(willEraseToObject(refinedTypeArgument) && (isTypeParameter(typeArgument) || // it is also not widening if we erase both to Object
        willEraseToObject(typeArgument))))
            return true;
        // check if the type arg is a subtype, or if its type args are widening
        if (isWideningTypeArguments(typeArgument, refinedTypeArgument, tp.isCovariant()))
            return true;
    }
    // so far so good
    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)

Example 17 with TypeParameter

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

the class AbstractTransformer method isWideningTypeDecl.

public boolean isWideningTypeDecl(TypedReference typedReference, Type currentType) {
    TypedReference refinedTypedReference = getRefinedDeclaration(typedReference, currentType);
    if (refinedTypedReference == null)
        return false;
    /*
         * We are widening if the type:
         * - is not object
         * - is erased to object
         * - refines a declaration that is not erased to object
         */
    Type declType = typedReference.getType();
    Type refinedDeclType = refinedTypedReference.getType();
    if (declType == null || refinedDeclType == null)
        return false;
    if (isWidening(declType, refinedDeclType))
        return true;
    // make sure we get the instantiated refined decl
    if (refinedDeclType.getDeclaration() instanceof TypeParameter && !(declType.getDeclaration() instanceof TypeParameter))
        refinedDeclType = nonWideningType(typedReference, refinedTypedReference);
    if (isWideningTypeArguments(declType, refinedDeclType, true))
        return true;
    if (CodegenUtil.hasTypeErased(refinedTypedReference.getDeclaration()) && !willEraseToObject(declType))
        return true;
    return false;
}
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) TypedReference(com.redhat.ceylon.model.typechecker.model.TypedReference)

Example 18 with TypeParameter

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

the class AbstractTransformer method hasDependentCovariantTypeParameters.

boolean hasDependentCovariantTypeParameters(Type type) {
    if (type.isUnion()) {
        for (Type m : type.getCaseTypes()) if (hasDependentCovariantTypeParameters(m))
            return true;
        return false;
    }
    if (type.isIntersection()) {
        for (Type m : type.getSatisfiedTypes()) if (hasDependentCovariantTypeParameters(m))
            return true;
        return false;
    }
    // check its type arguments
    // special case for Callable which has only a single type param in Java
    boolean isCallable = isCeylonCallable(type);
    // check if any type parameter is dependent on and covariant
    TypeDeclaration declaration = type.getDeclaration();
    java.util.List<TypeParameter> typeParams = declaration.getTypeParameters();
    Map<TypeParameter, Type> typeArguments = type.getTypeArguments();
    for (TypeParameter typeParam : typeParams) {
        Type typeArg = typeArguments.get(typeParam);
        if (type.isCovariant(typeParam) && hasDependentTypeParameters(typeParams, typeParam)) {
            // see if the type argument in question contains type parameters and is erased to Object
            if (containsTypeParameter(typeArg) && willEraseToObject(typeArg))
                return true;
        }
        // now check if we the type argument has the same problem
        if (hasDependentCovariantTypeParameters(typeArg))
            return true;
        // stop after the first type arg for Callable
        if (isCallable)
            break;
    }
    return false;
}
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) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration)

Example 19 with TypeParameter

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

the class ClassTransformer method buildJpaConstructor.

protected void buildJpaConstructor(Class model, ClassDefinitionBuilder classBuilder) {
    MethodDefinitionBuilder ctor = classBuilder.addConstructor();
    ctor.modelAnnotations(makeAtJpa());
    ctor.modelAnnotations(makeAtIgnore());
    ctor.modifiers(PROTECTED);
    for (TypeParameter tp : model.getTypeParameters()) {
        ctor.reifiedTypeParameter(tp);
    }
    final ListBuffer<JCStatement> stmts = ListBuffer.lb();
    // invoke super (or this if
    ListBuffer<JCExpression> superArgs = ListBuffer.<JCExpression>lb();
    if (model.isSerializable()) {
        superArgs.add(make().TypeCast(make().QualIdent(syms().ceylonSerializationType.tsym), makeNull()));
        for (JCExpression ta : makeReifiedTypeArguments(model.getType())) {
            superArgs.add(ta);
        }
    } else {
        for (JCExpression ta : makeReifiedTypeArguments(model.getExtendedType())) {
            superArgs.add(ta);
        }
    }
    stmts.add(make().Exec(make().Apply(null, model.isSerializable() ? naming.makeThis() : naming.makeSuper(), superArgs.toList())));
    if (!model.isSerializable()) {
        buildFieldInits(model, classBuilder, stmts);
    }
    ctor.body(stmts.toList());
}
Also used : TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement)

Example 20 with TypeParameter

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

the class ClassTransformer method refineMethod.

private Function refineMethod(Scope container, TypedReference pr, ClassOrInterface classModel, Function formalMethod, Unit unit) {
    Function refined = new Function();
    refined.setActual(true);
    refined.setShared(formalMethod.isShared());
    refined.setContainer(container);
    // in case there are subclasses
    refined.setDefault(true);
    refined.setDeferred(false);
    refined.setDeprecated(formalMethod.isDeprecated());
    refined.setName(formalMethod.getName());
    refined.setRefinedDeclaration(formalMethod.getRefinedDeclaration());
    refined.setScope(container);
    refined.setType(pr.getType());
    refined.setUnit(unit);
    refined.setUnboxed(formalMethod.getUnboxed());
    refined.setUntrustedType(formalMethod.getUntrustedType());
    refined.setTypeErased(formalMethod.getTypeErased());
    ArrayList<TypeParameter> refinedTp = new ArrayList<TypeParameter>();
    ;
    for (TypeParameter formalTp : formalMethod.getTypeParameters()) {
        refinedTp.add(formalTp);
    }
    refined.setTypeParameters(refinedTp);
    for (ParameterList formalPl : formalMethod.getParameterLists()) {
        ParameterList refinedPl = new ParameterList();
        for (Parameter formalP : formalPl.getParameters()) {
            Parameter refinedP = new Parameter();
            refinedP.setAtLeastOne(formalP.isAtLeastOne());
            refinedP.setDeclaration(refined);
            refinedP.setDefaulted(formalP.isDefaulted());
            refinedP.setDeclaredAnything(formalP.isDeclaredAnything());
            refinedP.setHidden(formalP.isHidden());
            refinedP.setSequenced(formalP.isSequenced());
            refinedP.setName(formalP.getName());
            final TypedReference typedParameter = pr.getTypedParameter(formalP);
            FunctionOrValue paramModel;
            if (formalP.getModel() instanceof Value) {
                Value paramValueModel = refineValue((Value) formalP.getModel(), typedParameter, refined, classModel.getUnit());
                paramValueModel.setInitializerParameter(refinedP);
                paramModel = paramValueModel;
            } else {
                Function paramFunctionModel = refineMethod(refined, typedParameter, classModel, (Function) formalP.getModel(), unit);
                paramFunctionModel.setInitializerParameter(refinedP);
                paramModel = paramFunctionModel;
            }
            refinedP.setModel(paramModel);
            refinedPl.getParameters().add(refinedP);
        }
        refined.addParameterList(refinedPl);
    }
    return refined;
}
Also used : Function(com.redhat.ceylon.model.typechecker.model.Function) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) TypedReference(com.redhat.ceylon.model.typechecker.model.TypedReference) ArrayList(java.util.ArrayList) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(com.redhat.ceylon.model.loader.model.JavaBeanValue) Value(com.redhat.ceylon.model.typechecker.model.Value) ParameterList(com.redhat.ceylon.model.typechecker.model.ParameterList) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue)

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