Search in sources :

Example 61 with ClassOrInterface

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

the class TypeVisitor method visit.

public void visit(Tree.SuperType that) {
    // if (inExtendsClause) { //can't appear anywhere else in the tree!
    Scope scope = that.getScope();
    ClassOrInterface ci = getContainingClassOrInterface(scope);
    if (ci != null) {
        if (scope instanceof Constructor) {
            that.setTypeModel(intersectionOfSupertypes(ci));
        } else if (ci.isClassOrInterfaceMember()) {
            ClassOrInterface oci = (ClassOrInterface) ci.getContainer();
            that.setTypeModel(intersectionOfSupertypes(oci));
        } else {
            that.addError("super appears in extends for non-member class");
        }
    }
// }
}
Also used : ModelUtil.getContainingClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) 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)

Example 62 with ClassOrInterface

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

the class AnalyzerUtil method notAssignableMessage.

static String notAssignableMessage(Type type, Type supertype, Node node) {
    Unit unit = node.getUnit();
    if (supertype.covers(type)) {
        return ": the assigned type '" + type.asString(unit) + "' is covered by, but not assignable to, the type '" + supertype.asString(unit) + "' (explicitly narrow assigned expression using 'of " + supertype.asString(unit) + "')";
    }
    String result = typingMessage(type, " is not assignable to ", supertype, unit);
    if (unit.getDefiniteType(type).isSubtypeOf(supertype)) {
        return result + " (the assigned type contains 'null')";
    } else if (unit.isCallableType(type) && unit.getCallableReturnType(type).isSubtypeOf(supertype)) {
        return result + " (specify arguments to the function reference)";
    } else {
        TypeDeclaration typeDec = type.getDeclaration();
        TypeDeclaration supertypeDec = supertype.getDeclaration();
        if (typeDec instanceof ClassOrInterface && supertypeDec instanceof ClassOrInterface && typeDec.isToplevel() && supertypeDec.isToplevel()) {
            String typeName = typeDec.getName();
            String supertypeName = supertypeDec.getName();
            if (typeName.equals(supertypeName)) {
                String typePackage = typeDec.getUnit().getPackage().getNameAsString();
                String supertypePackage = supertypeDec.getUnit().getPackage().getNameAsString();
                if (typePackage.startsWith("ceylon.") && supertypePackage.startsWith("java.")) {
                    return result + " (Java '" + supertypeName + "' is not the same type as Ceylon '" + typeName + "')";
                }
                if (typePackage.startsWith("java.") && supertypePackage.startsWith("ceylon.")) {
                    return result + " (Ceylon '" + supertypeName + "' is not the same type as Java '" + typeName + "')";
                }
            }
        }
        return result;
    }
}
Also used : ModelUtil.getContainingClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) Unit(org.eclipse.ceylon.model.typechecker.model.Unit) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 63 with ClassOrInterface

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

the class ExpressionVisitor method visit.

