# Hierarchy of class definition.
#
# Each classdef is associated with its super-classdefs in regard to
# its module of definition.
# Hierarchy of class definition.
#
# Each classdef is associated with its super-classdefs in regard to
# its module of definition.
# This poset will evolve in a monotonous way:
# * Two non connected nodes will remain unconnected
# * New nodes can appear with new edges
# This poset will evolve in a monotonous way:
# * Two non connected nodes will remain unconnected
# * New nodes can appear with new edges
# This poset will evolve in an anarchic way. Loops can even be created.
#
# FIXME decide what to do on loops
# This poset will evolve in an anarchic way. Loops can even be created.
#
# FIXME decide what to do on loops
# Build an ordered tree with from `concerns`
fun concerns_tree(mconcerns: Collection[MConcern]): ConcernsTree do
# Build an ordered tree with from `concerns`
fun concerns_tree(mconcerns: Collection[MConcern]): ConcernsTree do
# Does the current module has a given class `mclass`?
# Return true if the mmodule introduces, refines or imports a class.
# Does the current module has a given class `mclass`?
# Return true if the mmodule introduces, refines or imports a class.
# The most general is first, the most specific is last
fun linearize_mclasses(mclasses: Array[MClass])
do
self.flatten_mclass_hierarchy.sort(mclasses)
end
# The most general is first, the most specific is last
fun linearize_mclasses(mclasses: Array[MClass])
do
self.flatten_mclass_hierarchy.sort(mclasses)
end
# the refinement link is stronger than the specialisation link
# The most general is first, the most specific is last
fun linearize_mclassdefs(mclassdefs: Array[MClassDef])
# the refinement link is stronger than the specialisation link
# The most general is first, the most specific is last
fun linearize_mclassdefs(mclassdefs: Array[MClassDef])
# the refinement link is stronger than the specialisation link
# The most general is first, the most specific is last
fun linearize_mpropdefs(mpropdefs: Array[MPropDef])
# the refinement link is stronger than the specialisation link
# The most general is first, the most specific is last
fun linearize_mpropdefs(mpropdefs: Array[MPropDef])
- # The trick here is that fixed formal type will be associed to the bound
- # And unfixed formal types will be associed to a canonical formal type.
+ # The trick here is that fixed formal type will be associated to the bound
+ # And unfixed formal types will be associated to a canonical formal type.
if sub isa MParameterType or sub isa MVirtualType then
assert anchor != null
sub = sub.resolve_for(anchor.mclass.mclass_type, anchor, mmodule, false)
if sub isa MParameterType or sub isa MVirtualType then
assert anchor != null
sub = sub.resolve_for(anchor.mclass.mclass_type, anchor, mmodule, false)
# Is the type is already not nullable, then self is returned.
#
# Note: this just remove the `nullable` notation, but the result can still contains null.
# Is the type is already not nullable, then self is returned.
#
# Note: this just remove the `nullable` notation, but the result can still contains null.
- private var collect_mclassdefs_cache: HashMap[MModule, Set[MClassDef]] = new HashMap[MModule, Set[MClassDef]]
- private var collect_mclasses_cache: HashMap[MModule, Set[MClass]] = new HashMap[MModule, Set[MClass]]
- private var collect_mtypes_cache: HashMap[MModule, Set[MClassType]] = new HashMap[MModule, Set[MClassType]]
+ private var collect_mclassdefs_cache = new HashMap[MModule, Set[MClassDef]]
+ private var collect_mclasses_cache = new HashMap[MModule, Set[MClass]]
+ private var collect_mtypes_cache = new HashMap[MModule, Set[MClassType]]
var verbatim_bound = lookup_bound(mmodule, resolved_reciever)
# The bound is exactly as declared in the "type" property, so we must resolve it again
var res = verbatim_bound.resolve_for(mtype, anchor, mmodule, cleanup_virtual)
var verbatim_bound = lookup_bound(mmodule, resolved_reciever)
# The bound is exactly as declared in the "type" property, so we must resolve it again
var res = verbatim_bound.resolve_for(mtype, anchor, mmodule, cleanup_virtual)
# What to return here? There is a bunch a special cases:
# If 'cleanup_virtual' we must return the resolved type, since we cannot return self
if cleanup_virtual then return res
# What to return here? There is a bunch a special cases:
# If 'cleanup_virtual' we must return the resolved type, since we cannot return self
if cleanup_virtual then return res
if resolved_reciever isa MNullableType then resolved_reciever = resolved_reciever.mtype
if resolved_reciever.as(MClassType).mclass.kind == enum_kind then return res
# If the resolved type isa MVirtualType, it means that self was bound to it, and cannot be unbound. self is just fixed. so return the resolution.
if res isa MVirtualType then return res
# If we are final, just return the resolution
if is_fixed(mmodule, resolved_reciever) then return res
if resolved_reciever isa MNullableType then resolved_reciever = resolved_reciever.mtype
if resolved_reciever.as(MClassType).mclass.kind == enum_kind then return res
# If the resolved type isa MVirtualType, it means that self was bound to it, and cannot be unbound. self is just fixed. so return the resolution.
if res isa MVirtualType then return res
# If we are final, just return the resolution
if is_fixed(mmodule, resolved_reciever) then return res
if res isa MClassType and res.mclass.kind == enum_kind then return res
# TODO: Add 'fixed' virtual type in the specification.
# TODO: What if bound to a MParameterType?
if res isa MClassType and res.mclass.kind == enum_kind then return res
# TODO: Add 'fixed' virtual type in the specification.
# TODO: What if bound to a MParameterType?
#
# Each parameter type is associated to a specific class.
# It means that all refinements of a same class "share" the parameter type,
#
# Each parameter type is associated to a specific class.
# It means that all refinements of a same class "share" the parameter type,
# self is a parameter type of mtype (or of a super-class of mtype)
# The point of the function it to get the bound of the virtual type that make sense for mtype
# But because mtype is maybe a virtual/formal type, we need to get a real receiver first
# self is a parameter type of mtype (or of a super-class of mtype)
# The point of the function it to get the bound of the virtual type that make sense for mtype
# But because mtype is maybe a virtual/formal type, we need to get a real receiver first
# All definitions of the property.
# The first is the introduction,
# The other are redefinitions (in refinements and in subclasses)
# All definitions of the property.
# The first is the introduction,
# The other are redefinitions (in refinements and in subclasses)
# The definition that introduced the property
# Warning: the introduction is the first `MPropDef` object
# The definition that introduced the property
# Warning: the introduction is the first `MPropDef` object
- private var lookup_definitions_cache: HashMap2[MModule, MType, Array[MPROPDEF]] = new HashMap2[MModule, MType, Array[MPROPDEF]]
+ private var lookup_definitions_cache = new HashMap2[MModule, MType, Array[MPROPDEF]]
# Return the most specific property definitions inherited by a type.
# The selection knows that refinement is stronger than specialization;
# Return the most specific property definitions inherited by a type.
# The selection knows that refinement is stronger than specialization;
# If you want to know the next properties in the linearization,
# look at `MPropDef::lookup_next_definition`.
#
# If you want to know the next properties in the linearization,
# look at `MPropDef::lookup_next_definition`.
#
#
# REQUIRE: `not mtype.need_anchor`
# REQUIRE: `mtype.has_mproperty(mmodule, self)`
#
# REQUIRE: `not mtype.need_anchor`
# REQUIRE: `mtype.has_mproperty(mmodule, self)`
- # Return all definitions in a linearisation order
- # Most speficic first, most general last
+ # Return all definitions in a linearization order
+ # Most specific first, most general last
fun lookup_all_definitions(mmodule: MModule, mtype: MType): Array[MPROPDEF]
do
assert not mtype.need_anchor
fun lookup_all_definitions(mmodule: MModule, mtype: MType): Array[MPROPDEF]
do
assert not mtype.need_anchor
- private var lookup_all_definitions_cache: HashMap2[MModule, MType, Array[MPROPDEF]] = new HashMap2[MModule, MType, Array[MPROPDEF]]
+ private var lookup_all_definitions_cache = new HashMap2[MModule, MType, Array[MPROPDEF]]
# The constructor is a (the) root init with empty signature but a set of initializers
var is_root_init: Bool = false is writable
# The constructor is a (the) root init with empty signature but a set of initializers
var is_root_init: Bool = false is writable
return self == other
else if other == enum_kind or other == extern_kind then
# abstract_kind and concrete_kind are incompatible
return self == other
else if other == enum_kind or other == extern_kind then
# abstract_kind and concrete_kind are incompatible