Search in sources :

Example 76 with TypeParameter

use of org.eclipse.ceylon.model.typechecker.model.TypeParameter in project ceylon by eclipse.

the class TypeArgumentInference method inferTypeArgumentFromPositionalArgs.

private Type inferTypeArgumentFromPositionalArgs(TypeParameter tp, ParameterList parameters, Type receiverType, Tree.PositionalArgumentList pal, Declaration invoked) {
    boolean findingUpperBounds = isEffectivelyContravariant(tp, invoked, specifiedParameters(pal, parameters), false);
    List<Tree.PositionalArgument> args = pal.getPositionalArguments();
    List<Type> inferredTypes = new ArrayList<Type>(args.size());
    List<Parameter> params = parameters.getParameters();
    for (int i = 0, len = params.size(); i < len; i++) {
        Parameter parameter = params.get(i);
        if (args.size() > i) {
            Tree.PositionalArgument arg = args.get(i);
            if (arg instanceof Tree.SpreadArgument) {
                inferTypeArgFromSpreadArg(tp, receiverType, arg, i, invoked, findingUpperBounds, inferredTypes, params, pal);
            } else if (arg instanceof Tree.Comprehension) {
                if (parameter.isSequenced()) {
                    Tree.Comprehension c = (Tree.Comprehension) arg;
                    inferTypeArgFromComprehension(tp, parameter, c, findingUpperBounds, inferredTypes);
                }
            } else {
                if (parameter.isSequenced()) {
                    inferTypeArgFromPositionalArgs(tp, parameter, args.subList(i, args.size()), findingUpperBounds, inferredTypes);
                    break;
                } else {
                    Type parameterType = parameterType(receiverType, parameter, invoked);
                    Type argType = arg.getTypeModel();
                    addToUnionOrIntersection(findingUpperBounds, inferredTypes, inferTypeArg(tp, parameterType, argType, findingUpperBounds, pal));
                }
            }
        }
    }
    return unionOrIntersection(findingUpperBounds, inferredTypes);
}
Also used : ArrayList(java.util.ArrayList) PositionalArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.PositionalArgument) Type(org.eclipse.ceylon.model.typechecker.model.Type) ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) AnalyzerUtil.spreadType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType) AnalyzerUtil.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType) AnalyzerUtil.getUnspecifiedParameter(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getUnspecifiedParameter) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) AnalyzerUtil.getMatchingParameter(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getMatchingParameter) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) PositionalArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.PositionalArgument)

Example 77 with TypeParameter

use of org.eclipse.ceylon.model.typechecker.model.TypeParameter in project ceylon by eclipse.

the class TypeArgumentInference method inferFunctionRefTypeArgs.

/**
 * Infer the type arguments for a reference to a
 * generic function that occurs as a parameter in
 * an invocation. This implementation is used when
 * have an indirect ref whose type is a type
 * constructor. This version is also used for
 * static references.
 */
private List<Type> inferFunctionRefTypeArgs(Tree.StaticMemberOrTypeExpression smte, Type receiverType, boolean secondList, Declaration reference, List<TypeParameter> typeParameters, Type paramType, Declaration parameterizedDec) {
    Reference arg = appliedReference(smte);
    // this is the type of the parameter list
    // of the function ref itself, which
    // involves the type parameters we are
    // trying to infer
    Type parameterListType;
    Type fullType;
    Type argType;
    if (smte.getStaticMethodReferencePrimary()) {
        argType = arg.getType();
        parameterListType = appliedType(unit.getTupleDeclaration(), argType, argType, unit.getEmptyType());
        fullType = appliedType(unit.getCallableDeclaration(), argType, parameterListType);
    } else {
        fullType = arg.getFullType();
        if (secondList) {
            fullType = unit.getCallableReturnType(fullType);
        }
        parameterListType = unit.getCallableTuple(fullType);
        argType = unit.getCallableReturnType(fullType);
    }
    // this is the type of the parameter list
    // of the callable parameter that the
    // function ref is being passed to (these
    // parameters are going to be assigned to
    // the parameters of the function ref)
    Type argumentListType = unit.getCallableTuple(paramType);
    Type returnType = unit.getCallableReturnType(paramType);
    int argCount = unit.getTupleElementTypes(argumentListType).size();
    List<Type> inferredTypes = new ArrayList<Type>(typeParameters.size());
    for (TypeParameter tp : typeParameters) {
        boolean findUpperBounds = isEffectivelyContravariant(tp, fullType, argCount);
        Type type = inferFunctionRefTypeArg(smte, tp, parameterizedDec, parameterListType, argumentListType, argType, returnType, findUpperBounds);
        inferredTypes.add(type);
    }
    return constrainInferredTypes(typeParameters, inferredTypes, receiverType, reference);
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) AnalyzerUtil.spreadType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType) AnalyzerUtil.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) ArrayList(java.util.ArrayList)

Example 78 with TypeParameter

use of org.eclipse.ceylon.model.typechecker.model.TypeParameter in project ceylon by eclipse.

the class TypeArgumentInference method inferNullaryFunctionCallTypeArgs.

/**
 * Infer type arguments for the invocation of a
 * nullary function that occurs as an argument.
 * The parameter to which it is an argument isn't
 * a callable parameter.
 */
