Search in sources :

Example 56 with Constructor

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

the class DeclarationVisitor method visit.

@Override
public void visit(Tree.Constructor that) {
    Constructor c = new Constructor();
    that.setConstructor(c);
    if (scope instanceof Class) {
        Class clazz = (Class) scope;
        if (that.getIdentifier() == null && clazz.getDefaultConstructor() != null) {
            // found an overloaded default constructor
            // we'll set up the class overloads later
            // when exiting visit(Tree.ClassDefinition)
            clazz.setOverloaded(true);
            clazz.setAbstraction(true);
        }
    }
    visitDeclaration(that, c, false);
    Type at;
    Scope realScope = getRealScope(scope);
    if (realScope instanceof Class) {
        Class clazz = (Class) realScope;
        Type ot = clazz.getType();
        c.setExtendedType(ot);
        at = c.appliedType(ot, NO_TYPE_ARGS);
        clazz.setConstructors(true);
        if (clazz.isAnonymous()) {
            that.addError("anonymous class may not have constructor: '" + clazz.getName() + "' is an anonymous class");
        }
    } else {
        at = null;
        that.addError("constructor declaration must occur directly in the body of a class");
    }
    Function f = new Function();
    f.setType(at);
    that.setDeclarationModel(f);
    visitDeclaration(that, f);
    Scope o = enterScope(c);
    super.visit(that);
    exitScope(o);
    f.setImplemented(that.getBlock() != null);
    if (that.getParameterList() == null) {
        that.addError("missing parameter list in constructor declaration: '" + name(that.getIdentifier()) + "' must have a parameter list", 1000);
    } else {
        ParameterList model = that.getParameterList().getModel();
        model.setFirst(true);
        if (model != null) {
            c.addParameterList(model);
            // TODO: fix this
            f.addParameterList(model);
        }
    }
    if (c.isAbstract()) {
        if (that.getIdentifier() == null) {
            that.addError("default constructor may not be annotated 'abstract'", 1601);
        } else if (c.isShared()) {
            that.addError("abstract constructor may not be annotated 'shared'", 1610);
        }
    }
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) IntersectionType(org.eclipse.ceylon.model.typechecker.model.IntersectionType) LazyType(org.eclipse.ceylon.model.typechecker.model.LazyType) UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) TypeVisitor.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.TypeVisitor.getTupleType) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) ConditionScope(org.eclipse.ceylon.model.typechecker.model.ConditionScope) ModelUtil.getRealScope(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getRealScope) ModelUtil.isDefaultConstructor(org.eclipse.ceylon.model.typechecker.model.ModelUtil.isDefaultConstructor) ModelUtil.isConstructor(org.eclipse.ceylon.model.typechecker.model.ModelUtil.isConstructor) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) Class(org.eclipse.ceylon.model.typechecker.model.Class) AnalyzerUtil.isVeryAbstractClass(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.isVeryAbstractClass) ModelUtil.isAnonymousClass(org.eclipse.ceylon.model.typechecker.model.ModelUtil.isAnonymousClass)

Example 57 with Constructor

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

the class InheritanceVisitor method visit.

@Override
public void visit(Tree.DelegatedConstructor that) {
    super.visit(that);
    TypeDeclaration constructor = (TypeDeclaration) that.getScope();
    Scope container = constructor.getContainer();
    Tree.SimpleType type = that.getType();
    if (type != null && constructor instanceof Constructor && container instanceof Class) {
        Class containingClass = (Class) container;
        Type et = containingClass.getExtendedType();
        if (et != null) {
            Unit unit = that.getUnit();
            Type extendedType = containingClass.getExtendedType();
            Type constructedType = type.getTypeModel();
            Declaration delegate = type.getDeclarationModel();
            TypeDeclaration superclass = et.getDeclaration();
            if (superclass instanceof Constructor) {
                superclass = superclass.getExtendedType().getDeclaration();
            }
            if (delegate instanceof Constructor) {
                Constructor c = (Constructor) delegate;
                if (c.equals(constructor)) {
                    type.addError("constructor delegates to itself: '" + c.getName() + "'");
                }
                Type delegatedType = c.getExtendedType();
                TypeDeclaration delegated = delegatedType == null ? null : delegatedType.getDeclaration();
                if (superclass.equals(delegated)) {
                    checkIsExactly(constructedType.getExtendedType(), extendedType, type, "type arguments must match type arguments in extended class expression");
                } else if (containingClass.equals(delegated)) {
                    if (type instanceof Tree.QualifiedType) {
                        Tree.QualifiedType qt = (Tree.QualifiedType) type;
                        checkIsExactly(constructedType.getQualifyingType(), containingClass.getType(), qt.getOuterType(), "type arguments must be the type parameters of this class");
                    }
                } else {
                    type.addError("not a constructor of the immediate superclass: '" + delegate.getName(unit) + "' is not a constructor of '" + superclass.getName(unit) + "'");
                }
            } else if (delegate instanceof Class) {
                if (superclass.equals(delegate)) {
                    checkIsExactly(constructedType, extendedType, type, "type arguments must match type arguments in extended class expression");
                } else if (containingClass.equals(delegate)) {
                    checkIsExactly(constructedType, containingClass.getType(), type, "type arguments must be the type parameters of this class");
                } else {
                    type.addError("does not instantiate the immediate superclass: '" + delegate.getName(unit) + "' is not '" + superclass.getName(unit) + "'");
                }
            }
        }
    }
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) 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) Unit(org.eclipse.ceylon.model.typechecker.model.Unit) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 58 with Constructor

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

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

