Search in sources :

Example 51 with Unit

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

the class InheritanceVisitor method collectCaseTypes.

void collectCaseTypes(Tree.CaseTypes that, TypeDeclaration td) {
    Set<TypeDeclaration> typeSet = new HashSet<TypeDeclaration>();
    for (Tree.StaticType ct : that.getTypes()) {
        Type type = ct.getTypeModel();
        if (!isTypeUnknown(type)) {
            type = type.resolveAliases();
            TypeDeclaration ctd = type.getDeclaration();
            if (!typeSet.add(ctd)) {
                // this error is not really truly necessary
                Unit unit = that.getUnit();
                ct.addError("duplicate case type: '" + ctd.getName(unit) + "' of '" + td.getName() + "'");
            }
            if (!(ctd instanceof TypeParameter)) {
                // it's not a self type
                if (checkDirectSubtype(td, ct, type)) {
                    checkAssignable(type, td.getType(), ct, getCaseTypeExplanation(td, type));
                }
            // note: this is a better, faster way to call
            // validateEnumeratedSupertypeArguments()
            // but unfortunately it winds up displaying
            // the error on the wrong node, confusing
            // the user
            /*
                    Type supertype = 
                            type.getDeclaration()
                                .getType()
                                .getSupertype(td);
                    validateEnumeratedSupertypeArguments(t, 
                            type.getDeclaration(), supertype);
                    */
            }
            checkCaseType(td, ct, ctd);
        }
    }
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Unit(org.eclipse.ceylon.model.typechecker.model.Unit) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) HashSet(java.util.HashSet)

Example 52 with Unit

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

the class InheritanceVisitor method validateUpperBounds.

private void validateUpperBounds(Tree.TypeConstraint that, TypeDeclaration td) {
    if (!td.isInconsistentType()) {
        Unit unit = that.getUnit();
        List<Type> upperBounds = td.getSatisfiedTypes();
        List<Type> list = new ArrayList<Type>(upperBounds.size());
        for (Type st : upperBounds) {
            addToIntersection(list, st, unit);
        }
        if (canonicalIntersection(list, unit).isNothing()) {
            that.addError(typeDescription(td, unit) + " has unsatisfiable upper bound constraints: the constraints '" + typeNamesAsIntersection(upperBounds, unit) + "' cannot be satisfied by any type except 'Nothing'");
        }
    }
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) ArrayList(java.util.ArrayList) Unit(org.eclipse.ceylon.model.typechecker.model.Unit)

Example 53 with Unit

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

the class InheritanceVisitor method visit.

@Override
public void visit(Tree.SatisfiedTypes that) {
    super.visit(that);
    TypeDeclaration td = (TypeDeclaration) that.getScope();
    if (td.isAlias()) {
        return;
    }
    Set<TypeDeclaration> set = new HashSet<TypeDeclaration>();
    if (td.getSatisfiedTypes().isEmpty()) {
        // handle undecidable case
        return;
    }
    Unit unit = that.getUnit();
    for (Tree.StaticType t : that.getTypes()) {
        Type type = t.getTypeModel();
        if (!isTypeUnknown(type) && type.isClassOrInterface()) {
            type = type.resolveAliases();
            TypeDeclaration dec = type.getDeclaration();
            if (td instanceof ClassOrInterface && !unit.getPackage().getModule().isLanguageModule()) {
                if (unit.isCallableType(type)) {
                    t.addError("satisfies 'Callable'");
                }
                TypeDeclaration cad = unit.getConstrainedAnnotationDeclaration();
                if (dec.equals(cad)) {
                    t.addError("directly satisfies 'ConstrainedAnnotation'");
                }
            }
            if (!set.add(dec)) {
                // this error is not really truly necessary
                // but the spec says it is an error, and
                // the backend doesn't like it
                t.addError("duplicate satisfied type: '" + dec.getName(unit) + "' of '" + td.getName() + "'");
            }
            if (td instanceof ClassOrInterface) {
                TypeDeclaration std = dec;
                if (std.isSealed() && !unit.inSameModule(std)) {
                    String moduleName = std.getUnit().getPackage().getModule().getNameAsString();
                    t.addError("satisfies a sealed interface in a different module: '" + std.getName(unit) + "' in '" + moduleName + "'");
                }
            }
            checkSelfTypes(t, td, type);
            checkExtensionOfMemberType(t, td, type);
        /*if (!(td instanceof TypeParameter)) {
                    checkCaseOfSupertype(t, td, type);
                }*/
        }
        if (t instanceof Tree.SimpleType) {
            Tree.SimpleType st = (Tree.SimpleType) t;
            checkSupertypeVarianceAnnotations(st);
        }
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) Type(org.eclipse.ceylon.model.typechecker.model.Type) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Unit(org.eclipse.ceylon.model.typechecker.model.Unit) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) HashSet(java.util.HashSet)

