use of org.eclipse.ceylon.model.typechecker.model.TypedDeclaration 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.TypedDeclaration in project ceylon by eclipse.
the class TypeVisitor method visit.
@Override
public void visit(Tree.TypedDeclaration that) {
super.visit(that);
Tree.Type type = that.getType();
TypedDeclaration dec = that.getDeclarationModel();
setType(that, type, dec);
if (dec instanceof FunctionOrValue) {
FunctionOrValue mv = (FunctionOrValue) dec;
if (dec.isLate() && mv.isParameter()) {
that.addError("parameter may not be annotated late");
}
}
// if (type.getTypeModel().isTypeConstructor()) {
// type.addError("type constructor may not occur as the type of a declaration");
// }
}
use of org.eclipse.ceylon.model.typechecker.model.TypedDeclaration 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);
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypedDeclaration in project ceylon by eclipse.
the class ExpressionVisitor method handleUncheckedNulls.
private void handleUncheckedNulls(Tree.LocalModifier local, Type type, Tree.Term term, Declaration declaration) {
if (type != null && !type.isUnknown() && type.isSubtypeOf(unit.getObjectType())) {
if (declaration instanceof TypedDeclaration && canHaveUncheckedNulls(type)) {
TypedDeclaration td = (TypedDeclaration) declaration;
td.setUncheckedNullType(true);
} else {
// this case happens when a method of
// a Ceylon-primitive instantiation of
// a Java generic type is assigned to
// an inferred value or function
warnUncheckedNulls(local, type, term);
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypedDeclaration in project ceylon by eclipse.
the class ExpressionVisitor method visit.
@Override
public void visit(Tree.TypedDeclaration that) {
super.visit(that);
TypedDeclaration d = that.getDeclarationModel();
Type type = d.getType();
FunctionOrValue fov = (FunctionOrValue) d;
if (fov.isSmall() && type != null && !type.isInteger() && !type.isFloat() && !type.isCharacter() && !that.getType().hasErrors()) {
that.addError("type may not be annotated 'small': '" + d.getName() + "' has type '" + type.asString(that.getUnit()) + "' (only an 'Integer', 'Float', or 'Character' may be small)");
}
}
Aggregations