Search in sources :

Example 96 with TypeDeclaration

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

the class TypeHierarchyVisitor method visitDAGNode.

private void visitDAGNode(TypeDeclaration declaration, List<Type> sortedDag, Set<TypeDeclaration> visited, List<TypeDeclaration> stackOfProcessedType, Node errorReporter) {
    if (declaration == null) {
        return;
    }
    if (checkCyclicInheritance(declaration, stackOfProcessedType, errorReporter)) {
        // stop the cycle here but try and process the rest
        return;
    }
    if (visited.contains(declaration)) {
        return;
    }
    visited.add(declaration);
    Type type = getOrBuildType(declaration);
    stackOfProcessedType.add(declaration);
    org.eclipse.ceylon.model.typechecker.model.Type extendedType = declaration.getExtendedType();
    if (extendedType != null) {
        visitDAGNode(extendedType.getDeclaration(), sortedDag, visited, stackOfProcessedType, errorReporter);
    }
    for (org.eclipse.ceylon.model.typechecker.model.Type superSatisfiedType : declaration.getSatisfiedTypes()) {
        if (superSatisfiedType != null) {
            visitDAGNode(superSatisfiedType.getDeclaration(), sortedDag, visited, stackOfProcessedType, errorReporter);
        }
    }
    for (org.eclipse.ceylon.model.typechecker.model.Type superSatisfiedType : declaration.getBrokenSupertypes()) {
        TypeDeclaration typeDec = superSatisfiedType.getDeclaration();
        if (!(typeDec instanceof UnionType) && !(typeDec instanceof IntersectionType)) {
            visitDAGNode(typeDec, sortedDag, visited, stackOfProcessedType, errorReporter);
        }
    }
    stackOfProcessedType.remove(stackOfProcessedType.size() - 1);
    sortedDag.add(type);
}
Also used : UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) IntersectionType(org.eclipse.ceylon.model.typechecker.model.IntersectionType) UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) IntersectionType(org.eclipse.ceylon.model.typechecker.model.IntersectionType) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 97 with TypeDeclaration

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

the class TypeHierarchyVisitor method validateMemberRefinement.