@Override
public void visit(Tree.TypeLiteral that) {
    if (that instanceof Tree.InterfaceLiteral || that instanceof Tree.ClassLiteral || that instanceof Tree.NewLiteral || that instanceof Tree.AliasLiteral || that instanceof Tree.TypeParameterLiteral) {
        declarationLiteral = true;
    } else {
        modelLiteral = true;
    }
    try {
        super.visit(that);
    } finally {
        declarationLiteral = false;
        modelLiteral = false;
    }
    Type t;
    TypeDeclaration d;
    Tree.StaticType type = that.getType();
    Node errorNode;
    if (type != null) {
        t = type.getTypeModel();
        d = t.getDeclaration();
        errorNode = type;
    } else {
        errorNode = that;
        ClassOrInterface classOrInterface = getContainingClassOrInterface(that.getScope());
        if (that instanceof Tree.ClassLiteral || that instanceof Tree.InterfaceLiteral) {
            d = classOrInterface;
            if (d == null) {
                errorNode.addError("no containing type");
                // EARLY EXIT!!
                return;
            } else {
                t = classOrInterface.getType();
            }
        } else {
            errorNode.addError("missing type reference");
            // EARLY EXIT!!
            return;
        }
    }
    if (t != null) {
        that.setDeclaration(d);
        that.setWantsDeclaration(true);
        if (that instanceof Tree.ClassLiteral) {
            if (!(d instanceof Class)) {
                if (d != null) {
                    errorNode.addError("referenced declaration is not a class" + getDeclarationReferenceSuggestion(d));
                }
                that.setTypeModel(unit.getClassDeclarationType());
            } else {
                that.setTypeModel(unit.getClassDeclarationType((Class) d));
            }
        } else if (that instanceof Tree.NewLiteral) {
            if (d instanceof Class) {
                Class c = (Class) d;
                Constructor defaultConstructor = c.getDefaultConstructor();
                if (defaultConstructor != null) {
                    d = defaultConstructor;
                }
            }
            if (d instanceof Constructor) {
                Constructor c = (Constructor) d;
                if (c.getParameterList() == null) {
                    that.setTypeModel(unit.getValueConstructorDeclarationType());
                } else {
                    that.setTypeModel(unit.getCallableConstructorDeclarationType());
                }
            } else if (d != null) {
                errorNode.addError("referenced declaration is not a constructor" + getDeclarationReferenceSuggestion(d));
            }
        } else if (that instanceof Tree.InterfaceLiteral) {
            if (!(d instanceof Interface)) {
                if (d != null) {
                    errorNode.addError("referenced declaration is not an interface" + getDeclarationReferenceSuggestion(d));
                }
            }
            that.setTypeModel(unit.getInterfaceDeclarationType());
        } else if (that instanceof Tree.AliasLiteral) {
            if (!(d instanceof TypeAlias)) {
                errorNode.addError("referenced declaration is not a type alias" + getDeclarationReferenceSuggestion(d));
            }
            that.setTypeModel(unit.getAliasDeclarationType());
        } else if (that instanceof Tree.TypeParameterLiteral) {
            if (!(d instanceof TypeParameter)) {
                errorNode.addError("referenced declaration is not a type parameter" + getDeclarationReferenceSuggestion(d));
            }
            that.setTypeModel(unit.getTypeParameterDeclarationType());
        } else if (d != null) {
            that.setWantsDeclaration(false);
            t = t.resolveAliases();
            if (t == null || t.isUnknown()) {
                return;
            }
            // checkNonlocalType(that.getType(), t.getDeclaration());
            if (d instanceof Constructor) {
                if (((Constructor) d).isAbstraction()) {
                    errorNode.addError("constructor is overloaded");
                } else {
                    that.setTypeModel(unit.getConstructorMetatype(t));
                }
            } else if (d instanceof Class) {
                // checkNonlocal(that, t.getDeclaration());
                that.setTypeModel(unit.getClassMetatype(t));
            } else if (d instanceof Interface) {
                that.setTypeModel(unit.getInterfaceMetatype(t));
            } else {
                that.setTypeModel(unit.getTypeMetaType(t));
            }
        }
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) ModelUtil.getOuterClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getOuterClassOrInterface) ModelUtil.getContainingClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) AnalyzerUtil.unwrapAliasedTypeConstructor(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.unwrapAliasedTypeConstructor) ModelUtil.isConstructor(org.eclipse.ceylon.model.typechecker.model.ModelUtil.isConstructor) Node(org.eclipse.ceylon.compiler.typechecker.tree.Node) TypeAlias(org.eclipse.ceylon.model.typechecker.model.TypeAlias) 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) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) ModelUtil.findMatchingOverloadedClass(org.eclipse.ceylon.model.typechecker.model.ModelUtil.findMatchingOverloadedClass) Class(org.eclipse.ceylon.model.typechecker.model.Class) 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) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) ModelUtil.getOuterClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getOuterClassOrInterface) ModelUtil.getContainingClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface)

