Search in sources :

Example 21 with TypeParameter

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

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(org.eclipse.ceylon.model.typechecker.model.TypeParameter)

Example 22 with TypeParameter

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

the class ExpressionVisitor method accountForIntermediateRefinements.

private Reference accountForIntermediateRefinements(Tree.SpecifierStatement that, FunctionOrValue refinedMethodOrValue, FunctionOrValue methodOrValue, ClassOrInterface refiningType, List<Declaration> interveningRefinements) {
    // accumulate an intersection of the types of
    // everything it refines
    List<Type> refinedTypes = new ArrayList<Type>();
    // don't check this one here because it is
    // separately checked in visit(SpecifierStatement)
    Reference refinedProducedReference = getRefinedMemberReference(refinedMethodOrValue, refiningType);
    Map<TypeParameter, Type> substs = substitutions(refinedMethodOrValue, methodOrValue);
    Type refinedType = refinedProducedReference.getType().substitute(substs, null);
    boolean allHaveNulls = hasNullReturnValues(refinedType, refinedMethodOrValue);
    intersectReturnType(refinedTypes, refinedType);
    for (Declaration intervening : interveningRefinements) {
        if (intervening instanceof FunctionOrValue && // factors here as well?
        !refinedMethodOrValue.equals(intervening)) {
            FunctionOrValue refinement = (FunctionOrValue) intervening;
            Reference refinedMember = getRefinedMemberReference(refinement, refiningType);
            Map<TypeParameter, Type> subs = substitutions(refinement, methodOrValue);
            Type type = refinedMember.getType().substitute(subs, null);
            allHaveNulls = allHaveNulls && hasNullReturnValues(type, refinement);
            intersectReturnType(refinedTypes, type);
            checkIntermediateRefinement(that, refinement, refinedMember);
        }
    }
    Type it = canonicalIntersection(refinedTypes, unit);
    if (allHaveNulls && !unit.isOptionalType(it)) {
        methodOrValue.setUncheckedNullType(true);
        Tree.Term lhs = that.getBaseMemberExpression();
        // TODO: this is pretty ugly, think of something better!
        lhs.setTypeModel(unit.getOptionalType(lhs.getTypeModel()));
    }
    methodOrValue.setType(it);
    return refinedProducedReference;
}
Also used : ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) ModelUtil.unionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType) AnalyzerUtil.spreadType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType) AnalyzerUtil.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) ModelUtil.genericFunctionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.genericFunctionType) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) ArrayList(java.util.ArrayList) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) AnalyzerUtil.getPackageTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) AnalyzerUtil.getPackageTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) ModelUtil.getNativeDeclaration(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getNativeDeclaration) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 23 with TypeParameter

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

the class ExpressionVisitor method substitutions.

private static Map<TypeParameter, Type> substitutions(FunctionOrValue refined, FunctionOrValue member) {
    if (refined instanceof Function) {
        Function refinedMethod = (Function) refined;
        Function method = (Function) member;
        List<TypeParameter> refinedParams = refinedMethod.getTypeParameters();
        List<TypeParameter> params = method.getTypeParameters();
        Map<TypeParameter, Type> result = new HashMap<TypeParameter, Type>(params.size());
        for (int i = 0; i < refinedParams.size() && i < params.size(); i++) {
            result.put(refinedParams.get(i), params.get(i).getType());
        }
        return result;
    } else {
        return NO_SUBSTITUTIONS;
    }
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) ModelUtil.unionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType) AnalyzerUtil.spreadType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType) AnalyzerUtil.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) ModelUtil.genericFunctionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.genericFunctionType) HashMap(java.util.HashMap) AnalyzerUtil.checkCasesDisjoint(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.checkCasesDisjoint) ModelUtil.argumentSatisfiesEnumeratedConstraint(org.eclipse.ceylon.model.typechecker.model.ModelUtil.argumentSatisfiesEnumeratedConstraint)

Example 24 with TypeParameter

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

the class ExpressionVisitor method checkTypeConstructorParam.

