Search in sources :

Example 86 with TypeDeclaration

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

the class InheritanceVisitor method checkExtensionOfMemberType.

private void checkExtensionOfMemberType(Node that, TypeDeclaration td, Type type) {
    Type qt = type.getQualifyingType();
    if (qt != null && td instanceof ClassOrInterface) {
        Unit unit = that.getUnit();
        TypeDeclaration d = type.getDeclaration();
        if (d.isStatic() || d instanceof Constructor) {
            checkExtensionOfMemberType(that, td, qt);
        } else {
            Scope s = td;
            while (s != null) {
                s = s.getContainer();
                if (s instanceof TypeDeclaration) {
                    TypeDeclaration otd = (TypeDeclaration) s;
                    if (otd.getType().isSubtypeOf(qt)) {
                        return;
                    }
                }
            }
            that.addError("qualifying type '" + qt.asString(unit) + "' of supertype '" + type.asString(unit) + "' is not an outer type or supertype of any outer type of '" + td.getName(unit) + "'");
        }
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) Type(org.eclipse.ceylon.model.typechecker.model.Type) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Unit(org.eclipse.ceylon.model.typechecker.model.Unit) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 87 with TypeDeclaration

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

the class InheritanceVisitor method collectCaseValues.

void collectCaseValues(Tree.CaseTypes that, TypeDeclaration td) {
    Unit unit = that.getUnit();
    Set<Declaration> valueSet = new HashSet<Declaration>();
    for (Tree.StaticMemberOrTypeExpression bme : that.getBaseMemberExpressions()) {
        String name = name(bme.getIdentifier());
        TypedDeclaration value = bme instanceof Tree.BaseMemberExpression ? getTypedDeclaration(bme.getScope(), name, null, false, unit) : getPackageTypedDeclaration(name, null, false, unit);
        if (value != null) {
            if (value != null && !valueSet.add(value)) {
                // this error is not really truly necessary
                bme.addError("duplicate case: '" + value.getName(unit) + "' of '" + td.getName() + "'");
            }
            Type type = value.getType();
            if (type != null) {
                TypeDeclaration caseDec = type.getDeclaration();
                if (caseDec instanceof Constructor) {
                    Scope scope = caseDec.getContainer();
                    if (scope instanceof Class) {
                        // enumerated singleton constructors
                        Constructor cons = (Constructor) caseDec;
                        Class c = (Class) scope;
                        if (!c.isToplevel() && !c.isStatic()) {
                            bme.addError("case must be a value constructor of a toplevel or static class: '" + c.getName(unit) + "' is not toplevel");
                        } else if (!cons.getParameterLists().isEmpty()) {
                            bme.addError("case must be a value constructor of a toplevel or static class: '" + cons.getName(unit) + "' is not a value constructor");
                        }
                    /*else if (!c.inherits(unit.getIdentifiableDeclaration())) {
                                bme.addError("case must be a value constructor of an identifiable class: '" + 
                                        c.getName(unit) + 
                                        "' is not a subtype of 'Identifiable'");
                            }*/
                    }
                } else {
                    // enumerated anonymous subclasses
                    if (!caseDec.isObjectClass()) {
                        bme.addError("case must be a toplevel or static anonymous class: '" + value.getName(unit) + "' is not an anonymous class");
                    } else if (!value.isToplevel() && !value.isStatic()) {
                        bme.addError("case must be a toplevel or static anonymous class: '" + value.getName(unit) + "' is neither static nor toplevel");
                    }
                }
                if (checkDirectSubtype(td, bme, type)) {
                    checkAssignable(type, td.getType(), bme, getCaseTypeExplanation(td, type));
                }
            }
        }
    }
}
Also used : AnalyzerUtil.getPackageTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Unit(org.eclipse.ceylon.model.typechecker.model.Unit) Type(org.eclipse.ceylon.model.typechecker.model.Type) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Class(org.eclipse.ceylon.model.typechecker.model.Class) AnalyzerUtil.getPackageTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) HashSet(java.util.HashSet)

Example 88 with TypeDeclaration

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

the class InheritanceVisitor method checkCaseType.