Example 64 with ClassOrInterface

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

the class ExpressionVisitor method checkSuperInvocation.

private void checkSuperInvocation(Tree.MemberOrTypeExpression qmte, List<Type> signature, boolean spread) {
    Declaration member = qmte.getDeclaration();
    if (member != null) {
        String name = member.getName();
        TypeDeclaration type = (TypeDeclaration) member.getContainer();
        if (member.isFormal() && !inExtendsClause) {
            qmte.addError("supertype member is declared formal: '" + name + "' of '" + type.getName() + "'");
        } else {
            Scope scope = qmte.getScope();
            ClassOrInterface ci = getContainingClassOrInterface(scope);
            if (ci != null) {
                List<TypeDeclaration> refiners = new ArrayList<TypeDeclaration>(1);
                Type et = ci.getExtendedType();
                if (et != null) {
                    Declaration etm = et.getDeclaration().getMember(name, signature, spread);
                    if (etm != null && !etm.getContainer().equals(type) && etm.refines(member)) {
                        TypeDeclaration container = (TypeDeclaration) etm.getContainer();
                        refiners.add(container);
                    }
                }
                for (Type st : ci.getSatisfiedTypes()) {
                    Declaration stm = st.getDeclaration().getMember(name, signature, spread);
                    if (stm != null && !stm.getContainer().equals(type) && stm.refines(member)) {
                        TypeDeclaration container = (TypeDeclaration) stm.getContainer();
                        refiners.add(container);
                    }
                }
                if (refiners.size() == 1) {
                    TypeDeclaration r = refiners.get(0);
                    if (r instanceof Class) {
                        qmte.addError("inherited member is refined by intervening superclass: '" + r.getName() + "' refines '" + name + "' declared by '" + type.getName() + "'");
                    } else {
                        qmte.addError("inherited member is refined by intervening superinterface: '" + r.getName() + "' refines '" + name + "' declared by '" + type.getName() + "'");
                    }
                } else if (!refiners.isEmpty()) {
                    StringBuilder sb = new StringBuilder();
                    for (TypeDeclaration r : refiners) {
                        if (sb.length() > 0) {
                            sb.append(", ");
                        }
                        sb.append('\'').append(r.getName()).append('\'');
                    }
                    qmte.addError("inherited member is refined by intervening supertypes: '" + name + "' declared by '" + type.getName() + "' is refined by intervening types " + sb);
                }
            }
        }
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) ModelUtil.getOuterClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getOuterClassOrInterface) ModelUtil.getContainingClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface) 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) NativeUtil.declarationScope(org.eclipse.ceylon.compiler.typechecker.util.NativeUtil.declarationScope) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) ArrayList(java.util.ArrayList) ModelUtil.findMatchingOverloadedClass(org.eclipse.ceylon.model.typechecker.model.ModelUtil.findMatchingOverloadedClass) Class(org.eclipse.ceylon.model.typechecker.model.Class) AnalyzerUtil.getPackageTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) AnalyzerUtil.getPackageTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) ModelUtil.getNativeDeclaration(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getNativeDeclaration) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration) 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 65 with ClassOrInterface

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

the class TypeUtils method resolveTypeParameter.

/**
 * Finds the owner of the type parameter and outputs a reference to the corresponding type argument.
 */