private void validateMemberRefinement(Node that, TypeDeclaration td) {
    if (!td.isInconsistentType() && td instanceof ClassOrInterface && !td.isAbstract() && !td.isAlias() && // resulting in multiple errors
    !that.hasErrors()) {
        Set<String> errors = new HashSet<String>();
        for (TypeDeclaration std : td.getSupertypeDeclarations()) {
            for (Declaration d : std.getMembers()) {
                if (d.isShared() && !d.isStatic() && !isConstructor(d) && !isOverloadedVersion(d) && isResolvable(d) && !errors.contains(d.getName())) {
                    Declaration r = td.getMember(d.getName(), null, false);
                    // to the user!
                    if (r != null && !r.refines(d) && // is a dupe declaration
                    !r.getContainer().equals(td) && !((std instanceof Interface || r.isInterfaceMember()) && isDefinedInJava(std) && isDefinedInJava(r))) {
                        TypeDeclaration ctd = (TypeDeclaration) r.getContainer();
                        that.addError("member '" + d.getName() + "' is inherited ambiguously by '" + td.getName() + "' from '" + std.getName() + "' and a different generic instantiation of '" + ctd.getName() + "' and is not refined by '" + td.getName() + "' (refine '" + d.getName() + "' to satisfy both instantiations of '" + ctd.getName() + "')", 350);
                        errors.add(d.getName());
                    }
                }
            }
        }
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) ModelUtil.getNativeDeclaration(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getNativeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 98 with TypeDeclaration

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

the class TypeVisitor method visit.

@Override
public void visit(Tree.SatisfiedTypes that) {
    super.visit(that);
    TypeDeclaration td = (TypeDeclaration) that.getScope();
    if (td.isAlias()) {
        return;
    }
    List<Tree.StaticType> types = that.getTypes();
    List<Type> list = new ArrayList<Type>(types.size());
    if (types.isEmpty()) {
        that.addError("missing types in satisfies");
    }
    boolean foundTypeParam = false;
    boolean foundClass = false;
    boolean foundInterface = false;
    for (Tree.StaticType st : types) {
        inheritedType(st);
        Type type = st.getTypeModel();
        if (type != null) {
            TypeDeclaration std = type.getDeclaration();
            if (std != null && !(std instanceof UnknownType)) {
                if (std == td) {
                // unnecessary, handled by SupertypeVisitor
                // st.addError("directly extends itself: '" +
                // td.getName() + "'");
                } else if (std instanceof NothingType) {
                    st.addError("satisfies the bottom type 'Nothing'");
                } else if (std instanceof TypeAlias) {
                    st.addError("satisfies a type alias: '" + type.getDeclaration().getName(unit) + "'");
                } else if (std instanceof Constructor) {
                // nothing to do
                } else if (td instanceof TypeParameter) {
                    if (foundTypeParam) {
                        st.addUnsupportedError("type parameter upper bounds are not yet supported in combination with other bounds");
                    } else if (std instanceof TypeParameter) {
                        if (foundClass || foundInterface) {
                            st.addUnsupportedError("type parameter upper bounds are not yet supported in combination with other bounds");
                        }
                        foundTypeParam = true;
                        list.add(type);
                    } else if (std instanceof Class) {
                        if (foundClass) {
                            st.addUnsupportedError("multiple class upper bounds are not yet supported");
                        }
                        foundClass = true;
                        list.add(type);
                    } else if (std instanceof Interface) {
                        foundInterface = true;
                        list.add(type);
                    } else {
                        st.addError("upper bound must be a class, interface, or type parameter");
                    }
                } else {
                    if (std instanceof TypeParameter) {
                        st.addError("directly satisfies type parameter: '" + std.getName(unit) + "'");
                    } else if (std instanceof Class) {
                        st.addError("satisfies a class: '" + std.getName(unit) + "'");
                    } else if (std instanceof Interface) {
                        if (td.isDynamic() && !std.isDynamic()) {
                            st.addError("dynamic interface satisfies a non-dynamic interface: '" + std.getName(unit) + "'");
                        } else {
                            list.add(type);
                        }
                    } else {
                        st.addError("satisfied type must be an interface");
                    }
                }
            }
        }
    }
    td.setSatisfiedTypes(list);
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) AnalyzerUtil.setTypeConstructor(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.setTypeConstructor) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) AnalyzerUtil.unwrapAliasedTypeConstructor(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.unwrapAliasedTypeConstructor) ArrayList(java.util.ArrayList) TypeAlias(org.eclipse.ceylon.model.typechecker.model.TypeAlias) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) NothingType(org.eclipse.ceylon.model.typechecker.model.NothingType) 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) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Class(org.eclipse.ceylon.model.typechecker.model.Class) AnalyzerUtil.isVeryAbstractClass(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.isVeryAbstractClass) 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) NothingType(org.eclipse.ceylon.model.typechecker.model.NothingType) ModelUtil.getContainingClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)

Example 99 with TypeDeclaration

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

the class TypeVisitor method checkExtendedTypeExpression.

void checkExtendedTypeExpression(Tree.Type type) {
    if (type instanceof Tree.QualifiedType) {
        Tree.QualifiedType qualifiedType = (Tree.QualifiedType) type;
        Tree.StaticType outerType = qualifiedType.getOuterType();
        if (!(outerType instanceof Tree.SuperType)) {
            TypeDeclaration otd = qualifiedType.getDeclarationModel();
            if (otd != null) {
                if (otd.isStatic() || otd instanceof Constructor) {
                    checkExtendedTypeExpression(outerType);
                } else {
                    outerType.addError("illegal qualifier in constructor delegation (must be super)");
                }
            }
        }
    }
}
Also used : AnalyzerUtil.setTypeConstructor(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.setTypeConstructor) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) AnalyzerUtil.unwrapAliasedTypeConstructor(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.unwrapAliasedTypeConstructor) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) 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)

Example 100 with TypeDeclaration

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

the class TypeVisitor method visit.

/*@Override 
    public void visit(Tree.TypeConstraint that) {
        super.visit(that);
        if (that.getSelfType()!=null) {
            TypeDeclaration td = (TypeDeclaration) that.getSelfType().getScope();
            TypeParameter tp = that.getDeclarationModel();
            td.setSelfType(tp.getType());
            if (tp.isSelfType()) {
                that.addError("type parameter may not act as self type for two different types");
            }
            else {
                tp.setSelfTypedDeclaration(td);
            }
        }
    }*/
