if anchor == null then anchor = sub # UGLY: any anchor will work
var resolved_sub = sub.anchor_to(mmodule, anchor)
var res = resolved_sub.collect_mclasses(mmodule).has(sup.mclass)
- if res == false then return false
+ if not res then return false
if not sup isa MGenericType then return true
var sub2 = sub.supertype_to(mmodule, anchor, sup.mclass)
assert sub2.mclass == sup.mclass
var sub_arg = sub2.arguments[i]
var sup_arg = sup.arguments[i]
res = sub_arg.is_subtype(mmodule, anchor, sup_arg)
- if res == false then return false
+ if not res then return false
end
return true
end
class MClassKind
redef var to_s
+ # Can a class of kind `self` define a membership predicate?
+ var can_customize_isa: Bool
+
+ # Can a class of kind `self` define a constructor?
+ var can_init: Bool
+
# Is a constructor required?
var need_init: Bool
# Can a class of kind `self` specializes a class of kind `other`?
fun can_specialize(other: MClassKind): Bool
do
- if other == interface_kind then return true # everybody can specialize interfaces
- if self == interface_kind or self == enum_kind then
- # no other case for interfaces
+ if other == interface_kind then
+ # everybody can specialize interfaces
+ return true
+ else if self == interface_kind or self == enum_kind then
+ # no other case for interfaces and enums
return false
+ else if self == subset_kind then
+ # A subset may specialize anything, except another subset.
+ # TODO: Allow sub-subsets once we can handle them.
+ return other != subset_kind
else if self == extern_kind then
# only compatible with themselves
return self == other
- else if other == enum_kind or other == extern_kind then
- # abstract_kind and concrete_kind are incompatible
- return false
+ else
+ # assert self == abstract_kind or self == concrete_kind
+ return other == abstract_kind or other == concrete_kind
end
- # remain only abstract_kind and concrete_kind
- return true
end
end
# The class kind `abstract`
-fun abstract_kind: MClassKind do return once new MClassKind("abstract class", true)
+fun abstract_kind: MClassKind do return once new MClassKind("abstract class", false, true, true)
# The class kind `concrete`
-fun concrete_kind: MClassKind do return once new MClassKind("class", true)
+fun concrete_kind: MClassKind do return once new MClassKind("class", false, true, true)
# The class kind `interface`
-fun interface_kind: MClassKind do return once new MClassKind("interface", false)
+fun interface_kind: MClassKind do return once new MClassKind("interface", false, true, false)
# The class kind `enum`
-fun enum_kind: MClassKind do return once new MClassKind("enum", false)
+fun enum_kind: MClassKind do return once new MClassKind("enum", false, true, false)
# The class kind `extern`
-fun extern_kind: MClassKind do return once new MClassKind("extern class", false)
+fun extern_kind: MClassKind do return once new MClassKind("extern class", false, true, false)
+# The class kind `subset`
+fun subset_kind: MClassKind do return once new MClassKind("subset", true, false, false)
# A standalone pre-constructed model used to test various model-related methods.
#