# 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])
- var c = new MClass(self, name, 0, enum_kind, public_visibility)
- var cladef = new MClassDef(self, c.mclass_type, new Location(null, 0,0,0,0), new Array[String])
+ var c = new MClass(self, name, null, enum_kind, public_visibility)
+ var cladef = new MClassDef(self, c.mclass_type, new Location(null, 0,0,0,0))
# The kind of the class (interface, abstract class, etc.)
# In Nit, the kind of a class cannot evolve in refinements
var kind: MClassKind
# The kind of the class (interface, abstract class, etc.)
# In Nit, the kind of a class cannot evolve in refinements
var kind: MClassKind
# In Nit, the visibility of a class cannot evolve in refinements
var visibility: MVisibility
# In Nit, the visibility of a class cannot evolve in refinements
var visibility: MVisibility
- init(intro_mmodule: MModule, name: String, arity: Int, kind: MClassKind, visibility: MVisibility)
+ init(intro_mmodule: MModule, name: String, parameter_names: nullable Array[String], kind: MClassKind, visibility: MVisibility)
var mclass_type = new MGenericType(self, mparametertypes)
self.mclass_type = mclass_type
self.get_mtype_cache.add(mclass_type)
var mclass_type = new MGenericType(self, mparametertypes)
self.mclass_type = mclass_type
self.get_mtype_cache.add(mclass_type)
- init(mmodule: MModule, bound_mtype: MClassType, location: Location, parameter_names: Array[String])
+ init(mmodule: MModule, bound_mtype: MClassType, location: Location)
self.bound_mtype = bound_mtype
self.mmodule = mmodule
self.mclass = bound_mtype.mclass
self.location = location
mmodule.mclassdefs.add(self)
mclass.mclassdefs.add(self)
self.bound_mtype = bound_mtype
self.mmodule = mmodule
self.mclass = bound_mtype.mclass
self.location = location
mmodule.mclassdefs.add(self)
mclass.mclassdefs.add(self)
- # 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?
-# It's mean that all refinements of a same class "share" the parameter type,
-# but that a generic subclass has its on parameter types.
+# It means that all refinements of a same class "share" the parameter type,
+# but that a generic subclass has its own parameter types.
#
# However, in the sense of the meta-model, a parameter type of a class is
# a valid type in a subclass. The "in the sense of the meta-model" is
#
# However, in the sense of the meta-model, a parameter type of a class is
# a valid type in a subclass. The "in the sense of the meta-model" is
- # Internal name of the parameter type
- # Names of parameter types changes in each class definition
- # Therefore, this method return an internal name.
- # Example: return "G#1" for the second parameter of the class G
- # FIXME: add a way to get the real name in a classdef
- redef fun to_s do return "{mclass}#{rank}"
+ redef var name
+
+ redef fun to_s do return name
# Resolve the bound for a given resolved_receiver
# The result may be a other virtual type (or a parameter type)
# Resolve the bound for a given resolved_receiver
# The result may be a other virtual type (or a 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]]
# Is the property defined at the top_level of the module?
# Currently such a property are stored in `Object`
# Is the property defined at the top_level of the module?
# Currently such a property are stored in `Object`
# Is the property a constructor?
# Warning, this property can be inherited by subclasses with or without being a constructor
# therefore, you should use `is_init_for` the verify if the property is a legal constructor for a given class
# Is the property a constructor?
# Warning, this property can be inherited by subclasses with or without being a constructor
# therefore, you should use `is_init_for` the verify if the property is a legal constructor for a given class
# Is the property a legal constructor for a given class?
# As usual, visibility is not considered.
# Is the property a legal constructor for a given class?
# As usual, visibility is not considered.
# The signature attached to the `new` call on a root-init
# This is a concatenation of the signatures of the initializers
#
# REQUIRE `mproperty.is_root_init == (new_msignature != null)`
# The signature attached to the `new` call on a root-init
# This is a concatenation of the signatures of the initializers
#
# REQUIRE `mproperty.is_root_init == (new_msignature != null)`
- var is_extern writable = false
+ var is_extern = false is writable
+
+ # An optional constant value returned in functions.
+ #
+ # Only some specific primitife value are accepted by engines.
+ # Is used when there is no better implementation available.
+ #
+ # Currently used only for the implementation of the `--define`
+ # command-line option.
+ # SEE: module `mixin`.
+ var constant_value: nullable Object = null 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