private void checkTypeConstructorParam(TypeParameter param, Type argType, Node argNode) {
    if (!argType.isTypeConstructor()) {
        argNode.addError("not a type constructor: '" + argType.asString(unit) + "'");
    } else {
        argType = unwrapAliasedTypeConstructor(argType);
        if (argType.isUnion()) {
            for (Type ct : argType.getCaseTypes()) {
                checkTypeConstructorParam(param, ct, argNode);
            }
        } else if (argType.isIntersection()) {
            for (Type st : argType.getSatisfiedTypes()) {
                checkTypeConstructorParam(param, st, argNode);
            }
        } else if (argType.isNothing()) {
        // just let it through?!
        } else {
            TypeDeclaration argTypeDec = argType.getDeclaration();
            List<TypeParameter> argTypeParams = argTypeDec.getTypeParameters();
            int allowed = argTypeParams.size();
            int required = 0;
            for (TypeParameter tp : argTypeParams) {
                if (tp.isDefaulted()) {
                    break;
                }
                required++;
            }
            List<TypeParameter> paramTypeParams = param.getTypeParameters();
            int size = paramTypeParams.size();
            if (allowed < size || required > size) {
                argNode.addError("argument type constructor has wrong number of type parameters: argument '" + argTypeDec.getName(unit) + "' has " + allowed + " type parameters " + "but parameter '" + param.getName(unit) + "' has " + size + " type parameters");
            }
            for (int j = 0; j < size && j < allowed; j++) {
                TypeParameter paramParam = paramTypeParams.get(j);
                TypeParameter argParam = argTypeParams.get(j);
                if (paramParam.isCovariant() && !argParam.isCovariant()) {
                    argNode.addError("argument type constructor is not covariant: '" + argParam.getName() + "' of '" + argTypeDec.getName(unit) + "' must have the same variance as '" + paramParam.getName() + "' of '" + param.getName(unit) + "'");
                } else if (paramParam.isContravariant() && !argParam.isContravariant()) {
                    argNode.addError("argument type constructor is not contravariant: '" + argParam.getName() + "' of '" + argTypeDec.getName(unit) + "' must have the same variance as '" + paramParam.getName() + "' of '" + param.getName(unit) + "'");
                }
                if (!intersectionOfSupertypes(paramParam).isSubtypeOf(intersectionOfSupertypes(argParam))) {
                    argNode.addError("upper bound on type parameter of argument type constructor is not a supertype of upper bound on corresponding type parameter of parameter: '" + argParam.getName() + "' of '" + argTypeDec.getName(unit) + "' does accept all type arguments accepted by '" + paramParam.getName() + "' of '" + param.getName(unit) + "'");
                }
                if (!unionOfCaseTypes(paramParam).isSubtypeOf(unionOfCaseTypes(argParam))) {
                    argNode.addError("enumerated bound on type parameter of argument type constructor is not a supertype of enumerated bound on corresponding type parameter of parameter: '" + argParam.getName() + "' of '" + argTypeDec.getName(unit) + "' does accept all type arguments accepted by '" + paramParam.getName() + "' of '" + param.getName(unit) + "'");
                }
            }
        }
    }
}
Also used : ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) ModelUtil.unionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType) AnalyzerUtil.spreadType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType) AnalyzerUtil.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) ModelUtil.genericFunctionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.genericFunctionType) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) AnalyzerUtil.getPackageTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration) AnalyzerUtil.checkCasesDisjoint(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.checkCasesDisjoint) ModelUtil.argumentSatisfiesEnumeratedConstraint(org.eclipse.ceylon.model.typechecker.model.ModelUtil.argumentSatisfiesEnumeratedConstraint)

Example 25 with TypeParameter

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

the class ExpressionVisitor method refineMethod.