the class TypeVisitor method visit.

@Override
public void visit(Tree.ExtendedType that) {
    inExtendsOrClassAlias = that.getInvocationExpression() != null;
    super.visit(that);
    inExtendsOrClassAlias = false;
    inheritedType(that.getType());
    checkExtendedTypeExpression(that.getType());
    TypeDeclaration td = (TypeDeclaration) that.getScope();
    if (!td.isAlias()) {
        Tree.SimpleType et = that.getType();
        if (et != null) {
            Type type = et.getTypeModel();
            if (type != null) {
                TypeDeclaration etd = et.getDeclarationModel();
                if (etd != null && !(etd instanceof UnknownType)) {
                    if (etd instanceof Constructor) {
                        type = type.getExtendedType();
                        etd = etd.getExtendedType().getDeclaration();
                    }
                    if (etd == td) {
                    // unnecessary, handled by SupertypeVisitor
                    // et.addError("directly extends itself: '" +
                    // td.getName() + "'");
                    } else if (etd instanceof TypeParameter) {
                        et.addError("directly extends a type parameter: '" + type.getDeclaration().getName(unit) + "'");
                    } else if (etd instanceof Interface) {
                        et.addError("extends an interface: '" + type.getDeclaration().getName(unit) + "'");
                    } else if (etd instanceof TypeAlias) {
                        et.addError("extends a type alias: '" + type.getDeclaration().getName(unit) + "'");
                    } else if (etd instanceof NothingType) {
                        et.addError("extends the bottom type 'Nothing'");
                    } else {
                        td.setExtendedType(type);
                    }
                }
            }
        }
    }
}
Also used : 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) 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) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) TypeAlias(org.eclipse.ceylon.model.typechecker.model.TypeAlias) 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) NothingType(org.eclipse.ceylon.model.typechecker.model.NothingType)

Example 60 with Constructor

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

the class TypeVisitor method visit.

@Override
public void visit(Tree.ClassDeclaration that) {
    ClassAlias td = (ClassAlias) that.getDeclarationModel();
    td.setExtendedType(null);
    super.visit(that);
    Tree.ClassSpecifier cs = that.getClassSpecifier();
    if (cs == null) {
        that.addError("missing class body or aliased class reference");
    } else {
        Tree.ExtendedType et = that.getExtendedType();
        if (et != null) {
            et.addError("class alias may not extend a type");
        }
        Tree.SatisfiedTypes sts = that.getSatisfiedTypes();
        if (sts != null) {
            sts.addError("class 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.SimpleType ct = cs.getType();
        if (ct == null) {
        // that.addError("malformed aliased class");
        } else if (!(ct instanceof Tree.StaticType)) {
            ct.addError("aliased type must be a class");
        } else {
            Type type = ct.getTypeModel();
            if (type != null && !type.isUnknown()) {
                TypeDeclaration dec = type.getDeclaration();
                td.setConstructor(dec);
                if (dec instanceof Constructor) {
                    if (dec.isValueConstructor()) {
                        ct.addError("aliases a value constructor");
                    } else if (dec.isAbstract()) {
                        ct.addError("aliases a partial constructor: '" + dec.getName(unit) + "' is declared abstract");
                    }
                    if (td.isShared() && !dec.isShared()) {
                        ct.addError("shared alias of an unshared constructor: '" + dec.getName(unit) + "' is not shared");
                    }
                    type = type.getExtendedType();
                    dec = dec.getExtendedType().getDeclaration();
                }
                if (dec instanceof Class) {
                    td.setExtendedType(type);
                } else {
                    ct.addError("not a class: '" + dec.getName(unit) + "'");
                }
                TypeDeclaration etd = ct.getDeclarationModel();
                if (etd == td) {
                    ct.addError("directly aliases itself: '" + td.getName() + "'");
                }
            }
        }
    }
}
Also used : ClassAlias(org.eclipse.ceylon.model.typechecker.model.ClassAlias) 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) 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) 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

Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)95 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)65 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)48 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)47 Type (org.eclipse.ceylon.model.typechecker.model.Type)45 Class (org.eclipse.ceylon.model.typechecker.model.Class)42 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)42 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)27 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)27 Value (org.eclipse.ceylon.model.typechecker.model.Value)27 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)26 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)25 Function (org.eclipse.ceylon.model.typechecker.model.Function)23 ModelUtil.isConstructor (org.eclipse.ceylon.model.typechecker.model.ModelUtil.isConstructor)21 ArrayList (java.util.ArrayList)20 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)19 Interface (org.eclipse.ceylon.model.typechecker.model.Interface)17 AnalyzerUtil.unwrapAliasedTypeConstructor (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.unwrapAliasedTypeConstructor)16 AnalyzerUtil.getPackageTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration)14 AnalyzerUtil.getTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)14