Search in sources :

Example 41 with Interface

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

the class TypeVisitor method visit.

/* private boolean hasSharedConstructors(Class cd) {
        for (Declaration m: cd.getMembers()) {
            if (m instanceof Constructor &&
                    m.isShared()) {
                return true;
            }
        }
        return false;
    }*/
@Override
public void visit(Tree.InterfaceDefinition that) {
    Interface id = that.getDeclarationModel();
    id.setExtendedType(null);
    id.getSatisfiedTypes().clear();
    Class od = unit.getObjectDeclaration();
    if (od != null) {
        id.setExtendedType(od.getType());
    }
    super.visit(that);
}
Also used : Class(org.eclipse.ceylon.model.typechecker.model.Class) AnalyzerUtil.isVeryAbstractClass(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.isVeryAbstractClass) 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 42 with Interface

use of org.eclipse.ceylon.model.typechecker.model.Interface 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 43 with Interface

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

the class TypeVisitor method visit.

@Override
public void visit(Tree.InterfaceDeclaration that) {
    Interface id = that.getDeclarationModel();
    id.setExtendedType(null);
    super.visit(that);
    Tree.TypeSpecifier typeSpecifier = that.getTypeSpecifier();
    if (typeSpecifier == null) {
        if (!id.isNative()) {
            that.addError("missing interface body or aliased interface reference");
        }
    } else {
        Tree.SatisfiedTypes sts = that.getSatisfiedTypes();
        if (sts != null) {
            sts.addError("interface alias may not satisfy a type");
        }
        Tree.CaseTypes cts = that.getCaseTypes();
        if (cts != null) {
            that.addError("class alias may not have cases or a self type");
        }
        Tree.StaticType et = typeSpecifier.getType();
        if (et == null) {
        // that.addError("malformed aliased interface");
        } else if (!(et instanceof Tree.StaticType)) {
            typeSpecifier.addError("aliased type must be an interface");
        } else {
            Type type = et.getTypeModel();
            if (type != null && !type.isUnknown()) {
                TypeDeclaration dec = type.getDeclaration();
                if (dec instanceof Interface) {
                    id.setExtendedType(type);
                } else {
                    et.addError("not an interface: '" + dec.getName(unit) + "'");
                }
            }
        }
    }
}
Also used : 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) 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) 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 44 with Interface

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

the class TypeVisitor method visitSimpleType.

private void visitSimpleType(Tree.SimpleType that, Type ot, TypeDeclaration dec) {
    if (dec instanceof Constructor && // is allowed
    !inTypeLiteral && // constructor is allowed
    !inExtendsOrClassAlias && !inDelegatedConstructor) {
        that.addError("constructor is not a type: '" + dec.getName(unit) + "' is a constructor");
    }
    Tree.TypeArgumentList tal = that.getTypeArgumentList();
    if (tal != null) {
        dec = unwrapAliasedTypeConstructor(dec);
    }
    List<TypeParameter> params = dec.getTypeParameters();
    List<Type> typeArgs = getTypeArguments(tal, ot, params);
    // Note: we actually *check* these type arguments
    // later in ExpressionVisitor
    Type pt = dec.appliedType(ot, typeArgs);
    if (tal == null) {
        if (!params.isEmpty()) {
            // For now the only type constructors allowed
            // as the type of a value are type constructors
            // that alias Callable (in future relax this)
            // and interpret *every* type with a missing
            // type argument list as a type constructor
            Interface cd = unit.getCallableDeclaration();
            boolean functionTypeConstructor = dec.isAlias() ? dec.inherits(cd) : dec.equals(cd);
            if (functionTypeConstructor) {
                pt.setTypeConstructor(true);
            }
        }
    } else {
        if (params.isEmpty()) {
            that.addError("type declaration does not accept type arguments: '" + dec.getName(unit) + "' is not a generic type");
        }
        tal.setTypeModels(typeArgs);
        List<Tree.Type> args = tal.getTypes();
        for (int i = 0; i < args.size() && i < params.size(); i++) {
            Tree.Type t = args.get(i);
            if (t instanceof Tree.StaticType) {
                Tree.StaticType st = (Tree.StaticType) t;
                Tree.TypeVariance variance = st.getTypeVariance();
                if (variance != null) {
                    TypeParameter p = params.get(i);
                    String var = variance.getText();
                    if (var.equals("out")) {
                        pt.setVariance(p, OUT);
                    } else if (var.equals("in")) {
                        pt.setVariance(p, IN);
                    }
                    if (!p.isInvariant()) {
                        // Type doesn't yet know
                        // how to reason about *runtime*
                        // instantiations of variant types
                        // since they are effectively
                        // invariant
                        variance.addUnsupportedError("use-site variant instantiation of declaration-site variant types is not supported: type parameter '" + p.getName() + "' of '" + dec.getName(unit) + "' is declared " + (p.isCovariant() ? "covariant" : "contravariant") + " (remove the '" + var + "')");
                    }
                }
            }
        }
    }
    that.setTypeModel(pt);
    that.setDeclarationModel(dec);
}
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) 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) 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 45 with Interface

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

the class TypeParserTests method testSpreadCallableAbbrev.

@Test
public void testSpreadCallableAbbrev() {
    Type type = new TypeParser(MockLoader.instance).decodeType("a(*[b,a])", null, mockDefaultModule, mockPkgUnit);
    Assert.assertNotNull(type);
    TypeDeclaration declaration = type.getDeclaration();
    Assert.assertNotNull(declaration);
    Assert.assertTrue(declaration instanceof Interface);
    Assert.assertEquals("ceylon.language::Callable", declaration.getQualifiedNameString());
    Assert.assertEquals("a(b, a)", type.asString());
    Assert.assertNull(type.getQualifyingType());
}
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) TypeParser(org.eclipse.ceylon.model.loader.TypeParser) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) Test(org.junit.Test)

Aggregations

Interface (org.eclipse.ceylon.model.typechecker.model.Interface)105 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)99 Type (org.eclipse.ceylon.model.typechecker.model.Type)64 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)58 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)40 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)35 LazyInterface (org.eclipse.ceylon.model.loader.model.LazyInterface)34 Class (org.eclipse.ceylon.model.typechecker.model.Class)32 ModelUtil.getContainingClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface)32 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)32 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)29 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)27 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)21 ModelUtil.getOuterClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ModelUtil.getOuterClassOrInterface)20 UnionType (org.eclipse.ceylon.model.typechecker.model.UnionType)20 ModelUtil.intersectionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType)19 ModelUtil.unionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType)19 AnalyzerUtil.getTupleType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType)18 AnalyzerUtil.spreadType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType)18 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)18