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);
}
}
}
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) + "'");
}
}
}
}
}
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");
}
}
// }
}
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);
}
}
}
}
}
}
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() + "'");
}
}
}
}
}
Aggregations