static void resolveTypeParameter(final Node node, final TypeParameter tp, final GenerateJsVisitor gen, final boolean skipSelfDecl) {
    Scope parent = ModelUtil.getRealScope(node.getScope());
    int outers = 0;
    while (parent != null && parent != tp.getContainer()) {
        if (parent instanceof TypeDeclaration && !(parent instanceof Constructor || ((TypeDeclaration) parent).isAnonymous())) {
            outers++;
        }
        parent = parent.getScope();
    }
    if (tp.getContainer() instanceof ClassOrInterface) {
        if (parent == tp.getContainer()) {
            if (!skipSelfDecl) {
                TypeDeclaration ontoy = ModelUtil.getContainingClassOrInterface(node.getScope());
                while (ontoy.isAnonymous()) ontoy = ModelUtil.getContainingClassOrInterface(ontoy.getScope());
                gen.out(gen.getNames().self(ontoy));
                if (ontoy == parent)
                    outers--;
                for (int i = 0; i < outers; i++) {
                    gen.out(".outer$");
                }
                gen.out(".");
            }
            gen.out("$$targs$$.", gen.getNames().typeParameterName(tp));
        } else {
            // This can happen in expressions such as Singleton(n) when n is dynamic
            gen.out("{/*NO PARENT*/t:", gen.getClAlias(), "Anything}");
        }
    } else if (tp.getContainer() instanceof TypeAlias) {
        if (parent == tp.getContainer()) {
            gen.out("'", gen.getNames().typeParameterName(tp), "'");
        } else {
            // This can happen in expressions such as Singleton(n) when n is dynamic
            gen.out("{/*NO PARENT ALIAS*/t:", gen.getClAlias(), "Anything}");
        }
    } else {
        // it has to be a method, right?
        // We need to find the index of the parameter where the argument occurs
        // ...and it could be null...
        Type type = null;
        for (Iterator<ParameterList> iter0 = ((Function) tp.getContainer()).getParameterLists().iterator(); type == null && iter0.hasNext(); ) {
            for (Iterator<Parameter> iter1 = iter0.next().getParameters().iterator(); iter1.hasNext(); ) {
                type = typeContainsTypeParameter(iter1.next().getType(), tp);
            }
        }
        // A type argument of the argument's type, in which case we must get the reified generic from the argument
        if (tp.getContainer() == parent) {
            gen.out(gen.getNames().typeArgsParamName((Function) tp.getContainer()), ".", gen.getNames().typeParameterName(tp));
        } else {
            if (parent == null && node instanceof Tree.StaticMemberOrTypeExpression) {
                if (tp.getContainer() == ((Tree.StaticMemberOrTypeExpression) node).getDeclaration()) {
                    type = ((Tree.StaticMemberOrTypeExpression) node).getTarget().getTypeArguments().get(tp);
                    typeNameOrList(node, type, gen, skipSelfDecl);
                    return;
                }
            }
            gen.out("'", gen.getNames().typeParameterName(tp), "'");
        // gen.out.spitOut("Passing reference to " + tp.getQualifiedNameString() + " as a string...");
        // gen.out("/*Please report this to the ceylon-js team: METHOD TYPEPARM plist ",
        // Integer.toString(plistCount), "#", tp.getName(), "*/'", type.getProducedTypeQualifiedName(),
        // "' container " + tp.getContainer() + " at " + node);
        }
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) Function(org.eclipse.ceylon.model.typechecker.model.Function) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) NothingType(org.eclipse.ceylon.model.typechecker.model.NothingType) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Iterator(java.util.Iterator) TypeAlias(org.eclipse.ceylon.model.typechecker.model.TypeAlias) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Aggregations

ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)102 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)62 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)48 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)46 Type (org.eclipse.ceylon.model.typechecker.model.Type)44 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)27 Class (org.eclipse.ceylon.model.typechecker.model.Class)24 Interface (org.eclipse.ceylon.model.typechecker.model.Interface)23 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)23 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)20 ModelUtil.getContainingClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface)19 Value (org.eclipse.ceylon.model.typechecker.model.Value)19 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)18 ArrayList (java.util.ArrayList)17 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)17 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)16 Function (org.eclipse.ceylon.model.typechecker.model.Function)14 LazyInterface (org.eclipse.ceylon.model.loader.model.LazyInterface)13 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)12 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)12