@Override
public void visit(Tree.CaseTypes that) {
    super.visit(that);
    TypeDeclaration td = (TypeDeclaration) that.getScope();
    List<Tree.StaticMemberOrTypeExpression> bmes = that.getBaseMemberExpressions();
    List<Tree.StaticType> cts = that.getTypes();
    List<TypedDeclaration> caseValues = new ArrayList<TypedDeclaration>(bmes.size());
    List<Type> caseTypes = new ArrayList<Type>(bmes.size() + cts.size());
    if (td instanceof TypeParameter) {
        if (!bmes.isEmpty()) {
            that.addError("cases of type parameter must be a types");
        }
    } else {
        for (Tree.StaticMemberOrTypeExpression bme : bmes) {
            // bmes have not yet been resolved
            String name = name(bme.getIdentifier());
            TypedDeclaration od = bme instanceof Tree.BaseMemberExpression ? getTypedDeclaration(bme.getScope(), name, null, false, unit) : getPackageTypedDeclaration(name, null, false, unit);
            if (od != null) {
                caseValues.add(od);
                Type type = od.getType();
                if (type != null) {
                    caseTypes.add(type);
                }
            }
        }
    }
    for (Tree.StaticType ct : cts) {
        inheritedType(ct);
        Type type = ct.getTypeModel();
        if (!isTypeUnknown(type)) {
            if (type.isUnion() || type.isIntersection() || type.isNothing()) {
                // union/intersection types don't have equals()
                if (td instanceof TypeParameter) {
                    ct.addError("enumerated bound must be a class or interface type");
                } else {
                    ct.addError("case type must be a class, interface, or self type");
                }
            } else {
                TypeDeclaration ctd = type.getDeclaration();
                if (ctd.equals(td)) {
                    ct.addError("directly enumerates itself: '" + td.getName() + "'");
                } else if (type.isClassOrInterface()) {
                    caseTypes.add(type);
                } else if (type.isTypeParameter()) {
                    if (td instanceof TypeParameter) {
                        caseTypes.add(type);
                    } else {
                        TypeParameter tp = (TypeParameter) ctd;
                        td.setSelfType(type);
                        if (tp.isSelfType()) {
                            ct.addError("type parameter may not act as self type for two different types");
                        } else {
                            tp.setSelfTypedDeclaration(td);
                            caseTypes.add(type);
                        }
                        if (cts.size() > 1) {
                            ct.addError("a type may not have more than one self type");
                        }
                    }
                } else {
                    if (td instanceof TypeParameter) {
                        ct.addError("enumerated bound must be a class or interface type");
                    } else {
                        ct.addError("case type must be a class, interface, or self type");
                    }
                }
            }
        }
    }
    if (!caseTypes.isEmpty()) {
        TypeDeclaration first = caseTypes.get(0).getDeclaration();
        if (caseTypes.size() == 1 && first.isSelfType()) {
            // for a type family, the type that declares
            // the type parameter may not be the same
            // type for which it acts as a self type
            Scope scope = first.getContainer();
            if (scope instanceof ClassOrInterface) {
                ClassOrInterface ci = (ClassOrInterface) scope;
                if (!ci.isAbstract()) {
                    Tree.StaticType ct = cts.get(0);
                    if (ci.equals(td)) {
                        ct.addError("concrete class parameterized by self type: '" + ci.getName() + "' is not abstract but has the self type '" + first.getName() + "' (make '" + ci.getName() + "' abstract)", 905);
                    } else {
                        // type family
                        ct.addError("concrete class parameterized by self type: '" + ci.getName() + "' is not abstract but declares the self type '" + first.getName() + "' of '" + td.getName() + "' (make '" + ci.getName() + "' abstract)", 905);
                    }
                }
            }
        } else {
            if (td instanceof ClassOrInterface) {
                ClassOrInterface ci = (ClassOrInterface) td;
                if (!ci.isAbstract()) {
                    Class c = (Class) ci;
                    if (!c.hasEnumerated()) {
                        that.addError("concrete class has enumerated subtypes: " + "enumerated class '" + ci.getName() + "' is not abstract" + " (make '" + ci.getName() + "' abstract)", 905);
                    }
                }
            }
        }
        td.setCaseTypes(caseTypes);
        td.setCaseValues(caseValues);
    }
}
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) ModelUtil.getContainingClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) ArrayList(java.util.ArrayList) NothingType(org.eclipse.ceylon.model.typechecker.model.NothingType) 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) 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.isVeryAbstractClass(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.isVeryAbstractClass) 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

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