void checkCaseType(TypeDeclaration type, Tree.StaticType ct, TypeDeclaration caseTypeDec) {
    if (caseTypeDec instanceof ClassOrInterface && ct instanceof Tree.SimpleType && caseTypeDec.isParameterized()) {
        Tree.SimpleType t = (Tree.SimpleType) ct;
        Tree.TypeArgumentList tal = t.getTypeArgumentList();
        List<Tree.Type> args = tal == null ? Collections.<Tree.Type>emptyList() : tal.getTypes();
        List<TypeParameter> typeParameters = caseTypeDec.getTypeParameters();
        Set<TypeParameter> used = new HashSet<TypeParameter>();
        for (int i = 0; i < typeParameters.size(); i++) {
            TypeParameter typeParameter = typeParameters.get(i);
            Type argType;
            Node node;
            String typeArg;
            if (i < args.size()) {
                Tree.Type arg = args.get(i);
                argType = arg.getTypeModel();
                node = arg;
                typeArg = "type argument";
            } else {
                argType = typeParameter.getDefaultTypeArgument();
                node = tal;
                typeArg = "default type argument '" + argType.asString(node.getUnit()) + "' of '" + typeParameter.getName() + "' ";
            }
            if (argType != null) {
                TypeDeclaration argTypeDec = argType.getDeclaration();
                if (argType.isTypeParameter()) {
                    TypeParameter tp = (TypeParameter) argTypeDec;
                    if (!tp.getDeclaration().equals(type)) {
                        node.addError(typeArg + "is not a type parameter of the enumerated type: '" + tp.getName() + "' is not a type parameter of '" + type.getName() + "'");
                    } else if (!used.add(tp)) {
                        node.addError("type parameter of the enumerated type is used twice as a type argument: '" + argTypeDec.getName());
                    }
                } else if (typeParameter.isCovariant()) {
                    checkAssignable(typeParameter.getType(), argType, node, typeArg + " is not an upper bound of the type parameter '" + typeParameter.getName() + "' ");
                } else if (typeParameter.isContravariant()) {
                    checkAssignable(argType, typeParameter.getType(), node, typeArg + " is not a lower bound of the type parameter '" + typeParameter.getName() + "' ");
                } else {
                    node.addError(typeArg + "is not a type parameter of the enumerated type: '" + argTypeDec.getName() + "'");
                }
            }
        }
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Node(org.eclipse.ceylon.compiler.typechecker.tree.Node) AnalyzerUtil.checkCasesDisjoint(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.checkCasesDisjoint) Type(org.eclipse.ceylon.model.typechecker.model.Type) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) HashSet(java.util.HashSet)

Example 89 with TypeDeclaration

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

the class InheritanceVisitor method checkSelfTypes.

private void checkSelfTypes(Tree.StaticType that, TypeDeclaration td, Type type) {
    if (!(td instanceof TypeParameter)) {
        // TODO: is this really ok?!
        List<TypeParameter> params = type.getDeclaration().getTypeParameters();
        List<Type> args = type.getTypeArgumentList();
        Unit unit = that.getUnit();
        for (int i = 0; i < params.size(); i++) {
            TypeParameter param = params.get(i);
            if (param.isSelfType() && !args.isEmpty()) {
                Type arg = args.get(i);
                if (arg == null) {
                    arg = unit.getUnknownType();
                }
                TypeDeclaration std = param.getSelfTypedDeclaration();
                Type at;
                TypeDeclaration mtd;
                if (param.getContainer().equals(std)) {
                    at = td.getType();
                    mtd = td;
                } else {
                    // TODO: lots wrong here?
                    mtd = (TypeDeclaration) td.getMember(std.getName(), null, false);
                    at = mtd == null ? null : mtd.getType();
                }
                if (at != null && !at.isSubtypeOf(arg)) {
                    Type st = mtd.getSelfType();
                    if (st == null || !st.isExactly(arg)) {
                        String help = "";
                        TypeDeclaration atd = at.getDeclaration();
                        TypeDeclaration ad = arg.getDeclaration();
                        if (ad instanceof TypeParameter) {
                            TypeParameter tp = (TypeParameter) ad;
                            if (tp.getDeclaration().equals(td)) {
                                help = " (try making '" + ad.getName() + "' a self type of '" + td.getName() + "')";
                            }
                        } else if (ad instanceof Interface) {
                            help = " (try making " + message(atd) + " satisfy '" + ad.getName() + "')";
                        } else if (ad instanceof Class && td instanceof Class) {
                            help = " (try making " + message(atd) + " extend '" + ad.getName() + "')";
                        }
                        that.addError("type argument does not satisfy self type constraint on type parameter '" + param.getName() + "' of '" + type.getDeclaration().getName(unit) + "': '" + arg.asString(unit) + "' is not a supertype or self type of " + message(atd) + help);
                    }
                }
            }
        }
    }
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Type(org.eclipse.ceylon.model.typechecker.model.Type) Class(org.eclipse.ceylon.model.typechecker.model.Class) Unit(org.eclipse.ceylon.model.typechecker.model.Unit) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) AnalyzerUtil.checkCasesDisjoint(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.checkCasesDisjoint) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)

Example 90 with TypeDeclaration

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

the class InheritanceVisitor method checkDirectSubtype.

private static boolean checkDirectSubtype(TypeDeclaration td, Node node, Type type) {
    boolean found = false;
    TypeDeclaration ctd = type.getDeclaration();
    if (td instanceof Interface) {
        for (Type st : ctd.getSatisfiedTypes()) {
            if (st != null && st.resolveAliases().getDeclaration().equals(td)) {
                found = true;
            }
        }
    } else if (td instanceof Class) {
        Type et = ctd.getExtendedType();
        if (et != null && et.resolveAliases().getDeclaration().equals(td)) {
            found = true;
        }
    }
    if (!found) {
        node.addError("case type is not a direct subtype of enumerated type: " + ctd.getName(node.getUnit()));
    }
    return found;
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)

Aggregations

TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)303 Type (org.eclipse.ceylon.model.typechecker.model.Type)180 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)88 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)86 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)80 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)70 Class (org.eclipse.ceylon.model.typechecker.model.Class)68 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)65 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)57 UnionType (org.eclipse.ceylon.model.typechecker.model.UnionType)57 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)55 IntersectionType (org.eclipse.ceylon.model.typechecker.model.IntersectionType)51 Test (org.junit.Test)51 AnalyzerUtil.getPackageTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration)49 AnalyzerUtil.getTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)49 ArrayList (java.util.ArrayList)48 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)44 Interface (org.eclipse.ceylon.model.typechecker.model.Interface)43 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)39 ModelUtil.intersectionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType)34