Search in sources :

Example 61 with Class

use of org.eclipse.ceylon.model.typechecker.model.Class 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)

Example 62 with Class

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

the class TypeVisitor method visit.

@Override
public void visit(Tree.TypeParameterDeclaration that) {
    TypeParameter p = that.getDeclarationModel();
    p.setExtendedType(null);
    p.getSatisfiedTypes().clear();
    Class vd = unit.getAnythingDeclaration();
    if (vd != null) {
        p.setExtendedType(vd.getType());
    }
    super.visit(that);
    Tree.TypeSpecifier ts = that.getTypeSpecifier();
    if (ts != null) {
        Tree.StaticType type = ts.getType();
        if (type != null) {
            Type dta = type.getTypeModel();
            Declaration dec = p.getDeclaration();
            if (dta != null && dta.involvesDeclaration(dec)) {
                type.addError("default type argument involves parameterized type: '" + dta.asString(unit) + "' involves '" + dec.getName(unit) + "'");
                dta = null;
            }
            /*else if (dta.containsTypeParameters()) {
                    type.addError("default type argument involves type parameters: " + 
                            dta.asString(unit));
                    dta = null;
                }*/
            p.setDefaultTypeArgument(dta);
        }
    }
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) 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.getPackageTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration) 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) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) ModelUtil.getNativeDeclaration(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getNativeDeclaration) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 63 with Class

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

the class TypeVisitor method visit.

@Override
public void visit(Tree.ClassDefinition that) {
    Class cd = that.getDeclarationModel();
    if (!isVeryAbstractClass(that, unit)) {
        cd.setExtendedType(unit.getBasicType());
    } else {
        cd.setExtendedType(null);
    }
    cd.getSatisfiedTypes().clear();
    super.visit(that);
    Tree.ParameterList pl = that.getParameterList();
    if (pl != null) {
        if (cd.hasConstructors()) {
            pl.addError("class with parameters may not declare constructors: class '" + cd.getName() + "' has a parameter list and a constructor", 1002);
        } else if (cd.hasEnumerated()) {
            pl.addError("class with parameters may not declare constructors: class '" + cd.getName() + "' has a parameter list and a value constructor", 1003);
        } else if (cd.hasStaticMembers()) {
            pl.addError("class with parameters may not declare static members: class '" + cd.getName() + "' has a parameter list and a static member", 1003);
        }
    } else {
        if (!cd.hasConstructors() && !cd.hasEnumerated()) {
            // No parameter list and no constructors or enumerated
            // normally means something is wrong
            boolean error = true;
            // Check if the declaration is a native implementation
            if (cd.isNativeImplementation()) {
                Declaration hdr = getNativeHeader(cd);
                // Check that it has a native header
                if (hdr instanceof Class) {
                    Class hcd = (Class) hdr;
                    // constructors or enumerated
                    if (hcd.hasConstructors() || hcd.hasEnumerated()) {
                        // In that case there's no error
                        error = false;
                    }
                }
            }
            if (error) {
                that.addError("class must have a parameter list or at least one constructor: class '" + cd.getName() + "' has neither parameter list nor constructor", 1001);
            }
        }
    /*else {
                // Check if the class has at least one shared constructor
                boolean found = hasSharedConstructors(cd);
                // If not found check if the declaration is a native implementation
                if (!found && 
                        cd.isNative() && 
                        !cd.isNativeHeader()) {
                    Declaration hdr = getNativeHeader(cd);
                    // And check that it has a native header
                    if (hdr instanceof Class) {
                        Class hcd = (Class) hdr;
                        // In that case we try again with the header
                        found = hasSharedConstructors(hcd);
                    }
                }
                if (!found) {
                    that.addError("class with constructors must declare at least one shared constructor: class '" + 
                            cd.getName() + 
                            "' has no shared constructor");
                }
            }*/
    }
}
Also used : 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.getPackageTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration) 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) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) ModelUtil.getNativeDeclaration(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getNativeDeclaration) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 64 with Class

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

the class ExpressionVisitor method visitDirectInvocation.

/**
 * Typecheck a direct invocation.
 */
private void visitDirectInvocation(Tree.InvocationExpression that) {
    Tree.Term primary = unwrapExpressionUntilTerm(that.getPrimary());
    if (primary == null) {
        return;
    }
    Tree.MemberOrTypeExpression mte = (Tree.MemberOrTypeExpression) primary;
    Reference prf = mte.getTarget();
    Declaration dec = mte.getDeclaration();
    Functional fun = (Functional) dec;
    if (dec != null) {
        if (!(primary instanceof Tree.ExtendedTypeExpression)) {
            if (dec instanceof Class) {
                Class c = (Class) dec;
                if (c.isAbstract()) {
                    that.addError("abstract class may not be instantiated: '" + dec.getName(unit) + "'");
                }
            }
        }
        Tree.NamedArgumentList nal = that.getNamedArgumentList();
        if (nal != null && dec.isAbstraction()) {
            // TODO: this is not really right - it's the fact
            // that we're calling Java and don't have
            // meaningful parameter names that is the
            // real problem, not the overload
            that.addError("overloaded declarations may not be called using named arguments: '" + dec.getName(unit) + "'");
        }
        // that.setTypeModel(prf.getType());
        Type ct = primary.getTypeModel();
        if (ct != null) {
            List<Type> tal = ct.getTypeArgumentList();
            if (!tal.isEmpty()) {
                // pull the return type out of the Callable
                that.setTypeModel(tal.get(0));
            }
        }
        if (nal != null) {
            List<ParameterList> parameterLists = fun.getParameterLists();
            if (!parameterLists.isEmpty() && !parameterLists.get(0).isNamedParametersSupported()) {
                that.addError("named invocations of Java methods not supported");
            }
        }
        if (dec.isAbstraction()) {
        // nothing to check the argument types against
        // that.addError("no matching overloaded declaration");
        } else {
            // typecheck arguments using the parameter list
            // of the target declaration
            checkInvocationArguments(that, prf, fun);
        }
    }
}
Also used : TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) Functional(org.eclipse.ceylon.model.typechecker.model.Functional) 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) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) 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)

Example 65 with Class

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

the class ExpressionVisitor method defaultType.

private Type defaultType() {
    TypeDeclaration ut = new UnknownType(unit);
    Class ad = unit.getAnythingDeclaration();
    if (ad != null) {
        ut.setExtendedType(ad.getType());
    }
    return ut.getType();
}
Also used : UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) 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)

Aggregations

Class (org.eclipse.ceylon.model.typechecker.model.Class)184 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)110 Type (org.eclipse.ceylon.model.typechecker.model.Type)87 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)78 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)72 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)55 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)46 Value (org.eclipse.ceylon.model.typechecker.model.Value)46 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)42 UnionType (org.eclipse.ceylon.model.typechecker.model.UnionType)39 Function (org.eclipse.ceylon.model.typechecker.model.Function)38 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)36 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)35 Interface (org.eclipse.ceylon.model.typechecker.model.Interface)33 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)33 ArrayList (java.util.ArrayList)32 IntersectionType (org.eclipse.ceylon.model.typechecker.model.IntersectionType)32 JCNewClass (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass)31 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)27 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)23