MClass
es are global to the model; it means that a MClass
is not bound
to a specific MModule
.
This characteristic helps the reasoning about classes in a program since a
single MClass
object always denote the same class.
The drawback is that classes (MClass
) contain almost nothing by themselves.
These do not really have properties nor belong to a hierarchy since the property and the
hierarchy of a class depends of the refinement in the modules.
Most services on classes require the precision of a module, and no one can asks what are the super-classes of a class nor what are properties of a class without precising what is the module considered.
For instance, during the typing of a source-file, the module considered is the module of the file.
eg. the question is the method foo
exists in the class Bar
? must be reformulated into
is the method foo
exists in the class Bar
in the current module?
During some global analysis, the module considered may be the main module of the program.
nitc :: MClass :: _abstract_loaded
Indicate this class was partially loaded (it only has its identifier allocated)nitc :: MClass :: _ftype_cache
nitc :: MClass :: _ftype_computed
nitc :: MClass :: _get_mtype_cache
nitc :: MClass :: _has_new_factory
Is there anew
factory to allow the pseudo instantiation?
nitc :: MClass :: _intro_mattributes
TheMAttribute
this class introduced
nitc :: MClass :: _intro_mmethods
TheMMethod
this class introduced
nitc :: MClass :: _intro_mmodule
The module that introduce the classnitc :: MClass :: _is_example
nitc :: MClass :: _mattributes
AllMAttribute
this class contains
nitc :: MClass :: _mclass_type
The principal static type of the class.nitc :: MClass :: _mclassdefs
All class definitions (introduction and refinements)nitc :: MClass :: _mparameters
Each generic formal parameters in order.nitc :: MClass :: _position_attributes
The position of the class' block in virtual table,nitc :: MClass :: _position_methods
The position of the class' block in attribute tablenitc :: MClass :: _positions_attributes
For superclasses which have a non-invariant position, keep their position in attribute tablenitc :: MClass :: _positions_methods
For superclasses which have a non-invariant position, keep their position in virtual tablenitc :: MClass :: _the_root_init_mmethod
The base init of the class.nitc :: MClass :: abstract_loaded
Indicate this class was partially loaded (it only has its identifier allocated)nitc :: MClass :: abstract_loaded=
Indicate this class was partially loaded (it only has its identifier allocated)nitc :: MClass :: allocate_vtable
Allocate a single vtablenitc :: MClass :: calculate_delta
Computes delta for each classnitc :: MClass :: collect_accessible_inits
Collect all init methods accessible byself
nitc :: MClass :: collect_accessible_mattributes
Collect all attributes accessible byself
nitc :: MClass :: collect_accessible_mmethods
Collect all methods accessible byself
nitc :: MClass :: collect_accessible_mproperties
Collect all properties accessible byself
nitc :: MClass :: collect_accessible_vts
Collect all virtual types accessible byself
nitc :: MClass :: collect_inherited_inits
Collect all init methods inherited byself
nitc :: MClass :: collect_inherited_mattributes
Collect all attributes inherited byself
nitc :: MClass :: collect_inherited_mmethods
Collect all methods inherited byself
nitc :: MClass :: collect_inherited_mproperties
Collect all properties inehrited byself
nitc :: MClass :: collect_inherited_vts
Collect all virtual types inherited byself
nitc :: MClass :: collect_intro_inits
Collect all init methods introduced inself
nitc :: MClass :: collect_intro_mattributes
Collect all attributes introduced inself
nitc :: MClass :: collect_intro_mmethods
Collect all methods introduced inself
nitc :: MClass :: collect_intro_mpropdefs
Collect all property definitions that are introductions inself
nitc :: MClass :: collect_intro_mproperties
Collect all properties introduced inself
nitc :: MClass :: collect_intro_vts
Collect all virtual types introduced inself
nitc :: MClass :: collect_local_inits
Collect all init methods introduced and redefined inself
nitc :: MClass :: collect_local_mattributes
Collect all attributes introduced and redefined inself
nitc :: MClass :: collect_local_mmethods
Collect all methods introduced and redefined inself
nitc :: MClass :: collect_local_mproperties
Collect all properties introduced and redefined inself
nitc :: MClass :: collect_local_vts
Collect all virtual types introduced or redefined inself
nitc :: MClass :: collect_mclassdefs
Collect all class definitions ofself
nitc :: MClass :: collect_redef_inits
Collect all init methods redefined inself
nitc :: MClass :: collect_redef_mattributes
Collect all attributes redefined inself
nitc :: MClass :: collect_redef_mmethods
Collect all methods redefined inself
nitc :: MClass :: collect_redef_mpropdefs
Collect all propierty definitions that are redefinition inself
nitc :: MClass :: collect_redef_mproperties
Collect all properties redefined inself
nitc :: MClass :: collect_redef_vts
Collect all virtual types redefined inself
nitc :: MClass :: compile_to_java
Generate a Java RTClass for a Nit MClassnitc :: MClass :: compile_type_table
Compile the type table for the MClassnitc :: MClass :: compile_vft
Compile the virtual function table for the mclassnitc :: MClass :: compute_ftype
Type in C of the extern classnitc :: MClass :: compute_identifier
Allocate a unique identifier to the class with perfect hashingnitc :: MClass :: create_abstract_method
This method create an abstract method representation with this MMethodDef an this AMethoddefnitc :: MClass :: create_empty_method
Create method with an empty blocknitc :: MClass :: defaultinit
nitc :: MClass :: extended_mproperties
the set of redefition that call to supernitc :: MClass :: fill_vtable
Fill the vtable with local methods forself
class
nitc :: MClass :: ftype_cache
nitc :: MClass :: ftype_cache=
nitc :: MClass :: ftype_computed
nitc :: MClass :: ftype_computed=
nitc :: MClass :: full_name=
The canonical name of the classnitc :: MClass :: get_mtype_cache
nitc :: MClass :: get_mtype_cache=
nitc :: MClass :: get_position_attributes
Return the position of the attribute's block of classcl
in self
if cl
has an invariant position in self,
nitc :: MClass :: get_position_methods
Return the position of the method's block of classcl
in self
if cl
has an invariant position in self,
nitc :: MClass :: has_new_factory
Is there anew
factory to allow the pseudo instantiation?
nitc :: MClass :: has_new_factory=
Is there anew
factory to allow the pseudo instantiation?
nitc :: MClass :: in_hierarchy
Return the classself
in the class hierarchy of the module mmodule
.
nitc :: MClass :: intro_mattributes
TheMAttribute
this class introduced
nitc :: MClass :: intro_mattributes=
TheMAttribute
this class introduced
nitc :: MClass :: intro_mmethods
TheMMethod
this class introduced
nitc :: MClass :: intro_mmethods=
TheMMethod
this class introduced
nitc :: MClass :: intro_mmodule=
The module that introduce the classnitc :: MClass :: is_abstract=
Isself
and abstract class?
nitc :: MClass :: is_example=
nitc :: MClass :: is_extender
extenders contain more introduction than redefinitionsnitc :: MClass :: is_interface=
Isself
an interface kind?
nitc :: MClass :: is_overrider
overriders contain more definitions than introductionsnitc :: MClass :: is_pure_extender
pure extenders contain only introductionsnitc :: MClass :: is_pure_overrider
pure overriders contain only redefinitionsnitc :: MClass :: is_pure_replacer
pure replacers never call to super in its redefinitionsnitc :: MClass :: is_pure_specializer
pure specializers always call to super in its redefinitionsnitc :: MClass :: is_replacer
replacers have less redefinitions that call super than not calling itnitc :: MClass :: is_specializer
specializers have more redefinitions that call super than not calling itnitc :: MClass :: mattributes=
AllMAttribute
this class contains
nitc :: MClass :: mclass_type=
The principal static type of the class.nitc :: MClass :: mclassdefs
All class definitions (introduction and refinements)nitc :: MClass :: mclassdefs=
All class definitions (introduction and refinements)nitc :: MClass :: moved_class_attributes
This method is called whencurrent_class
class is moved in attribute table of self
nitc :: MClass :: moved_class_methods
This method is called whencurrent_class
class is moved in virtual table of self
nitc :: MClass :: mparameters
Each generic formal parameters in order.nitc :: MClass :: mparameters=
Each generic formal parameters in order.nitc :: MClass :: overriden_mproperties
the set of redefition that do not call to supernitc :: MClass :: position_attributes
The position of the class' block in virtual table,nitc :: MClass :: position_attributes=
The position of the class' block in virtual table,nitc :: MClass :: position_methods
The position of the class' block in attribute tablenitc :: MClass :: position_methods=
The position of the class' block in attribute tablenitc :: MClass :: positions_attributes
For superclasses which have a non-invariant position, keep their position in attribute tablenitc :: MClass :: positions_attributes=
For superclasses which have a non-invariant position, keep their position in attribute tablenitc :: MClass :: positions_methods
For superclasses which have a non-invariant position, keep their position in virtual tablenitc :: MClass :: positions_methods=
For superclasses which have a non-invariant position, keep their position in virtual tablenitc :: MClass :: set_offsets
Set the offsets for the properties introduced byself
class
nitc :: MClass :: setup_parameter_names
Initializemparameters
from their names.
nitc :: MClass :: signature_to_s
A string version of the signature a generic class.nitc :: MClass :: superclasses_ordering
Order superclasses of selfnitc :: MClass :: the_root_init_mmethod
The base init of the class.nitc :: MClass :: the_root_init_mmethod=
The base init of the class.nitc :: MClass :: update_positions
Update the positions of this classnitc :: MClass :: visibility=
The visibility of the classnitc :: model_collect $ MClass :: collect_ancestors
Collect all ancestors ofself
nitc :: model_collect $ MClass :: collect_children
Collect all direct children ofself
nitc :: model_collect $ MClass :: collect_descendants
Collect all descendants ofself
nitc :: model_collect $ MClass :: collect_linearization
Collectself
linearization anchored on mainmodule
nitc :: api_metrics $ MClass :: collect_metrics
nitc :: model_collect $ MClass :: collect_modifiers
Collect modifier keywords likeredef
, private
etc
nitc :: model_collect $ MClass :: collect_parents
Collect all direct parents ofself
nitc :: json_model $ MClass :: core_serialize_to
Actual serialization ofself
to serializer
nitc :: term_model $ MClass :: cs_signature
Returnsself
signature formatted for console.
nitc :: html_model $ MClass :: css_classes
CSS classes used to decorateself
nitc :: html_model $ MClass :: html_namespace
Returnsfull_name
decorated with HTML links
nitc :: html_model $ MClass :: html_signature
Returns the MEntity signature decorated with HTMLnitc :: model_examples $ MClass :: is_example
Isself
existing for an example purpose?
nitc :: json_model $ MClass :: json_namespace
Returnself.full_name
as an object that can be serialized to json.
nitc $ MClass :: mdoc_or_fallback
The documentation associated to the entity or their main nested entity.nitc :: model_index $ MClass :: mentity_kind_rank
Compare MEntity class kindnitc :: commands_graph $ MClass :: to_dot_node
Returnself
as a DotNode
nitc :: MClass :: _abstract_loaded
Indicate this class was partially loaded (it only has its identifier allocated)nitc :: MEntity :: _const_color
nitc :: MEntity :: _css_classes
CSS classes used to decorateself
nitc :: MEntity :: _deprecation
Is the entity deprecated?nitc :: MClass :: _ftype_cache
nitc :: MClass :: _ftype_computed
nitc :: MClass :: _get_mtype_cache
nitc :: MClass :: _has_new_factory
Is there anew
factory to allow the pseudo instantiation?
nitc :: MEntity :: _html_full_name
The MEntityfull_name
escaped for HTML
nitc :: MClass :: _intro_mattributes
TheMAttribute
this class introduced
nitc :: MClass :: _intro_mmethods
TheMMethod
this class introduced
nitc :: MClass :: _intro_mmodule
The module that introduce the classnitc :: MEntity :: _is_broken
The indication that the entity did not pass some semantic verifications.nitc :: MClass :: _is_example
nitc :: MClass :: _mattributes
AllMAttribute
this class contains
nitc :: MClass :: _mclass_type
The principal static type of the class.nitc :: MClass :: _mclassdefs
All class definitions (introduction and refinements)nitc :: MClass :: _mparameters
Each generic formal parameters in order.nitc :: MClass :: _position_attributes
The position of the class' block in virtual table,nitc :: MClass :: _position_methods
The position of the class' block in attribute tablenitc :: MClass :: _positions_attributes
For superclasses which have a non-invariant position, keep their position in attribute tablenitc :: MClass :: _positions_methods
For superclasses which have a non-invariant position, keep their position in virtual tablenitc :: MClass :: _the_root_init_mmethod
The base init of the class.nitc :: MClass :: abstract_loaded
Indicate this class was partially loaded (it only has its identifier allocated)nitc :: MClass :: abstract_loaded=
Indicate this class was partially loaded (it only has its identifier allocated)serialization :: Serializable :: accept_inspect_serializer_core
serialization :: Serializable :: accept_json_serializer
Refinable service to customize the serialization of this class to JSONserialization :: Serializable :: accept_msgpack_attribute_counter
Hook to customize the behavior of theAttributeCounter
serialization :: Serializable :: accept_msgpack_serializer
Hook to customize the serialization of this class to MessagePacknitc :: MEntity :: add_doc_to_infobox
Append an entry for the doc in the given infoboxserialization :: Serializable :: add_to_bundle
Called by[]=
to dynamically choose the appropriate method according
nitc :: MClass :: allocate_vtable
Allocate a single vtablenitc :: MClass :: calculate_delta
Computes delta for each classcore :: Object :: class_factory
Implementation used byget_class
to create the specific class.
nitc :: MClass :: collect_accessible_inits
Collect all init methods accessible byself
nitc :: MClass :: collect_accessible_mattributes
Collect all attributes accessible byself
nitc :: MClass :: collect_accessible_mmethods
Collect all methods accessible byself
nitc :: MClass :: collect_accessible_mproperties
Collect all properties accessible byself
nitc :: MClass :: collect_accessible_vts
Collect all virtual types accessible byself
nitc :: MEntity :: collect_ancestors
Collectself
ancestors (direct and indirect)
nitc :: MEntity :: collect_children
Collectself
children (direct descendants)
nitc :: MEntity :: collect_descendants
Collectself
descendants (direct and direct)
nitc :: MClass :: collect_inherited_inits
Collect all init methods inherited byself
nitc :: MClass :: collect_inherited_mattributes
Collect all attributes inherited byself
nitc :: MClass :: collect_inherited_mmethods
Collect all methods inherited byself
nitc :: MClass :: collect_inherited_mproperties
Collect all properties inehrited byself
nitc :: MClass :: collect_inherited_vts
Collect all virtual types inherited byself
nitc :: MClass :: collect_intro_inits
Collect all init methods introduced inself
nitc :: MClass :: collect_intro_mattributes
Collect all attributes introduced inself
nitc :: MClass :: collect_intro_mmethods
Collect all methods introduced inself
nitc :: MClass :: collect_intro_mpropdefs
Collect all property definitions that are introductions inself
nitc :: MClass :: collect_intro_mproperties
Collect all properties introduced inself
nitc :: MClass :: collect_intro_vts
Collect all virtual types introduced inself
nitc :: MEntity :: collect_linearization
Collectself
linearization anchored on mainmodule
nitc :: MClass :: collect_local_inits
Collect all init methods introduced and redefined inself
nitc :: MClass :: collect_local_mattributes
Collect all attributes introduced and redefined inself
nitc :: MClass :: collect_local_mmethods
Collect all methods introduced and redefined inself
nitc :: MClass :: collect_local_mproperties
Collect all properties introduced and redefined inself
nitc :: MClass :: collect_local_vts
Collect all virtual types introduced or redefined inself
nitc :: MClass :: collect_mclassdefs
Collect all class definitions ofself
nitc :: MEntity :: collect_metrics
nitc :: MEntity :: collect_modifiers
Collect modifier keywords likeredef
, private
etc
nitc :: MEntity :: collect_parents
Collectself
parents (direct ancestors)
nitc :: MClass :: collect_redef_inits
Collect all init methods redefined inself
nitc :: MClass :: collect_redef_mattributes
Collect all attributes redefined inself
nitc :: MClass :: collect_redef_mmethods
Collect all methods redefined inself
nitc :: MClass :: collect_redef_mpropdefs
Collect all propierty definitions that are redefinition inself
nitc :: MClass :: collect_redef_mproperties
Collect all properties redefined inself
nitc :: MClass :: collect_redef_vts
Collect all virtual types redefined inself
nitc :: MClass :: compile_to_java
Generate a Java RTClass for a Nit MClassnitc :: MClass :: compile_type_table
Compile the type table for the MClassnitc :: MClass :: compile_vft
Compile the virtual function table for the mclassnitc :: MClass :: compute_ftype
Type in C of the extern classnitc :: MClass :: compute_identifier
Allocate a unique identifier to the class with perfect hashingnitc :: MEntity :: const_color
nitc :: MEntity :: const_color=
nitc :: MEntity :: core_serialize_base
serialization :: Serializable :: core_serialize_to
Actual serialization ofself
to serializer
nitc :: MClass :: create_abstract_method
This method create an abstract method representation with this MMethodDef an this AMethoddefnitc :: MEntity :: create_ast_representation
Build a ANode fromself
nitc :: MClass :: create_empty_method
Create method with an empty blocknitc :: MEntity :: cs_comment
Returns the comment of this MEntity formatted for console.nitc :: MEntity :: cs_declaration
Returns the complete MEntity declaration (modifiers + name + signature).nitc :: MEntity :: cs_full_name
Returnsself.full_name
formatted for console
nitc :: MEntity :: cs_list_item
Returnsself
as a list element that can be displayed in console.
nitc :: MEntity :: cs_location
Source code location of this MEntity formatted for consolenitc :: MEntity :: cs_short_comment
Returns the comment of this MEntity formatted for console.nitc :: MEntity :: cs_signature
Returnsself
signature formatted for console.
nitc :: MEntity :: cs_source_code
Source code associated to this MEntity.nitc :: MEntity :: css_classes=
CSS classes used to decorateself
nitc :: MEntity :: defaultinit
core :: Object :: defaultinit
nitc :: MClass :: defaultinit
nitc :: HInfoBoxable :: defaultinit
nitc :: MEntity :: deprecation=
Is the entity deprecated?nitc :: MClass :: extended_mproperties
the set of redefition that call to supernitc :: MEntity :: field_separator
nitc :: MClass :: fill_vtable
Fill the vtable with local methods forself
class
serialization :: Serializable :: from_deserializer
Create an instance of this class from thedeserializer
nitc :: MClass :: ftype_cache
nitc :: MClass :: ftype_cache=
nitc :: MClass :: ftype_computed
nitc :: MClass :: ftype_computed=
nitc :: MClass :: full_name=
The canonical name of the classnitc :: MClass :: get_mtype_cache
nitc :: MClass :: get_mtype_cache=
nitc :: MClass :: get_position_attributes
Return the position of the attribute's block of classcl
in self
if cl
has an invariant position in self,
nitc :: MClass :: get_position_methods
Return the position of the method's block of classcl
in self
if cl
has an invariant position in self,
nitc :: MClass :: has_new_factory
Is there anew
factory to allow the pseudo instantiation?
nitc :: MClass :: has_new_factory=
Is there anew
factory to allow the pseudo instantiation?
nitc :: MEntity :: hierarchy_poset
Build a poset representingself
in it's own hierarchy
nitc :: MEntity :: html_declaration
Returns the complete MEntity declaration decorated with HTMLnitc :: MEntity :: html_full_name=
The MEntityfull_name
escaped for HTML
nitc :: MEntity :: html_name=
The MEntity name escaped for HTMLnitc :: MEntity :: html_namespace
Returnsfull_name
decorated with HTML links
nitc :: MEntity :: html_signature
Returns the MEntity signature decorated with HTMLnitc :: MClass :: in_hierarchy
Return the classself
in the class hierarchy of the module mmodule
.
nitc :: HInfoBoxable :: infobox
An new infobox documenting the entitynitc :: MClass :: intro_mattributes
TheMAttribute
this class introduced
nitc :: MClass :: intro_mattributes=
TheMAttribute
this class introduced
nitc :: MClass :: intro_mmethods
TheMMethod
this class introduced
nitc :: MClass :: intro_mmethods=
TheMMethod
this class introduced
nitc :: MClass :: intro_mmodule=
The module that introduce the classnitc :: MClass :: is_abstract=
Isself
and abstract class?
nitc :: MEntity :: is_broken=
The indication that the entity did not pass some semantic verifications.nitc :: MClass :: is_example=
nitc :: MClass :: is_extender
extenders contain more introduction than redefinitionsnitc :: MEntity :: is_fictive=
Isself
created for internal purpose?
nitc :: MClass :: is_interface=
Isself
an interface kind?
nitc :: MClass :: is_overrider
overriders contain more definitions than introductionsnitc :: MClass :: is_pure_extender
pure extenders contain only introductionsnitc :: MClass :: is_pure_overrider
pure overriders contain only redefinitionsnitc :: MClass :: is_pure_replacer
pure replacers never call to super in its redefinitionsnitc :: MClass :: is_pure_specializer
pure specializers always call to super in its redefinitionsnitc :: MClass :: is_replacer
replacers have less redefinitions that call super than not calling itcore :: Object :: is_same_instance
Return true ifself
and other
are the same instance (i.e. same identity).
core :: Object :: is_same_serialized
Isself
the same as other
in a serialization context?
core :: Object :: is_same_type
Return true ifself
and other
have the same dynamic type.
nitc :: MClass :: is_specializer
specializers have more redefinitions that call super than not calling itnitc :: MEntity :: json_namespace
Returnself.full_name
as an object that can be serialized to json.
nitc :: MEntity :: line_separator
nitc :: MEntity :: linkto_text
Link to theself
with a specific text.
nitc :: MClass :: mattributes=
AllMAttribute
this class contains
nitc :: MClass :: mclass_type=
The principal static type of the class.nitc :: MClass :: mclassdefs
All class definitions (introduction and refinements)nitc :: MClass :: mclassdefs=
All class definitions (introduction and refinements)nitc :: MEntity :: mdoc_or_fallback
The documentation associated to the entity or their main nested entity.nitc :: MClass :: moved_class_attributes
This method is called whencurrent_class
class is moved in attribute table of self
nitc :: MClass :: moved_class_methods
This method is called whencurrent_class
class is moved in virtual table of self
nitc :: MClass :: mparameters
Each generic formal parameters in order.nitc :: MClass :: mparameters=
Each generic formal parameters in order.serialization :: Serializable :: msgpack_extra_array_items
Hook to request a larger than usual metadata arraycore :: Object :: native_class_name
The class name of the object in CString format.core :: Object :: output_class_name
Display class name on stdout (debug only).nitc :: MClass :: overriden_mproperties
the set of redefition that do not call to supernitc :: MClass :: position_attributes
The position of the class' block in virtual table,nitc :: MClass :: position_attributes=
The position of the class' block in virtual table,nitc :: MClass :: position_methods
The position of the class' block in attribute tablenitc :: MClass :: position_methods=
The position of the class' block in attribute tablenitc :: MClass :: positions_attributes
For superclasses which have a non-invariant position, keep their position in attribute tablenitc :: MClass :: positions_attributes=
For superclasses which have a non-invariant position, keep their position in attribute tablenitc :: MClass :: positions_methods
For superclasses which have a non-invariant position, keep their position in virtual tablenitc :: MClass :: positions_methods=
For superclasses which have a non-invariant position, keep their position in virtual tablementity
nitc :: MEntity :: ratings_by_dimension
Get the ratings of adimension
serialization :: Serializable :: serialize_msgpack
Serializeself
to MessagePack bytes
serialization :: Serializable :: serialize_to
Serializeself
to serializer
serialization :: Serializable :: serialize_to_json
Serializeself
to JSON
serialization :: Serializable :: serialize_to_or_delay
Accept references or force direct serialization (usingserialize_to
)
nitc :: MClass :: set_offsets
Set the offsets for the properties introduced byself
class
nitc :: MClass :: setup_parameter_names
Initializemparameters
from their names.
nitc :: MClass :: signature_to_s
A string version of the signature a generic class.nitc :: MEntity :: source_url
Render a HTML link for the MEntity locationnitc :: MClass :: superclasses_ordering
Order superclasses of selfnitc :: MClass :: the_root_init_mmethod
The base init of the class.nitc :: MClass :: the_root_init_mmethod=
The base init of the class.serialization :: Serializable :: to_pretty_json
Serializeself
to plain pretty JSON
nitc :: MEntity :: tpl_module
Builds a dot UML package diagram entity fromself
nitc :: MClass :: update_positions
Update the positions of this classnitc :: MClass :: visibility=
The visibility of the classv.enter_visit
on all nested entities.
nitc :: MEntity :: write_extra_doc
Extra auto documentation to append to thestream
nitc :: MEntity :: write_location
Location (file and line when available) of related declarationsSerializer::serialize
# A named class
#
# `MClass`es are global to the model; it means that a `MClass` is not bound
# to a specific `MModule`.
#
# This characteristic helps the reasoning about classes in a program since a
# single `MClass` object always denote the same class.
#
# The drawback is that classes (`MClass`) contain almost nothing by themselves.
# These do not really have properties nor belong to a hierarchy since the property and the
# hierarchy of a class depends of the refinement in the modules.
#
# Most services on classes require the precision of a module, and no one can asks what are
# the super-classes of a class nor what are properties of a class without precising what is
# the module considered.
#
# For instance, during the typing of a source-file, the module considered is the module of the file.
# eg. the question *is the method `foo` exists in the class `Bar`?* must be reformulated into
# *is the method `foo` exists in the class `Bar` in the current module?*
#
# During some global analysis, the module considered may be the main module of the program.
class MClass
super MEntity
# The module that introduce the class
#
# While classes are not bound to a specific module,
# the introducing module is used for naming and visibility.
var intro_mmodule: MModule
# The short name of the class
# In Nit, the name of a class cannot evolve in refinements
redef var name
redef var location
# The canonical name of the class
#
# It is the name of the class prefixed by the full_name of the `intro_mmodule`
# Example: `"owner::module::MyClass"`
redef var full_name is lazy do
return "{self.intro_mmodule.namespace_for(visibility)}::{name}"
end
redef var c_name is lazy do
return "{intro_mmodule.c_namespace_for(visibility)}__{name.to_cmangle}"
end
# The number of generic formal parameters
# 0 if the class is not generic
var arity: Int is noinit
# Each generic formal parameters in order.
# is empty if the class is not generic
var mparameters = new Array[MParameterType]
# A string version of the signature a generic class.
#
# eg. `Map[K: nullable Object, V: nullable Object]`
#
# If the class in non generic the name is just given.
#
# eg. `Object`
fun signature_to_s: String
do
if arity == 0 then return name
var res = new FlatBuffer
res.append name
res.append "["
for i in [0..arity[ do
if i > 0 then res.append ", "
res.append mparameters[i].name
res.append ": "
res.append intro.bound_mtype.arguments[i].to_s
end
res.append "]"
return res.to_s
end
# Initialize `mparameters` from their names.
protected fun setup_parameter_names(parameter_names: nullable Array[String]) is
autoinit
do
if parameter_names == null then
self.arity = 0
else
self.arity = parameter_names.length
end
# Create the formal parameter types
if arity > 0 then
assert parameter_names != null
var mparametertypes = new Array[MParameterType]
for i in [0..arity[ do
var mparametertype = new MParameterType(self, i, parameter_names[i])
mparametertypes.add(mparametertype)
end
self.mparameters = mparametertypes
var mclass_type = new MGenericType(self, mparametertypes)
self.mclass_type = mclass_type
self.get_mtype_cache[mparametertypes] = mclass_type
else
self.mclass_type = new MClassType(self)
end
end
# The kind of the class (interface, abstract class, etc.)
#
# In Nit, the kind of a class cannot evolve in refinements.
var kind: MClassKind
# The visibility of the class
#
# In Nit, the visibility of a class cannot evolve in refinements.
redef var visibility
init
do
intro_mmodule.intro_mclasses.add(self)
var model = intro_mmodule.model
model.mclasses_by_name.add_one(name, self)
model.mclasses.add(self)
end
redef fun model do return intro_mmodule.model
# All class definitions (introduction and refinements)
var mclassdefs = new Array[MClassDef]
# Alias for `name`
redef fun to_s do return self.name
# The definition that introduces the class.
#
# Warning: such a definition may not exist in the early life of the object.
# In this case, the method will abort.
#
# Use `try_intro` instead.
var intro: MClassDef is noinit
# The definition that introduces the class or `null` if not yet known.
#
# SEE: `intro`
fun try_intro: nullable MClassDef do
if isset _intro then return _intro else return null
end
# Return the class `self` in the class hierarchy of the module `mmodule`.
#
# SEE: `MModule::flatten_mclass_hierarchy`
# REQUIRE: `mmodule.has_mclass(self)`
fun in_hierarchy(mmodule: MModule): POSetElement[MClass]
do
return mmodule.flatten_mclass_hierarchy[self]
end
# The principal static type of the class.
#
# For non-generic class, `mclass_type` is the only `MClassType` based
# on self.
#
# For a generic class, the arguments are the formal parameters.
# i.e.: for the class `Array[E:Object]`, the `mclass_type` is `Array[E]`.
# If you want `Array[Object]`, see `MClassDef::bound_mtype`.
#
# For generic classes, the mclass_type is also the way to get a formal
# generic parameter type.
#
# To get other types based on a generic class, see `get_mtype`.
#
# ENSURE: `mclass_type.mclass == self`
var mclass_type: MClassType is noinit
# Return a generic type based on the class
# Is the class is not generic, then the result is `mclass_type`
#
# REQUIRE: `mtype_arguments.length == self.arity`
fun get_mtype(mtype_arguments: Array[MType]): MClassType
do
assert mtype_arguments.length == self.arity
if self.arity == 0 then return self.mclass_type
var res = get_mtype_cache.get_or_null(mtype_arguments)
if res != null then return res
res = new MGenericType(self, mtype_arguments)
self.get_mtype_cache[mtype_arguments.to_a] = res
return res
end
private var get_mtype_cache = new HashMap[Array[MType], MGenericType]
# Is there a `new` factory to allow the pseudo instantiation?
var has_new_factory = false is writable
# Is `self` a standard or abstract class kind?
var is_class: Bool is lazy do return kind == concrete_kind or kind == abstract_kind
# Is `self` an interface kind?
var is_interface: Bool is lazy do return kind == interface_kind
# Is `self` an enum kind?
var is_enum: Bool is lazy do return kind == enum_kind
# Is `self` and abstract class?
var is_abstract: Bool is lazy do return kind == abstract_kind
redef var is_test is lazy do return intro.is_test
redef fun mdoc_or_fallback
do
# Don’t use `intro.mdoc_or_fallback` because it would create an infinite
# recursion.
return intro.mdoc
end
end
src/model/model.nit:412,1--625,3
redef class MClass
# The base init of the class.
#
# TODO: merge with `root_init` and `ModelBuilder::the_root_init_mmethod` if possible
var the_root_init_mmethod: nullable MMethod = null
end
src/modelize/modelize_property.nit:522,1--527,3
redef class MClass
redef var is_example is lazy do return intro.is_example
redef fun examples do
var res = super
for mclassdef in mclassdefs do
for example in mclassdef.examples do
if not res.has(example) then res.add example
end
end
return res
end
end
src/model/model_examples.nit:91,1--103,3
redef class MClass
redef fun to_node(nodes: HashMap[MEntity, NeoNode], model_name: nullable String): NeoNode do
if nodes.has_key(self) then return nodes[self]
var node = super
node["kind"] = kind.to_s
node["visibility"] = visibility.to_s
if not mparameters.is_empty then
var parameter_names = new Array[String]
for p in mparameters do parameter_names.add(p.name)
node["parameter_names"] = new JsonArray.from(parameter_names)
end
node.out_edges.add(new NeoEdge(node, "CLASSTYPE", mclass_type.to_node(nodes, model_name)))
return node
end
end
src/neo.nit:733,1--747,3
redef class MClass
# A reference to the virtual table of this class
var vtable: nullable VTable
# True when the class is effectively loaded by the vm, false otherwise
var loaded: Bool = false
# Indicate this class was partially loaded (it only has its identifier allocated)
var abstract_loaded: Bool = false
# Color for Cohen subtyping test : the absolute position of the id
# of this class in virtual tables
var color: Int
# For superclasses which have a non-invariant position, keep their position in attribute table
var positions_attributes: HashMap[MClass, Int] = new HashMap[MClass, Int]
# For superclasses which have a non-invariant position, keep their position in virtual table
var positions_methods: HashMap[MClass, Int] = new HashMap[MClass, Int]
# The position of the class' block in virtual table,
# the position is set to -1 when the invariant position is no longer satisfied
var position_attributes: Int
# The position of the class' block in attribute table
# the position is set to -1 when the invariant position is no longer satisfied
var position_methods: Int
# The chosen prefix for this class.
# The prefix is the direct superclass which has the most properties,
# this class will stay at its usual position in virtual table and attribute table
var prefix: nullable MClass
# The linear extension of all superclasses with the prefix rule
var ordering: Array[MClass]
# The `MAttribute` this class introduced
var intro_mattributes = new Array[MAttribute]
# The `MMethod` this class introduced
var intro_mmethods = new Array[MMethod]
# All `MAttribute` this class contains
var mattributes = new Array[MAttribute]
# All `MMethod` this class contains
var mmethods = new Array[MMethod]
# Allocates a VTable for this class and gives it an id
# * `vm` The currently executed VirtualMachine
# * `explicit` Indicate if this class was directly instantiated (i.e. not indirectly loaded)
private fun make_vt(vm: VirtualMachine, explicit: Bool)
do
# `ordering` contains the order of superclasses for virtual tables
ordering = superclasses_ordering(vm)
ordering.remove(self)
var ids = new Array[Int]
var nb_methods = new Array[Int]
var nb_attributes = new Array[Int]
# Absolute offset of attribute from the beginning of the attributes table
var offset_attributes = 0
# Absolute offset of method from the beginning of the methods table,
# is initialize to 3 because the first position is empty in the virtual table
# and the second and third are respectively class id and delta
var offset_methods = 3
var parent
var prefix_index = ordering.index_of(prefix.as(not null))
for i in [0..ordering.length[ do
parent = ordering[i]
# Get the number of introduced methods and attributes for this class
var methods = parent.intro_mmethods.length
var attributes = parent.intro_mattributes.length
# Updates `mmethods` and `mattributes`
mmethods.add_all(parent.intro_mmethods)
mattributes.add_all(parent.intro_mattributes)
ids.push(parent.vtable.id)
nb_methods.push(methods)
nb_attributes.push(attributes)
# If the class is in the suffix part of the order
if i > prefix_index then
moved_class_attributes(vm, ordering[i], offset_attributes)
moved_class_methods(vm, ordering[i], offset_methods)
end
offset_attributes += attributes
offset_methods += methods
offset_methods += 2 # Because each block starts with an id and the delta
end
# Update the positions of the class
update_positions(offset_attributes, offset_methods)
ordering.add(self)
# Compute the identifier with Perfect Hashing
compute_identifier(vm, ids, offset_methods)
# Update caches and offsets of methods and attributes for this class
# If the loading was explicit, the virtual table will be allocated and filled
set_offsets(vm, explicit)
if not explicit then
# Just init the C-pointer to NULL to avoid errors
vtable.internal_vtable = vm.memory_manager.null_ptr
end
end
# Allocate a unique identifier to the class with perfect hashing
# * `vm` The currently executed VirtualMachine
# * `ids` Array of superclasses identifiers
# * `offset_methods : Offset from the beginning of the table of the group of methods
private fun compute_identifier(vm: VirtualMachine, ids: Array[Int], offset_methods: Int)
do
vtable = new VTable
var idc = new Array[Int]
# Give an identifier to the class and put it inside the virtual table
vtable.mask = vm.ph.pnand(ids, 1, idc) - 1
vtable.id = idc[0]
vtable.classname = name
# Set the color for subtyping tests in SST of this class
color = offset_methods - 2
# Indicate the class has its identifier computed
abstract_loaded = true
end
# Update the positions of this class
# * `offset_attributes` The offset of the block of attributes of this class
# * `offset_methods` The offset of the block of methods of this class
private fun update_positions(offset_attributes: Int, offset_methods: Int)
do
# Recopy the position tables of the prefix in `self`
for key, value in prefix.positions_methods do
positions_methods[key] = value
end
for key, value in prefix.positions_attributes do
positions_attributes[key] = value
end
# Save the offsets of self class
position_attributes = offset_attributes
position_methods = offset_methods
end
# Set the offsets for the properties introduced by `self` class
# * `vm` The currently executed VirtualMachine
# * `explicit` Indicate if this class was explicitly loaded
private fun set_offsets(vm: VirtualMachine, explicit: Bool)
do
# Fixing offsets for self attributes and methods
var relative_offset_attr = 0
var relative_offset_meth = 0
# Update `intro_mmethods` and `intro_mattributes`
# For each MClassdef this MClass has
for classdef in mclassdefs do
# For each property this MClassdef introduce
for p in classdef.intro_mproperties do
# Collect properties and fixing offsets
if p isa MMethod then
p.offset = relative_offset_meth
relative_offset_meth += 1
intro_mmethods.add(p)
end
if p isa MAttribute then
p.offset = relative_offset_attr
relative_offset_attr += 1
intro_mattributes.add(p)
end
end
end
# Updates caches with introduced attributes of `self` class
mattributes.add_all(intro_mattributes)
mmethods.add_all(intro_mmethods)
if explicit then allocate_vtable(vm)
end
# Allocate a single vtable
# * `vm` The currently executed VirtualMachine
private fun allocate_vtable(vm: VirtualMachine)
do
var ids = new Array[Int]
var nb_methods_total = new Array[Int]
var nb_attributes_total = new Array[Int]
for cl in ordering do
ids.add(cl.vtable.id)
nb_methods_total.add(cl.intro_mmethods.length)
nb_attributes_total.add(cl.intro_mattributes.length)
end
# Calculate the delta to prepare object structure
var deltas = calculate_delta(nb_attributes_total)
vtable.internal_vtable = vm.memory_manager.init_vtable(ids, nb_methods_total, deltas, vtable.mask)
# The virtual table now needs to be filled with pointer to methods
for cl in ordering do
fill_vtable(vm, vtable.as(not null), cl)
end
loaded = true
end
# Fill the vtable with local methods for `self` class
# * `vm` Current instance of the VirtualMachine
# * `table` the table of self class, will be filled with its methods
# * `cl` The class which introduced the methods
private fun fill_vtable(vm: VirtualMachine, table: VTable, cl: MClass)
do
var methods = new Array[MMethodDef]
for m in cl.intro_mmethods do
# `propdef` is the most specific implementation for this MMethod
var propdef = m.lookup_first_definition(vm.mainmodule, self.intro.bound_mtype)
methods.push(propdef)
end
# Call a method in C to put propdefs of self methods in the vtables
vm.memory_manager.put_methods(vtable.internal_vtable, vtable.mask, cl.vtable.id, methods)
end
# Computes delta for each class
# A delta represents the offset for this group of attributes in the object
# *`nb_attributes` : number of attributes for each class (classes are linearized from Object to current)
# * return deltas for each class
private fun calculate_delta(nb_attributes: Array[Int]): Array[Int]
do
var deltas = new Array[Int]
var total = 0
for nb in nb_attributes do
deltas.push(total)
total += nb
end
return deltas
end
# Order superclasses of self
# Return the order of superclasses in runtime structures of this class
private fun superclasses_ordering(v: VirtualMachine): Array[MClass]
do
var superclasses = new Array[MClass]
# Add all superclasses of `self`
superclasses.add_all(self.in_hierarchy(v.mainmodule).greaters)
var res = new Array[MClass]
if superclasses.length > 1 then
# Starting at self
var ordering = self.dfs(v, res)
return ordering
else
# There is no super-class, self is Object
prefix = self
return superclasses
end
end
# A kind of Depth-First-Search for superclasses ordering
# *`v` : the current executed instance of VirtualMachine
# * `res` : Result Array, ie current superclasses ordering
private fun dfs(v: VirtualMachine, res: Array[MClass]): Array[MClass]
do
# Add this class at the beginning
res.insert(self, 0)
var direct_parents = self.in_hierarchy(v.mainmodule).direct_greaters.to_a
if direct_parents.length > 1 then
# Prefix represents the class which has the most properties
# we try to choose it in first to reduce the number of potential recompilations
var prefix = null
var max = -1
for cl in direct_parents do
# If we never have visited this class
if not res.has(cl) then
var properties_length = cl.mmethods.length + cl.mattributes.length
if properties_length > max then
max = properties_length
prefix = cl
end
end
end
if prefix != null then
if self.prefix == null then self.prefix = prefix
# Add the prefix class ordering at the beginning of our sequence
var prefix_res = new Array[MClass]
prefix_res = prefix.dfs(v, prefix_res)
# Then we recurse on other classes
for cl in direct_parents do
if cl != prefix then
res = new Array[MClass]
res = cl.dfs(v, res)
for cl_res in res do
if not prefix_res.has(cl_res) then prefix_res.push(cl_res)
end
end
end
res = prefix_res
end
res.push(self)
else
if direct_parents.length > 0 then
if prefix == null then prefix = direct_parents.first
res = direct_parents.first.dfs(v, res)
end
end
if not res.has(self) then res.push(self)
return res
end
# This method is called when `current_class` class is moved in virtual table of `self`
# *`vm` Running instance of the virtual machine
# *`current_class` The class which was moved in `self` structures
# *`offset` The offset of block of methods of `current_class` in `self`
fun moved_class_methods(vm: VirtualMachine, current_class: MClass, offset: Int)
do
# `current_class` was moved in `self` method table
if current_class.position_methods > 0 then
# The invariant position is no longer satisfied
current_class.positions_methods[current_class] = current_class.position_methods
current_class.position_methods = - current_class.position_methods
else
# The class has already several positions and an update is needed
current_class.positions_methods[current_class] = -current_class.positions_methods[current_class]
for sub in ordering do
if sub == current_class then continue
var super_id = current_class.vtable.id
var mask = sub.vtable.mask
vm.load_class(sub)
if vm.inter_is_subtype_ph(super_id, mask, sub.vtable.internal_vtable) then
if not sub.positions_methods.has_key(current_class) then
sub.positions_methods[current_class] = current_class.position_methods
else
var old_position = sub.positions_methods[current_class]
if old_position > 0 then
# Indicate this class can not used anymore single inheritance implementation
sub.positions_methods[current_class] = - old_position
end
end
end
end
end
# Save the position of `current_class` in `self`
positions_methods[current_class] = offset
end
# This method is called when `current_class` class is moved in attribute table of `self`
# *`vm` Running instance of the virtual machine
# *`current_class` The class which was moved in `self` structures
# *`offset` The offset of block of attributes of `current_class` in `self`
fun moved_class_attributes(vm: VirtualMachine, current_class: MClass, offset: Int)
do
# `current_class` was moved in `self` attribute table
if not current_class.positions_attributes.has_key(current_class) then
# The invariant position is no longer satisfied
current_class.positions_attributes[current_class] = current_class.position_attributes
current_class.position_attributes = - current_class.position_attributes
else
# The class has already several positions and an update is needed
current_class.positions_attributes[current_class] = - current_class.positions_attributes[current_class]
for sub in ordering do
if sub == current_class then continue
var super_id = current_class.vtable.id
var mask = sub.vtable.mask
vm.load_class(sub)
if vm.inter_is_subtype_ph(super_id, mask, sub.vtable.internal_vtable) then
if not sub.positions_methods.has_key(current_class) then
sub.positions_attributes[current_class] = current_class.position_attributes
else
var old_position = sub.positions_attributes[current_class]
if old_position > 0 then
# Indicate this class can not used anymore single inheritance implementation
sub.positions_attributes[current_class] = - old_position
end
end
end
end
end
# Save the position of `current_class` in `self`
positions_attributes[current_class] = offset
end
# Return the position of the method's block of class `cl` in `self` if `cl` has an invariant position in self,
# Otherwise return a negative position
fun get_position_methods(cl: MClass): Int
do
# The class has an invariant position in all subclasses
if cl.position_methods > 0 then return cl.position_methods
# The position has an invariant position for this class and its subclasses only
if positions_methods.has_key(cl) then
var pos = positions_methods[cl]
if pos > 0 then return pos
return -1
end
# No invariant position at all, the caller must use a multiple inheritance implementation
return -1
end
# Return the position of the attribute's block of class `cl` in `self` if `cl` has an invariant position in self,
# Otherwise return a negative position
fun get_position_attributes(cl: MClass): Int
do
# The class has an invariant position in all subclasses
if cl.position_attributes > 0 then return cl.position_attributes
# The position has an invariant position for this class and its subclasses only
if positions_attributes.has_key(cl) then
var pos = positions_attributes[cl]
if pos > 0 then return pos
return -1
end
# No invariant position at all, the caller must use a multiple inheritance implementation
return -1
end
end
src/vm/virtual_machine.nit:408,1--858,3
redef class MClass
private var ftype_cache: nullable ForeignType = null
private var ftype_computed = false
# Extern type associated to this class according to specialisation
fun ftype: nullable ForeignType do return ftype_cache
redef fun ctype do return ftype_cache.ctype
# Type in C of the extern class
# If not defined in the intro of this class will look in super-classes
# FIXME this only supports type definition at intro, extend to superclasses by redef
private fun compute_ftype(v: ExternClassesTypingPhaseModel): nullable ForeignType
do
if ftype_computed then return ftype_cache
if kind != extern_kind then return null
# base case
if name == "Pointer" then
ftype_cache = new ForeignType
ftype_computed = true
return ftype_cache
end
var ftype = intro.ftype
if ftype == null then
var ftype_b: nullable ForeignType = null # FIXME hack to circumvent bug where ftype is typed null
# look in super classes
for s in in_hierarchy(intro_mmodule).direct_greaters do
var super_ftype = s.compute_ftype(v)
if super_ftype != null then
if ftype_b == null then
ftype_b = super_ftype
continue
else
# detect conflict
if super_ftype != ftype_b then
v.toolcontext.error(null, "FFI Error: extern type conflict in `{self}`.")
return null
end
end
end
end
ftype = ftype_b
end
ftype_cache = ftype
ftype_computed = true
return ftype
end
end
src/ffi/extern_classes.nit:84,1--136,3
redef class MClass
# This method create an abstract method representation with this MMethodDef an this AMethoddef
private fun create_abstract_method(v: ContractsVisitor, mproperty: MMethod, mclassdef: MClassDef, msignature: nullable MSignature, n_signature: ASignature): AMethPropdef
do
# new methoddef definition
var m_def = new MMethodDef(mclassdef, mproperty, v.current_location)
# set the signature
if msignature != null then m_def.msignature = msignature.clone
# set the abstract flag
m_def.is_abstract = true
# Build the new node method
var n_def = v.ast_builder.make_method(null,null,m_def,n_signature,null,null,null,null)
# Define the location of the new method for corresponding of the actual method
n_def.location = v.current_location
# Association new npropdef to mpropdef
v.toolcontext.modelbuilder.unsafe_add_mpropdef2npropdef(m_def,n_def)
return n_def
end
# Create method with an empty block
# the `mproperty` i.e the global property definition. The mclassdef to set where the method is declared and it's model `msignature` and ast `n_signature` signature
private fun create_empty_method(v: ContractsVisitor, mproperty: MMethod, mclassdef: MClassDef, msignature: nullable MSignature, n_signature: ASignature): AMethPropdef
do
var n_def = create_abstract_method(v, mproperty, mclassdef, msignature, n_signature)
n_def.mpropdef.is_abstract = false
n_def.n_block = v.ast_builder.make_block
return n_def
end
end
src/contracts.nit:576,1--605,3
redef class MClass
redef fun collect_modifiers do return intro.collect_modifiers
redef fun collect_linearization(mainmodule) do
var mclassdefs = self.mclassdefs.to_a
mainmodule.linearize_mclassdefs(mclassdefs)
return mclassdefs
end
# Collect all ancestors of `self`
redef fun collect_ancestors(mainmodule, filter) do
var res = new HashSet[MENTITY]
if not mainmodule.flatten_mclass_hierarchy.has(self) then return res
for mclass in in_hierarchy(mainmodule).greaters do
if mclass == self then continue
if filter == null or filter.accept_mentity(mclass) then res.add mclass
end
return res
end
# Collect all direct parents of `self`
redef fun collect_parents(mainmodule, filter) do
var res = new HashSet[MENTITY]
if not mainmodule.flatten_mclass_hierarchy.has(self) then return res
for mclass in in_hierarchy(mainmodule).direct_greaters do
if mclass == self then continue
if filter == null or filter.accept_mentity(mclass) then res.add mclass
end
return res
end
# Collect all direct children of `self`
redef fun collect_children(mainmodule, filter) do
var res = new HashSet[MENTITY]
if not mainmodule.flatten_mclass_hierarchy.has(self) then return res
for mclass in in_hierarchy(mainmodule).direct_smallers do
if mclass == self then continue
if filter == null or filter.accept_mentity(mclass) then res.add mclass
end
return res
end
# Collect all descendants of `self`
redef fun collect_descendants(mainmodule, filter) do
var res = new HashSet[MENTITY]
if not mainmodule.flatten_mclass_hierarchy.has(self) then return res
for mclass in in_hierarchy(mainmodule).smallers do
if mclass == self then continue
if filter == null or filter.accept_mentity(mclass) then res.add mclass
end
return res
end
# Collect all class definitions of `self`
fun collect_mclassdefs(filter: nullable ModelFilter): Set[MClassDef] do
var res = new HashSet[MClassDef]
for mclassdef in mclassdefs do
if filter == null or filter.accept_mentity(mclassdef) then res.add mclassdef
end
return res
end
# Collect all property definitions that are introductions in `self`
fun collect_intro_mpropdefs(filter: nullable ModelFilter): Set[MPropDef] do
var set = new HashSet[MPropDef]
for mclassdef in mclassdefs do
for mpropdef in mclassdef.mpropdefs do
if not mpropdef.is_intro then continue
if filter == null or filter.accept_mentity(mpropdef) then set.add(mpropdef)
end
end
return set
end
# Collect all properties introduced in `self`
fun collect_intro_mproperties(filter: nullable ModelFilter): Set[MProperty] do
var set = new HashSet[MProperty]
for mclassdef in mclassdefs do
for mprop in mclassdef.intro_mproperties do
if filter == null or filter.accept_mentity(mprop) then set.add(mprop)
end
end
return set
end
# Collect all propierty definitions that are redefinition in `self`
fun collect_redef_mpropdefs(filter: nullable ModelFilter): Set[MPropDef] do
var set = new HashSet[MPropDef]
for mclassdef in mclassdefs do
for mpropdef in mclassdef.mpropdefs do
if mpropdef.is_intro then continue
if filter == null or filter.accept_mentity(mpropdef) then set.add(mpropdef)
end
end
return set
end
# Collect all properties redefined in `self`
fun collect_redef_mproperties(filter: nullable ModelFilter): Set[MProperty] do
var set = new HashSet[MProperty]
for mclassdef in mclassdefs do
for mpropdef in mclassdef.mpropdefs do
if mpropdef.mproperty.intro_mclassdef.mclass == self then continue
if filter == null or filter.accept_mentity(mpropdef) then
set.add(mpropdef.mproperty)
end
end
end
return set
end
# Collect all properties introduced and redefined in `self`
fun collect_local_mproperties(filter: nullable ModelFilter): Set[MProperty] do
var set = new HashSet[MProperty]
set.add_all collect_intro_mproperties(filter)
set.add_all collect_redef_mproperties(filter)
return set
end
# Collect all properties inehrited by `self`
fun collect_inherited_mproperties(mainmodule: MModule, filter: nullable ModelFilter): Set[MProperty] do
var set = new HashSet[MProperty]
for parent in collect_parents(mainmodule, filter) do
set.add_all(parent.collect_intro_mproperties(filter))
set.add_all(parent.collect_inherited_mproperties(mainmodule, filter))
end
return set
end
# Collect all properties accessible by `self`
#
# This include introduced, redefined, inherited properties.
fun collect_accessible_mproperties(mainmodule: MModule, filter: nullable ModelFilter): Set[MProperty] do
var set = new HashSet[MProperty]
set.add_all(collect_intro_mproperties(filter))
set.add_all(collect_redef_mproperties(filter))
set.add_all(collect_inherited_mproperties(mainmodule, filter))
return set
end
# Collect all methods introduced in `self`
fun collect_intro_mmethods(filter: nullable ModelFilter): Set[MMethod] do
var res = new HashSet[MMethod]
for mproperty in collect_intro_mproperties(filter) do
if mproperty isa MMethod then res.add(mproperty)
end
return res
end
# Collect all methods redefined in `self`
fun collect_redef_mmethods(filter: nullable ModelFilter): Set[MMethod] do
var res = new HashSet[MMethod]
for mproperty in collect_redef_mproperties(filter) do
if mproperty isa MMethod then res.add(mproperty)
end
return res
end
# Collect all methods introduced and redefined in `self`
fun collect_local_mmethods(filter: nullable ModelFilter): Set[MMethod] do
var set = new HashSet[MMethod]
set.add_all collect_intro_mmethods(filter)
set.add_all collect_redef_mmethods(filter)
return set
end
# Collect all methods inherited by `self`
fun collect_inherited_mmethods(mainmodule: MModule, filter: nullable ModelFilter): Set[MMethod] do
var res = new HashSet[MMethod]
for mproperty in collect_inherited_mproperties(mainmodule, filter) do
if mproperty isa MMethod then res.add(mproperty)
end
return res
end
# Collect all methods accessible by `self`
#
# This include introduced, redefined, inherited methods.
fun collect_accessible_mmethods(mainmodule: MModule, filter: nullable ModelFilter): Set[MMethod] do
var set = new HashSet[MMethod]
set.add_all(collect_intro_mmethods(filter))
set.add_all(collect_redef_mmethods(filter))
set.add_all(collect_inherited_mmethods(mainmodule, filter))
return set
end
# Collect all attributes introduced in `self`
fun collect_intro_mattributes(filter: nullable ModelFilter): Set[MAttribute] do
var res = new HashSet[MAttribute]
for mproperty in collect_intro_mproperties(filter) do
if mproperty isa MAttribute then res.add(mproperty)
end
return res
end
# Collect all attributes redefined in `self`
fun collect_redef_mattributes(filter: nullable ModelFilter): Set[MAttribute] do
var res = new HashSet[MAttribute]
for mproperty in collect_redef_mproperties(filter) do
if mproperty isa MAttribute then res.add(mproperty)
end
return res
end
# Collect all attributes introduced and redefined in `self`
fun collect_local_mattributes(filter: nullable ModelFilter): Set[MAttribute] do
var set = new HashSet[MAttribute]
set.add_all collect_intro_mattributes(filter)
set.add_all collect_redef_mattributes(filter)
return set
end
# Collect all attributes inherited by `self`
fun collect_inherited_mattributes(mainmodule: MModule, filter: nullable ModelFilter): Set[MAttribute] do
var res = new HashSet[MAttribute]
for mproperty in collect_inherited_mproperties(mainmodule, filter) do
if mproperty isa MAttribute then res.add(mproperty)
end
return res
end
# Collect all attributes accessible by `self`
#
# This include introduced, redefined, inherited mattributes.
fun collect_accessible_mattributes(mainmodule: MModule, filter: nullable ModelFilter): Set[MAttribute] do
var set = new HashSet[MAttribute]
set.add_all(collect_intro_mattributes(filter))
set.add_all(collect_redef_mattributes(filter))
set.add_all(collect_inherited_mattributes(mainmodule, filter))
return set
end
# Collect all init methods introduced in `self`
fun collect_intro_inits(filter: nullable ModelFilter): Set[MMethod] do
var res = new HashSet[MMethod]
for mproperty in collect_intro_mmethods(filter) do
if mproperty.is_init then res.add(mproperty)
end
return res
end
# Collect all init methods redefined in `self`
fun collect_redef_inits(filter: nullable ModelFilter): Set[MMethod] do
var res = new HashSet[MMethod]
for mproperty in collect_redef_mmethods(filter) do
if mproperty.is_init then res.add(mproperty)
end
return res
end
# Collect all init methods introduced and redefined in `self`
fun collect_local_inits(filter: nullable ModelFilter): Set[MMethod] do
var set = new HashSet[MMethod]
set.add_all collect_intro_inits(filter)
set.add_all collect_redef_inits(filter)
return set
end
# Collect all init methods inherited by `self`
fun collect_inherited_inits(mainmodule: MModule, filter: nullable ModelFilter): Set[MMethod] do
var res = new HashSet[MMethod]
for mproperty in collect_inherited_mmethods(mainmodule, filter) do
if mproperty.is_init then res.add(mproperty)
end
return res
end
# Collect all init methods accessible by `self`
#
# This include introduced, redefined, inherited inits.
fun collect_accessible_inits(mainmodule: MModule, filter: nullable ModelFilter): Set[MMethod] do
var set = new HashSet[MMethod]
set.add_all(collect_intro_inits(filter))
set.add_all(collect_redef_inits(filter))
set.add_all(collect_inherited_inits(mainmodule, filter))
return set
end
# Collect all virtual types introduced in `self`
fun collect_intro_vts(filter: nullable ModelFilter): Set[MVirtualTypeProp] do
var res = new HashSet[MVirtualTypeProp]
for mproperty in collect_intro_mproperties(filter) do
if mproperty isa MVirtualTypeProp then res.add(mproperty)
end
return res
end
# Collect all virtual types redefined in `self`
fun collect_redef_vts(filter: nullable ModelFilter): Set[MVirtualTypeProp] do
var res = new HashSet[MVirtualTypeProp]
for mproperty in collect_intro_mproperties(filter) do
if mproperty isa MVirtualTypeProp then res.add(mproperty)
end
return res
end
# Collect all virtual types introduced or redefined in `self`
fun collect_local_vts(filter: nullable ModelFilter): Set[MVirtualTypeProp] do
var set = new HashSet[MVirtualTypeProp]
set.add_all collect_intro_vts(filter)
set.add_all collect_redef_vts(filter)
return set
end
# Collect all virtual types inherited by `self`
fun collect_inherited_vts(mainmodule: MModule, filter: nullable ModelFilter): Set[MVirtualTypeProp] do
var res = new HashSet[MVirtualTypeProp]
for mproperty in collect_inherited_mproperties(mainmodule, filter) do
if mproperty isa MVirtualTypeProp then res.add(mproperty)
end
return res
end
# Collect all virtual types accessible by `self`
#
# This include introduced, redefined, inherited virtual types.
fun collect_accessible_vts(mainmodule: MModule, filter: nullable ModelFilter): Set[MVirtualTypeProp] do
var set = new HashSet[MVirtualTypeProp]
for mproperty in collect_accessible_mproperties(mainmodule, filter) do
if mproperty isa MVirtualTypeProp then set.add mproperty
end
return set
end
end
src/model/model_collect.nit:642,1--966,3
redef class MClass
# Runtime name
private fun rt_name: String do return "RTClass_{intro_mmodule.jname}_{jname}"
# Generate a Java RTClass for a Nit MClass
fun compile_to_java(v: JavaCompilerVisitor) do
v.add("public class {rt_name} extends RTClass \{")
v.add(" protected static RTClass instance;")
v.add(" private {rt_name}() \{")
v.add(" this.class_name = \"{name}\";")
compile_vft(v)
compile_type_table(v)
v.add(" \}")
v.add(" public static RTClass get{rt_name}() \{")
v.add(" if(instance == null) \{")
v.add(" instance = new {rt_name}();")
v.add(" \}")
v.add(" return instance;")
v.add(" \}")
v.add("\}")
end
# Compile the virtual function table for the mclass
private fun compile_vft(v: JavaCompilerVisitor) do
# TODO handle generics
if mclass_type.need_anchor then return
var mclassdefs = mclass_type.collect_mclassdefs(v.compiler.mainmodule).to_a
v.compiler.mainmodule.linearize_mclassdefs(mclassdefs)
var mainmodule = v.compiler.mainmodule
for mclassdef in mclassdefs.reversed do
for mprop in mclassdef.intro_mproperties do
var mpropdef = mprop.lookup_first_definition(mainmodule, intro.bound_mtype)
if not mpropdef isa MMethodDef then continue
var rt_name = mpropdef.rt_name
v.add("this.vft.put(\"{mprop.full_name}\", {rt_name}.get{rt_name}());")
# fill super next definitions
while mpropdef.has_supercall do
var prefix = mpropdef.full_name
mpropdef = mpropdef.lookup_next_definition(mainmodule, intro.bound_mtype)
rt_name = mpropdef.rt_name
v.add("this.vft.put(\"{prefix}\", {rt_name}.get{rt_name}());")
end
end
end
end
# Compile the type table for the MClass
fun compile_type_table(v: JavaCompilerVisitor) do
for pclass in in_hierarchy(v.compiler.mainmodule).greaters do
if pclass == self then
v.add("supers.put(\"{pclass.jname}\", this);")
else
v.add("supers.put(\"{pclass.jname}\", {pclass.rt_name}.get{pclass.rt_name}());")
end
end
end
end
src/compiler/java_compiler.nit:1330,1--1389,3
redef class MClass
# Class Depth in Inheritance Tree
#
# Following the longest path composed only of extends edges from self to Object
fun ditc(mainmodule: MModule): Int do
if in_hierarchy(mainmodule).direct_greaters.is_empty then
return 0
end
var min = -1
for p in in_hierarchy(mainmodule).direct_greaters do
if p.kind != abstract_kind and p.kind != concrete_kind and p.kind != extern_kind then continue
var d = p.ditc(mainmodule) + 1
if min == -1 or d < min then
min = d
end
end
if min == -1 then min = 0
return min
end
# Interface Depth in Inheritance Tree
#
# Following the longest path composed only of implements edges from self to Object
fun diti(mainmodule: MModule): Int do
if in_hierarchy(mainmodule).direct_greaters.is_empty then
return 0
end
var min = -1
for p in in_hierarchy(mainmodule).direct_greaters do
if p.kind != interface_kind then continue
var d = p.diti(mainmodule) + 1
if min == -1 or d < min then
min = d
end
end
if min == -1 then min = 0
return min
end
end
src/metrics/inheritance_metrics.nit:507,1--546,3
redef class MClass
# the set of redefition that call to super
fun extended_mproperties(filter: ModelFilter): Set[MProperty] do
var set = new HashSet[MProperty]
for mclassdef in mclassdefs do
for mpropdef in mclassdef.mpropdefs do
if not filter.accept_mentity(mpropdef) then continue
if not mpropdef.has_supercall then continue
if mpropdef.mproperty.intro_mclassdef.mclass != self then set.add(mpropdef.mproperty)
end
end
return set
end
# the set of redefition that do not call to super
fun overriden_mproperties(filter: ModelFilter): Set[MProperty] do
var set = new HashSet[MProperty]
for mclassdef in mclassdefs do
for mpropdef in mclassdef.mpropdefs do
if not filter.accept_mentity(mpropdef) then continue
if mpropdef.has_supercall then continue
if mpropdef.mproperty.intro_mclassdef.mclass != self then set.add(mpropdef.mproperty)
end
end
return set
end
# pure overriders contain only redefinitions
private fun is_pure_overrider(filter: ModelFilter): Bool do
var news = collect_intro_mproperties(filter).length
var locs = collect_local_mproperties(filter).length
if news == 0 and locs > 0 then return true
return false
end
# overriders contain more definitions than introductions
private fun is_overrider(filter: ModelFilter): Bool do
var rdfs = collect_redef_mproperties(filter).length
var news = collect_intro_mproperties(filter).length
var locs = collect_local_mproperties(filter).length
if rdfs >= news and locs > 0 then return true
return false
end
# pure extenders contain only introductions
private fun is_pure_extender(filter: ModelFilter): Bool do
var rdfs = collect_redef_mproperties(filter).length
var locs = collect_local_mproperties(filter).length
if rdfs == 0 and locs > 0 then return true
return false
end
# extenders contain more introduction than redefinitions
private fun is_extender(filter: ModelFilter): Bool do
var rdfs = collect_redef_mproperties(filter).length
var news = collect_intro_mproperties(filter).length
var locs = collect_local_mproperties(filter).length
if news > rdfs and locs > 0 then return true
return false
end
# pure specializers always call to super in its redefinitions
private fun is_pure_specializer(filter: ModelFilter): Bool do
var ovrs = overriden_mproperties(filter).length
var rdfs = collect_redef_mproperties(filter).length
if ovrs == 0 and rdfs > 0 then return true
return false
end
# specializers have more redefinitions that call super than not calling it
private fun is_specializer(filter: ModelFilter): Bool do
var spcs = extended_mproperties(filter).length
var ovrs = overriden_mproperties(filter).length
var rdfs = collect_redef_mproperties(filter).length
if spcs > ovrs and rdfs > 0 then return true
return false
end
# pure replacers never call to super in its redefinitions
private fun is_pure_replacer(filter: ModelFilter): Bool do
var spcs = extended_mproperties(filter).length
var rdfs = collect_redef_mproperties(filter).length
if spcs == 0 and rdfs > 0 then return true
return false
end
# replacers have less redefinitions that call super than not calling it
private fun is_replacer(filter: ModelFilter): Bool do
var spcs = extended_mproperties(filter).length
var ovrs = overriden_mproperties(filter).length
var rdfs = collect_redef_mproperties(filter).length
if ovrs > spcs and rdfs > 0 then return true
return false
end
# equals contain as redifinition than introduction
private fun is_equal(filter: ModelFilter): Bool do
var spcs = extended_mproperties(filter).length
var ovrs = overriden_mproperties(filter).length
var rdfs = collect_redef_mproperties(filter).length
if spcs == ovrs and rdfs > 0 then return true
return false
end
end
src/metrics/mendel_metrics.nit:257,1--360,3
redef class MClass
redef fun cs_icon(no_color) do return intro.cs_icon(no_color)
redef fun cs_signature(no_color) do return intro.cs_signature(no_color)
end
src/doc/templates/term_model.nit:148,1--151,3
redef class MClass
redef fun tpl_class(model) do
var name = name.escape_to_dot
var t = new Template
t.add "{name} [\n label = \"\{"
if kind == abstract_kind then
t.add "abstract\\n{name}"
else if kind == interface_kind then
t.add "interface\\n{name}"
else
t.add "{name}"
end
if arity > 0 then
t.add "["
t.add mparameters.first.name
for i in [1 .. mparameters.length[ do
t.add ", "
t.add mparameters[i].name
end
t.add "]"
end
t.add "|"
var props = collect_intro_mproperties(model.filter)
for i in props do
if not i isa MAttribute then continue
t.add i.tpl_class(model)
t.add "\\l"
end
t.add "|"
for i in props do
if not i isa MMethod then continue
t.add i.tpl_class(model)
t.add "\\l"
end
t.add "\}\"\n]\n"
var g = in_hierarchy(model.mainmodule).direct_greaters
for i in g do
if not model.filter.accept_mentity(i) then continue
t.add "{i.name} -> {name} [dir=back"
if i.kind == interface_kind then
t.add " arrowtail=open style=dashed"
else
t.add " arrowtail=empty"
end
t.add "];\n"
end
return t
end
end
src/uml/uml_class.nit:52,1--102,3
redef class MClass
redef fun mentity_kind_rank do return 4
end
src/model/model_index.nit:658,1--660,3
redef class MClass
redef fun html_icon do return new BSIcon("stop", css_classes)
redef fun html_signature(short) do return intro.html_signature(short)
redef fun css_classes do return super + [visibility.to_s]
redef fun html_namespace do
var mgroup = intro_mmodule.mgroup
var tpl = new Template
if mgroup != null then
tpl.add mgroup.mpackage.html_namespace
tpl.add " :: "
end
tpl.add "<span>"
tpl.add html_link
tpl.add "</span>"
return tpl
end
end
src/doc/templates/html_model.nit:134,1--151,3
redef class MClass
redef fun core_serialize_to(v) do
super
if mparameters.not_empty then
v.serialize_attribute("mparameters", mparameters)
end
end
redef fun json_namespace do
var ns = new JsonNamespace
ns.add_all intro_mmodule.ns_for(visibility)
ns.add "::"
ns.add to_json_ref
return ns
end
end
src/doc/templates/json_model.nit:149,1--165,3
redef class MClass
redef var nitdoc_breadcrumbs is lazy do
return intro_mmodule.nitdoc_breadcrumbs + [self]
end
end
src/doc/static/static_base.nit:273,1--277,3