use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class JsonPackage method loadInterface.
@SuppressWarnings("unchecked")
Interface loadInterface(String name, Map<String, Object> m, Scope parent, final List<TypeParameter> existing) {
// Check if it's been loaded first
// It hasn't been loaded, so create it
Interface t;
m.remove(KEY_NAME);
if (m.get(KEY_METATYPE) instanceof Interface) {
t = (Interface) m.get(KEY_METATYPE);
if (m.size() <= 3) {
// it's been loaded
return t;
}
} else {
if (m.containsKey("$alias")) {
t = new InterfaceAlias();
} else {
t = new Interface();
}
t.setContainer(parent);
t.setScope(parent);
t.setName(name);
t.setUnit(u2);
if (parent == this) {
u2.addDeclaration(t);
}
parent.addMember(t);
m.put(KEY_METATYPE, t);
setAnnotations(t, (Integer) m.remove(KEY_PACKED_ANNS), m.remove(KEY_ANNOTATIONS));
}
if (m.remove(KEY_DYNAMIC) != null) {
t.setDynamic(true);
}
List<TypeParameter> tparms = t.getTypeParameters();
List<Map<String, Object>> listOfMaps = (List<Map<String, Object>>) m.get(KEY_TYPE_PARAMS);
if (listOfMaps != null && (tparms == null || tparms.size() < listOfMaps.size())) {
tparms = parseTypeParameters(listOfMaps, t, existing);
m.remove(KEY_TYPE_PARAMS);
}
final List<TypeParameter> allparms = JsonPackage.merge(tparms, existing);
// All interfaces extend Object, except aliases
if (t.getExtendedType() == null) {
if (t.isAlias()) {
t.setExtendedType(getTypeFromJson((Map<String, Object>) m.remove("$alias"), parent instanceof Declaration ? (Declaration) parent : null, allparms));
} else {
t.setExtendedType(getTypeFromJson(objclass, parent instanceof Declaration ? (Declaration) parent : null, null));
}
}
if (m.containsKey(KEY_SELF_TYPE)) {
for (TypeParameter _tp : tparms) {
if (_tp.getName().equals(m.get(KEY_SELF_TYPE))) {
t.setSelfType(_tp.getType());
_tp.setSelfTypedDeclaration(t);
}
}
m.remove(KEY_SELF_TYPE);
}
if (m.containsKey("of") && t.getCaseTypes() == null) {
t.setCaseTypes(parseTypeList((List<Map<String, Object>>) m.remove("of"), allparms));
}
if (m.containsKey(KEY_SATISFIES)) {
for (Type s : parseTypeList((List<Map<String, Object>>) m.remove(KEY_SATISFIES), allparms)) {
t.getSatisfiedTypes().add(s);
}
}
addAttributesAndMethods(m, t, allparms);
if (m.containsKey(KEY_INTERFACES)) {
Map<String, Map<String, Object>> cdefs = (Map<String, Map<String, Object>>) m.remove(KEY_INTERFACES);
for (Map.Entry<String, Map<String, Object>> cdef : cdefs.entrySet()) {
loadInterface(cdef.getKey(), cdef.getValue(), t, allparms);
}
}
if (m.containsKey(KEY_CLASSES)) {
Map<String, Map<String, Object>> cdefs = (Map<String, Map<String, Object>>) m.remove(KEY_CLASSES);
for (Map.Entry<String, Map<String, Object>> cdef : cdefs.entrySet()) {
loadClass(cdef.getKey(), cdef.getValue(), t, allparms);
}
}
if (t.isDynamic() && (getModule().getJsMajor() < 9 || (getModule().getJsMajor() == 9 && getModule().getJsMinor() < 1))) {
// previous versions did not set dynamic flag on members
t.makeMembersDynamic();
}
return t;
}
use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class ExpressionVisitor method checkIndexedAssignment.
private void checkIndexedAssignment(Tree.AssignmentOp that, Type rhst) {
Tree.IndexExpression idx = (Tree.IndexExpression) that.getLeftTerm();
if (idx.getElementOrRange() instanceof Tree.Element) {
Type pt = type(idx);
if (that.getTypeModel() != null && pt != null) {
Interface cmd = unit.getKeyedCorrespondenceMutatorDeclaration();
Type vt = checkIndexElement(idx, pt, cmd, false, "KeyedCorrespondenceMutator", true);
if (vt != null) {
checkAssignable(rhst, vt, that.getRightTerm(), "assigned expression must be assignable to item type '" + vt.asString() + "' of 'CorrespondenceMutator'");
// that.setTypeModel(vt);
}
}
} else {
idx.getPrimary().addError("ranged index assignment is not supported");
}
}
use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class InheritanceVisitor method checkSelfTypes.
private void checkSelfTypes(Tree.StaticType that, TypeDeclaration td, Type type) {
if (!(td instanceof TypeParameter)) {
// TODO: is this really ok?!
List<TypeParameter> params = type.getDeclaration().getTypeParameters();
List<Type> args = type.getTypeArgumentList();
Unit unit = that.getUnit();
for (int i = 0; i < params.size(); i++) {
TypeParameter param = params.get(i);
if (param.isSelfType() && !args.isEmpty()) {
Type arg = args.get(i);
if (arg == null) {
arg = unit.getUnknownType();
}
TypeDeclaration std = param.getSelfTypedDeclaration();
Type at;
TypeDeclaration mtd;
if (param.getContainer().equals(std)) {
at = td.getType();
mtd = td;
} else {
// TODO: lots wrong here?
mtd = (TypeDeclaration) td.getMember(std.getName(), null, false);
at = mtd == null ? null : mtd.getType();
}
if (at != null && !at.isSubtypeOf(arg)) {
Type st = mtd.getSelfType();
if (st == null || !st.isExactly(arg)) {
String help = "";
TypeDeclaration atd = at.getDeclaration();
TypeDeclaration ad = arg.getDeclaration();
if (ad instanceof TypeParameter) {
TypeParameter tp = (TypeParameter) ad;
if (tp.getDeclaration().equals(td)) {
help = " (try making '" + ad.getName() + "' a self type of '" + td.getName() + "')";
}
} else if (ad instanceof Interface) {
help = " (try making " + message(atd) + " satisfy '" + ad.getName() + "')";
} else if (ad instanceof Class && td instanceof Class) {
help = " (try making " + message(atd) + " extend '" + ad.getName() + "')";
}
that.addError("type argument does not satisfy self type constraint on type parameter '" + param.getName() + "' of '" + type.getDeclaration().getName(unit) + "': '" + arg.asString(unit) + "' is not a supertype or self type of " + message(atd) + help);
}
}
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class InheritanceVisitor method checkDirectSubtype.
private static boolean checkDirectSubtype(TypeDeclaration td, Node node, Type type) {
boolean found = false;
TypeDeclaration ctd = type.getDeclaration();
if (td instanceof Interface) {
for (Type st : ctd.getSatisfiedTypes()) {
if (st != null && st.resolveAliases().getDeclaration().equals(td)) {
found = true;
}
}
} else if (td instanceof Class) {
Type et = ctd.getExtendedType();
if (et != null && et.resolveAliases().getDeclaration().equals(td)) {
found = true;
}
}
if (!found) {
node.addError("case type is not a direct subtype of enumerated type: " + ctd.getName(node.getUnit()));
}
return found;
}
use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class TypeHierarchyVisitor method validateMemberRefinement.
private void validateMemberRefinement(Node that, TypeDeclaration td) {
if (!td.isInconsistentType() && td instanceof ClassOrInterface && !td.isAbstract() && !td.isAlias() && // resulting in multiple errors
!that.hasErrors()) {
Set<String> errors = new HashSet<String>();
for (TypeDeclaration std : td.getSupertypeDeclarations()) {
for (Declaration d : std.getMembers()) {
if (d.isShared() && !d.isStatic() && !isConstructor(d) && !isOverloadedVersion(d) && isResolvable(d) && !errors.contains(d.getName())) {
Declaration r = td.getMember(d.getName(), null, false);
// to the user!
if (r != null && !r.refines(d) && // is a dupe declaration
!r.getContainer().equals(td) && !((std instanceof Interface || r.isInterfaceMember()) && isDefinedInJava(std) && isDefinedInJava(r))) {
TypeDeclaration ctd = (TypeDeclaration) r.getContainer();
that.addError("member '" + d.getName() + "' is inherited ambiguously by '" + td.getName() + "' from '" + std.getName() + "' and a different generic instantiation of '" + ctd.getName() + "' and is not refined by '" + td.getName() + "' (refine '" + d.getName() + "' to satisfy both instantiations of '" + ctd.getName() + "')", 350);
errors.add(d.getName());
}
}
}
}
}
}
Aggregations