Example 54 with Unit

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

the class InheritanceVisitor method validateEnumeratedSupertypes.

private void validateEnumeratedSupertypes(Node that, ClassOrInterface d) {
    Type type = d.getType();
    Unit unit = that.getUnit();
    if (d instanceof Class) {
        Type superclass = d.getExtendedType();
        if (superclass != null && superclass.isAnything() && !type.isObject() && !type.isNull()) {
            // a class which directly extends Anything
            // must be handled as a special case here
            // because of a performance optimization in
            // Class.inherits()
            that.addError("not a subtype of any case of root type: '" + d.getName(unit) + "' directly inherits 'Anything'");
        }
    }
    for (Type supertype : type.getSupertypes()) {
        if (!type.isExactly(supertype)) {
            TypeDeclaration std = supertype.getDeclaration();
            List<Type> cts = std.getCaseTypes();
            if (cts != null && !cts.isEmpty()) {
                if (cts.size() == 1 && cts.get(0).getDeclaration().isSelfType()) {
                    continue;
                }
                List<Type> types = new ArrayList<Type>(cts.size());
                for (Type ct : cts) {
                    TypeDeclaration ctd = ct.resolveAliases().getDeclaration();
                    Type cst = type.getSupertype(ctd);
                    if (cst != null) {
                        types.add(cst);
                    }
                }
                if (types.isEmpty()) {
                    that.addError("type is not a subtype of any case of enumerated supertype: '" + d.getName(unit) + "' inherits '" + std.getName(unit) + "'");
                } else if (types.size() > 1) {
                    StringBuilder sb = new StringBuilder();
                    for (Type pt : types) {
                        sb.append("'").append(pt.asString(unit)).append("' and ");
                    }
                    sb.setLength(sb.length() - 5);
                    that.addError("type is a subtype of multiple cases of enumerated supertype '" + std.getName(unit) + "': '" + d.getName(unit) + "' inherits " + sb);
                }
            }
        }
    }
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) ArrayList(java.util.ArrayList) Class(org.eclipse.ceylon.model.typechecker.model.Class) Unit(org.eclipse.ceylon.model.typechecker.model.Unit) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 55 with Unit

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

the class InheritanceVisitor method checkSupertypeIntersection.

private void checkSupertypeIntersection(Node that, TypeDeclaration td, Type st1, Type st2) {
    TypeDeclaration st1d = st1.getDeclaration();
    TypeDeclaration st2d = st2.getDeclaration();
    if (st1d.equals(st2d)) /*&& !st1.isExactly(st2)*/
    {
        Unit unit = that.getUnit();
        if (!areConsistentSupertypes(st1, st2, unit)) {
            that.addError(typeDescription(td, unit) + " has the same parameterized supertype twice with incompatible type arguments: '" + st1.asString(unit) + " & " + st2.asString(unit) + "'");
            td.setInconsistentType(true);
        }
    }
}
Also used : Unit(org.eclipse.ceylon.model.typechecker.model.Unit) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Aggregations

Unit (org.eclipse.ceylon.model.typechecker.model.Unit)82 Type (org.eclipse.ceylon.model.typechecker.model.Type)41 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)31 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)25 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)23 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)16 AnalyzerUtil.getTypedDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration)11 ArrayList (java.util.ArrayList)10 Class (org.eclipse.ceylon.model.typechecker.model.Class)10 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)10 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)9 Function (org.eclipse.ceylon.model.typechecker.model.Function)9 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)9 ModelUtil.intersectionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType)9 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)9 Value (org.eclipse.ceylon.model.typechecker.model.Value)9 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)7 Module (org.eclipse.ceylon.model.typechecker.model.Module)7 IntersectionType (org.eclipse.ceylon.model.typechecker.model.IntersectionType)6 LazyType (org.eclipse.ceylon.model.typechecker.model.LazyType)6