use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.
the class InheritanceVisitor method visit.
@Override
public void visit(Tree.ExtendedType that) {
super.visit(that);
TypeDeclaration td = (TypeDeclaration) that.getScope();
if (!td.isAlias()) {
Tree.SimpleType et = that.getType();
if (et != null) {
Tree.InvocationExpression ie = that.getInvocationExpression();
Class clazz = (Class) td;
boolean hasConstructors = clazz.hasConstructors() || clazz.hasEnumerated();
boolean anonymous = clazz.isAnonymous();
if (ie == null) {
if (!hasConstructors || anonymous) {
et.addError("missing instantiation arguments");
}
} else {
if (hasConstructors && !anonymous) {
et.addError("unnecessary instantiation arguments");
}
}
Unit unit = that.getUnit();
Type type = et.getTypeModel();
if (type != null) {
checkSelfTypes(et, td, type);
checkExtensionOfMemberType(et, td, type);
// checkCaseOfSupertype(et, td, type);
Type ext = td.getExtendedType();
TypeDeclaration etd = ext == null ? null : ext.getDeclaration();
TypeDeclaration aetd = type.getDeclaration();
if (aetd instanceof Constructor && aetd.isAbstract()) {
et.addError("extends a partial constructor: '" + aetd.getName(unit) + "' is declared abstract");
}
while (etd != null && etd.isAlias()) {
Type etdet = etd.getExtendedType();
etd = etdet == null ? null : etdet.getDeclaration();
}
if (etd != null) {
if (etd.isFinal()) {
et.addError("extends a final class: '" + etd.getName(unit) + "' is declared final");
}
if (aetd instanceof Class && !contains(aetd, that.getScope())) {
Class c = (Class) aetd;
Constructor dc = c.getDefaultConstructor();
if (dc != null && !dc.isShared()) {
that.addError("extends a class with an unshared default constructor: default constructor of '" + c.getName(unit) + "' is not 'shared'");
}
}
if (etd.isSealed() && !unit.inSameModule(etd)) {
String moduleName = etd.getUnit().getPackage().getModule().getNameAsString();
et.addError("extends a sealed class in a different module: '" + etd.getName(unit) + "' in '" + moduleName + "' is sealed");
}
}
}
checkSupertypeVarianceAnnotations(et);
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.
the class InheritanceVisitor method visit.
@Override
public void visit(Tree.Constructor that) {
super.visit(that);
Constructor c = that.getConstructor();
Scope container = c.getContainer();
if (container instanceof Class) {
Class cl = (Class) container;
List<TypedDeclaration> caseValues = cl.getCaseValues();
if (caseValues != null && !c.isAbstract() && !cl.isAbstract()) {
that.addError("concrete enumerated class may not have non-partial callable constructor: enumerated class '" + cl.getName() + "' is not abstract and constructor '" + c.getName() + "' is not partial");
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Constructor 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);
}
use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.
the class TypeVisitor method checkExtendedTypeExpression.
void checkExtendedTypeExpression(Tree.Type type) {
if (type instanceof Tree.QualifiedType) {
Tree.QualifiedType qualifiedType = (Tree.QualifiedType) type;
Tree.StaticType outerType = qualifiedType.getOuterType();
if (!(outerType instanceof Tree.SuperType)) {
TypeDeclaration otd = qualifiedType.getDeclarationModel();
if (otd != null) {
if (otd.isStatic() || otd instanceof Constructor) {
checkExtendedTypeExpression(outerType);
} else {
outerType.addError("illegal qualifier in constructor delegation (must be super)");
}
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Constructor 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);
}
Aggregations