Search in sources :

Example 11 with SiteVariance

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

the class TypeParserTests method testParamsVariance2.

@Test
public void testParamsVariance2() {
    Type type = new TypeParser(MockLoader.instance).decodeType("t2<b,out c>", null, mockDefaultModule, mockPkgUnit);
    assertTypeWithParameters(type);
    Map<TypeParameter, SiteVariance> varianceOverrides = type.getVarianceOverrides();
    Assert.assertNotNull(varianceOverrides);
    Assert.assertEquals(1, varianceOverrides.size());
    List<TypeParameter> tps = type.getDeclaration().getTypeParameters();
    Assert.assertEquals(null, varianceOverrides.get(tps.get(0)));
    Assert.assertEquals(SiteVariance.OUT, varianceOverrides.get(tps.get(1)));
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) IntersectionType(org.eclipse.ceylon.model.typechecker.model.IntersectionType) UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) TypeParser(org.eclipse.ceylon.model.loader.TypeParser) SiteVariance(org.eclipse.ceylon.model.typechecker.model.SiteVariance) Test(org.junit.Test)

Example 12 with SiteVariance

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

the class TypeParser method parseTypeArgumentVariance.

/**
 * Spec says:
 * <blockquote><pre>
 * Variance: ("out" | "in")?
 * </blockquote></pre>
 * Which is what we do, but by updating the given part.
 */
private void parseTypeArgumentVariance(Part type) {
    SiteVariance variance = null;
    if (lexer.lookingAt(TypeLexer.OUT)) {
        variance = SiteVariance.OUT;
        lexer.eat();
    } else if (lexer.lookingAt(TypeLexer.IN)) {
        variance = SiteVariance.IN;
        lexer.eat();
    }
    // lazy allocation
    if (variance != null && type.variance == null) {
        type.variance = new LinkedList<SiteVariance>();
        for (int i = 0, l = type.getParameters().size(); i < l; i++) {
            // patch it up for the previous type params which did not have variance
            type.variance.add(null);
        }
    }
    // only add the variance if we have to
    if (type.variance != null) {
        // we add it even if it's null, as long as we're recording variance
        type.variance.add(variance);
    }
}
Also used : SiteVariance(org.eclipse.ceylon.model.typechecker.model.SiteVariance)

Example 13 with SiteVariance

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

the class ExpressionVisitor method checkArgumentsAgainstTypeConstructor.

private void checkArgumentsAgainstTypeConstructor(List<Type> typeArguments, Tree.TypeArguments tas, Type type, Node parent) {
    boolean explicit = tas instanceof Tree.TypeArgumentList;
    TypeDeclaration tcd = type.getDeclaration();
    List<TypeParameter> typeParameters = tcd.getTypeParameters();
    int size = typeArguments.size();
    if (size != typeParameters.size()) {
        tas.addError("wrong number of type arguments: type constructor requires " + size + " type arguments");
    } else {
        Map<TypeParameter, Type> args = getTypeArgumentMap(tcd, null, typeArguments);
        Map<TypeParameter, SiteVariance> variances = // TODO!!!!!
        Collections.emptyMap();
        for (int i = 0; i < size; i++) {
            TypeParameter param = typeParameters.get(i);
            Type arg = typeArguments.get(i);
            if (!isTypeUnknown(arg)) {
                List<Type> sts = param.getSatisfiedTypes();
                for (Type st : sts) {
                    Type bound = st.substitute(args, variances);
                    if (!isTypeUnknown(bound) && !arg.isSubtypeOf(bound)) {
                        String message = "type argument '" + arg.asString(unit) + "' is not assignable to upper bound '" + bound.asString(unit) + "' of type parameter '" + param.getName() + "' of '" + param.getDeclaration().getName(unit) + "'";
                        if (explicit) {
                            typeArgNode(tas, i, parent).addError(message);
                        } else {
                            parent.addError("inferred " + message);
                        }
                    }
                }
            }
            if (!satisfiesEnumeratedConstraint(param, arg, args, variances)) {
                String message = "type argument '" + arg.asString(unit) + "' is not one of the enumerated cases of the type parameter '" + param.getName() + "' of '" + param.getDeclaration().getName(unit) + "'";
                if (explicit) {
                    typeArgNode(tas, i, parent).addError(message);
                } else {
                    parent.addError("inferred " + message);
                }
            }
        }
    }
}
Also used : 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) SiteVariance(org.eclipse.ceylon.model.typechecker.model.SiteVariance) 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 14 with SiteVariance

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

the class AnalyzerUtil method getTypeArguments.

/**
 * Get the type arguments specified explicitly in the
 * code, or an empty list if no type arguments were
 * explicitly specified. For missing arguments, use
 * default type arguments.
 *
 * @param tas the type argument list
 * @param qualifyingType the qualifying type
 * @param typeParameters the list of type parameters
 *
 * @return a list of type arguments to the given type
 *         parameters
 */