private List<Type> inferNullaryFunctionCallTypeArgs(Tree.StaticMemberOrTypeExpression smte, Type receiverType, Declaration reference, List<TypeParameter> typeParameters, Type paramType, Declaration parameterizedDec) {
    Reference arg = appliedReference(smte);
    List<Type> inferredTypes = new ArrayList<Type>(typeParameters.size());
    Type argType = arg.getType();
    TypeDeclaration ptd = paramType.getDeclaration();
    Type template = // all supertypes of argType?
    ptd instanceof ClassOrInterface ? argType.getSupertype(ptd) : argType;
    for (TypeParameter tp : typeParameters) {
        boolean covariant = template.occursCovariantly(tp) && !template.occursContravariantly(tp);
        boolean contravariant = template.occursContravariantly(tp) && !template.occursCovariantly(tp);
        Type it = inferNullaryFunctionCallTypeArg(smte, tp, paramType, parameterizedDec, template, covariant, contravariant);
        inferredTypes.add(it);
    }
    return constrainInferredTypes(typeParameters, inferredTypes, receiverType, reference);
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) Type(org.eclipse.ceylon.model.typechecker.model.Type) ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) AnalyzerUtil.spreadType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType) AnalyzerUtil.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) ArrayList(java.util.ArrayList) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 79 with TypeParameter

use of org.eclipse.ceylon.model.typechecker.model.TypeParameter in project ceylon by eclipse.

the class TypeArgumentInference method inferNullaryFunctionCallTypeArg.

private Type inferNullaryFunctionCallTypeArg(Tree.StaticMemberOrTypeExpression smte, TypeParameter tp, Type paramType, Declaration parameterizedDec, Type template, boolean covariant, boolean contravariant) {
    // if (covariant) {
    // it = unit.getNothingType();
    // }
    // else if (contravariant) {
    // it = intersectionOfSupertypes(tp);
    // }
    // else {
    List<Type> list = new ArrayList<Type>(1);
    Type rt = inferTypeArg(tp, template, paramType, !covariant, !contravariant, false, new ArrayList<TypeParameter>(), smte);
    if (!isTypeUnknown(rt) && !involvesTypeParams(parameterizedDec, rt)) {
        addToUnionOrIntersection(contravariant, list, rt);
    }
    return unionOrIntersection(contravariant, list);
// }
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) AnalyzerUtil.spreadType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType) AnalyzerUtil.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) ArrayList(java.util.ArrayList)

Example 80 with TypeParameter

use of org.eclipse.ceylon.model.typechecker.model.TypeParameter in project ceylon by eclipse.

the class InheritanceVisitor method validateEnumeratedSupertypeArgument.

private void validateEnumeratedSupertypeArgument(Node that, TypeDeclaration type, Type supertype, TypeParameter tp, Type arg) {
    Unit unit = that.getUnit();
    if (arg.isTypeParameter()) {
        TypeParameter atp = (TypeParameter) arg.getDeclaration();
        if (atp.getDeclaration().equals(type)) {
            // parameter of the enumerated supertype
            if (tp.isCovariant() && !atp.isCovariant()) {
                that.addError("argument to covariant type parameter of enumerated supertype must be covariant: " + typeDescription(tp, unit));
            }
            if (tp.isContravariant() && !atp.isContravariant()) {
                that.addError("argument to contravariant type parameter of enumerated supertype must be contravariant: " + typeDescription(tp, unit));
            }
        } else {
            that.addError("argument to type parameter of enumerated supertype must be a type parameter of '" + type.getName() + "': " + typeDescription(tp, unit));
        }
    } else if (tp.isCovariant()) {
        if (!(arg.isNothing())) {
            // TODO: let it be the union of the lower bounds on p
            that.addError("argument to covariant type parameter of enumerated supertype must be a type parameter or 'Nothing': " + typeDescription(tp, unit));
        }
    } else if (tp.isContravariant()) {
        List<Type> sts = tp.getSatisfiedTypes();
        // TODO: do I need to do type arg substitution here??
        Type ub = intersectionOfSupertypes(tp);
        if (!(arg.isExactly(ub))) {
            that.addError("argument to contravariant type parameter of enumerated supertype must be a type parameter or '" + typeNamesAsIntersection(sts, unit) + "': " + typeDescription(tp, unit));
        }
    } else {
        that.addError("argument to type parameter of enumerated supertype must be a type parameter: " + typeDescription(tp, unit));
    }
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Type(org.eclipse.ceylon.model.typechecker.model.Type) Unit(org.eclipse.ceylon.model.typechecker.model.Unit)

Aggregations

TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)181 Type (org.eclipse.ceylon.model.typechecker.model.Type)138 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)82 ArrayList (java.util.ArrayList)57 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)57 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)54 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)46 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)45 ModelUtil.intersectionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType)35 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)32 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)30 Function (org.eclipse.ceylon.model.typechecker.model.Function)29 AnalyzerUtil.getTupleType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType)28 AnalyzerUtil.spreadType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType)28 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)28 IntersectionType (org.eclipse.ceylon.model.typechecker.model.IntersectionType)27 JCTypeParameter (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCTypeParameter)26 Class (org.eclipse.ceylon.model.typechecker.model.Class)26 UnionType (org.eclipse.ceylon.model.typechecker.model.UnionType)25 HashMap (java.util.HashMap)24