private void refineMethod(Tree.SpecifierStatement that) {
    Function refinedMethod = (Function) that.getRefined();
    Function method = (Function) that.getDeclaration();
    ClassOrInterface ci = (ClassOrInterface) method.getContainer();
    Declaration root = method.getRefinedDeclaration();
    TypeDeclaration td = (TypeDeclaration) root.getContainer();
    List<Declaration> interveningRefinements = getInterveningRefinements(method, root, ci, td);
    if (interveningRefinements.isEmpty()) {
        that.getBaseMemberExpression().addError("shortcut refinement does not exactly refine any overloaded inherited member");
    } else {
        Reference refinedProducedReference = accountForIntermediateRefinements(that, refinedMethod, method, ci, interveningRefinements);
        List<Tree.ParameterList> parameterLists;
        Tree.Term me = that.getBaseMemberExpression();
        if (me instanceof Tree.ParameterizedExpression) {
            Tree.ParameterizedExpression pe = (Tree.ParameterizedExpression) me;
            parameterLists = pe.getParameterLists();
        } else {
            parameterLists = emptyList();
        }
        List<ParameterList> refinedParamLists = refinedMethod.getParameterLists();
        List<ParameterList> methodParamLists = method.getParameterLists();
        Map<TypeParameter, Type> subs = substitutions(refinedMethod, method);
        for (int i = 0; i < refinedParamLists.size() && i < methodParamLists.size(); i++) {
            ParameterList refinedParameters = refinedParamLists.get(i);
            ParameterList parameters = methodParamLists.get(i);
            Tree.ParameterList parameterList = parameterLists.size() <= i ? null : parameterLists.get(i);
            List<Parameter> rps = refinedParameters.getParameters();
            for (int j = 0; j < rps.size(); j++) {
                Parameter refinedParameter = rps.get(j);
                Type refinedParameterType = refinedProducedReference.getTypedParameter(refinedParameter).getFullType().substitute(subs, null);
                Parameter parameter;
                if (parameterList == null || parameterList.getParameters().size() <= j) {
                    parameter = parameters.getParameters().get(j);
                    parameter.getModel().setType(refinedParameterType);
                    parameter.setSequenced(refinedParameter.isSequenced());
                } else {
                    Tree.Parameter param = parameterList.getParameters().get(j);
                    parameter = param.getParameterModel();
                    Type parameterType = parameter.getModel().getTypedReference().getFullType();
                    Node typeNode = param;
                    if (param instanceof Tree.ParameterDeclaration) {
                        Tree.ParameterDeclaration pd = (Tree.ParameterDeclaration) param;
                        Tree.Type type = pd.getTypedDeclaration().getType();
                        if (type != null) {
                            typeNode = type;
                        }
                    }
                    checkIsExactlyIgnoringNull(refinedParameters.isNamedParametersSupported(), parameterType, refinedParameterType, typeNode, "type of parameter '" + parameter.getName() + "' of '" + method.getName() + "' declared by '" + ci.getName() + "' is different to type of corresponding parameter " + message(refinedMethod, refinedParameter), 9200);
                    if (refinedParameter.isSequenced() && !parameter.isSequenced()) {
                        param.addError("parameter must be variadic: parameter " + message(refinedMethod, refinedParameter) + " is variadic");
                    }
                    if (!refinedParameter.isSequenced() && parameter.isSequenced()) {
                        param.addError("parameter may not be variadic: parameter " + message(refinedMethod, refinedParameter) + " is not variadic");
                    }
                }
            }
        }
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) ModelUtil.getOuterClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getOuterClassOrInterface) ModelUtil.getContainingClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Node(org.eclipse.ceylon.compiler.typechecker.tree.Node) Function(org.eclipse.ceylon.model.typechecker.model.Function) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) AnalyzerUtil.getPackageTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) AnalyzerUtil.getPackageTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) ModelUtil.getNativeDeclaration(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getNativeDeclaration) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) AnalyzerUtil.checkCasesDisjoint(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.checkCasesDisjoint) ModelUtil.argumentSatisfiesEnumeratedConstraint(org.eclipse.ceylon.model.typechecker.model.ModelUtil.argumentSatisfiesEnumeratedConstraint) ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) ModelUtil.unionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType) AnalyzerUtil.spreadType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType) AnalyzerUtil.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) ModelUtil.genericFunctionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.genericFunctionType) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) 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) AnalyzerUtil.getPackageTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)

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