static List<Type> getTypeArguments(Tree.TypeArguments tas, Type qualifyingType, List<TypeParameter> typeParameters) {
    if (tas instanceof Tree.TypeArgumentList) {
        // accumulate substitutions in case we need
        // them below for calculating default args
        Map<TypeParameter, Type> typeArgs = new HashMap<TypeParameter, Type>();
        Map<TypeParameter, SiteVariance> vars = new HashMap<TypeParameter, SiteVariance>();
        if (qualifyingType != null) {
            typeArgs.putAll(qualifyingType.getTypeArguments());
            vars.putAll(qualifyingType.getVarianceOverrides());
        }
        Tree.TypeArgumentList tal = (Tree.TypeArgumentList) tas;
        int size = typeParameters.size();
        List<Type> typeArguments = new ArrayList<Type>(size);
        List<Tree.Type> types = tal.getTypes();
        int count = types.size();
        for (int i = 0; i < count; i++) {
            Tree.Type type = types.get(i);
            Type t = type.getTypeModel();
            if (t == null) {
                typeArguments.add(null);
            } else {
                typeArguments.add(t);
                if (i < size) {
                    TypeParameter tp = typeParameters.get(i);
                    if (tp.isTypeConstructor()) {
                        setTypeConstructor(type, tp);
                    }
                    typeArgs.put(tp, t);
                    if (type instanceof Tree.StaticType) {
                        Tree.StaticType st = (Tree.StaticType) type;
                        TypeVariance tv = st.getTypeVariance();
                        if (tv != null) {
                            boolean contra = tv.getText().equals("in");
                            vars.put(tp, contra ? IN : OUT);
                        }
                    }
                }
            }
        }
        // for missing arguments, use the default args
        for (int i = typeArguments.size(); i < size; i++) {
            TypeParameter tp = typeParameters.get(i);
            Type dta = tp.getDefaultTypeArgument();
            if (dta == null) {
                break;
            } else {
                Type da = dta.substitute(typeArgs, vars);
                typeArguments.add(da);
                typeArgs.put(tp, da);
            }
        }
        return typeArguments;
    } else if (tas instanceof Tree.InferredTypeArguments && tas.getTypeModels() != null) {
        return tas.getTypeModels();
    } else {
        return emptyList();
    }
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) TypeVariance(org.eclipse.ceylon.compiler.typechecker.tree.Tree.TypeVariance) ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) NothingType(org.eclipse.ceylon.model.typechecker.model.NothingType) ModelUtil.unionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) SiteVariance(org.eclipse.ceylon.model.typechecker.model.SiteVariance) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree)

Example 15 with SiteVariance

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

the class JsonPackage method loadTypeArguments.

/**
 * Load the type arguments from a map where keys are the type argument names (including their types,
 * e.g. List.Element) and the keys are maps suitable for decoding with getTypeFromJson)
 */
Type loadTypeArguments(Map<String, Object> m, final TypeDeclaration td, final Declaration container, final List<TypeParameter> typeParams) {
    if (td == null) {
        return null;
    }
    @SuppressWarnings("unchecked") final Map<String, Map<String, Object>> targs = (Map<String, Map<String, Object>>) m.get(KEY_TYPE_ARGS);
    if (targs == null) {
        return null;
    }
    // Substitute type parameters
    final HashMap<TypeParameter, Type> concretes = new HashMap<>(targs.size());
    HashMap<TypeParameter, SiteVariance> variances = null;
    Declaration d = td;
    while (d != null) {
        for (TypeParameter tparm : d.getTypeParameters()) {
            Map<String, Object> targMap = targs.get(partiallyQualifiedName(d) + "." + tparm.getName());
            if (targMap == null) {
                // TODO error I guess
                continue;
            }
            if (targMap.containsKey(KEY_PACKAGE) || targMap.containsKey(KEY_TYPES)) {
                // Substitute for proper type
                final Type _pt = getTypeFromJson(targMap, container, typeParams);
                concretes.put(tparm, _pt);
            } else if (targMap.containsKey(KEY_NAME) && typeParams != null) {
                // Look for type parameter with same name
                for (TypeParameter typeParam : typeParams) {
                    if (typeParam.getName().equals(targMap.get(KEY_NAME))) {
                        concretes.put(tparm, typeParam.getType());
                    }
                }
            }
            Integer usv = (Integer) targMap.get(KEY_US_VARIANCE);
            if (usv != null) {
                if (variances == null) {
                    variances = new HashMap<>();
                }
                variances.put(tparm, SiteVariance.values()[usv]);
            }
        }
        d = ModelUtil.getContainingDeclaration(d);
    }
    if (!concretes.isEmpty()) {
        return td.getType().substitute(concretes, variances);
    }
    return null;
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) HashMap(java.util.HashMap) IntersectionType(org.eclipse.ceylon.model.typechecker.model.IntersectionType) NothingType(org.eclipse.ceylon.model.typechecker.model.NothingType) UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) SiteVariance(org.eclipse.ceylon.model.typechecker.model.SiteVariance) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) Map(java.util.Map) HashMap(java.util.HashMap)

Aggregations

SiteVariance (org.eclipse.ceylon.model.typechecker.model.SiteVariance)20 Type (org.eclipse.ceylon.model.typechecker.model.Type)18 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)18 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)11 IntersectionType (org.eclipse.ceylon.model.typechecker.model.IntersectionType)8 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)8 ArrayList (java.util.ArrayList)7 HashMap (java.util.HashMap)7 UnionType (org.eclipse.ceylon.model.typechecker.model.UnionType)7 NothingType (org.eclipse.ceylon.model.typechecker.model.NothingType)6 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)5 ModelUtil.intersectionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType)5 Map (java.util.Map)4 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)4 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)4 LinkedHashMap (java.util.LinkedHashMap)3 AnalyzerUtil.getPackageTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration)3 AnalyzerUtil.getTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)3 TypeParser (org.eclipse.ceylon.model.loader.TypeParser)3 LazyType (org.eclipse.ceylon.model.typechecker.model.LazyType)3