use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class TypeVisitor method visit.
/* private boolean hasSharedConstructors(Class cd) {
for (Declaration m: cd.getMembers()) {
if (m instanceof Constructor &&
m.isShared()) {
return true;
}
}
return false;
}*/
@Override
public void visit(Tree.InterfaceDefinition that) {
Interface id = that.getDeclarationModel();
id.setExtendedType(null);
id.getSatisfiedTypes().clear();
Class od = unit.getObjectDeclaration();
if (od != null) {
id.setExtendedType(od.getType());
}
super.visit(that);
}
use of org.eclipse.ceylon.model.typechecker.model.Interface 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.Interface in project ceylon by eclipse.
the class TypeVisitor method visit.
@Override
public void visit(Tree.InterfaceDeclaration that) {
Interface id = that.getDeclarationModel();
id.setExtendedType(null);
super.visit(that);
Tree.TypeSpecifier typeSpecifier = that.getTypeSpecifier();
if (typeSpecifier == null) {
if (!id.isNative()) {
that.addError("missing interface body or aliased interface reference");
}
} else {
Tree.SatisfiedTypes sts = that.getSatisfiedTypes();
if (sts != null) {
sts.addError("interface 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.StaticType et = typeSpecifier.getType();
if (et == null) {
// that.addError("malformed aliased interface");
} else if (!(et instanceof Tree.StaticType)) {
typeSpecifier.addError("aliased type must be an interface");
} else {
Type type = et.getTypeModel();
if (type != null && !type.isUnknown()) {
TypeDeclaration dec = type.getDeclaration();
if (dec instanceof Interface) {
id.setExtendedType(type);
} else {
et.addError("not an interface: '" + dec.getName(unit) + "'");
}
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Interface 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);
}
use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class TypeParserTests method testSpreadCallableAbbrev.
@Test
public void testSpreadCallableAbbrev() {
Type type = new TypeParser(MockLoader.instance).decodeType("a(*[b,a])", null, mockDefaultModule, mockPkgUnit);
Assert.assertNotNull(type);
TypeDeclaration declaration = type.getDeclaration();
Assert.assertNotNull(declaration);
Assert.assertTrue(declaration instanceof Interface);
Assert.assertEquals("ceylon.language::Callable", declaration.getQualifiedNameString());
Assert.assertEquals("a(b, a)", type.asString());
Assert.assertNull(type.getQualifyingType());
}
Aggregations