MProperty
are global to the model; it means that a MProperty
is not bound
to a specific MModule
nor a specific MClass
.
A MProperty gather definitions (see mpropdefs
) ; one for the introduction
and the other in subclasses and in refinements.
A MProperty
is used to denotes services in polymorphic way (ie. independent
of any dynamic type).
For instance, a call site "x.foo" is associated to a MProperty
.
nitc :: MProperty :: _intro_mclassdef
The classdef that introduce the propertynitc :: MProperty :: _is_after_all
Does self have theafter_all
annotation?
nitc :: MProperty :: _is_autoinit
Is the property usable as an initializer?nitc :: MProperty :: _is_before_all
Does self have thebefore_all
annotation?
nitc :: MProperty :: _is_example
nitc :: MProperty :: _mpropdefs
All definitions of the property.nitc :: MProperty :: _visibility
The visibility of the propertynitc :: MProperty :: collect_mpropdefs
Collect all property definitions ofself
nitc :: MProperty :: defaultinit
nitc :: MProperty :: full_name=
The canonical name of the property.nitc :: MProperty :: intro_mclassdef
The classdef that introduce the propertynitc :: MProperty :: intro_mclassdef=
The classdef that introduce the propertynitc :: MProperty :: is_after_all=
Does self have theafter_all
annotation?
nitc :: MProperty :: is_autoinit=
Is the property usable as an initializer?nitc :: MProperty :: is_before=
Does self have thebefore
annotation?
nitc :: MProperty :: is_before_all
Does self have thebefore_all
annotation?
nitc :: MProperty :: is_before_all=
Does self have thebefore_all
annotation?
nitc :: MProperty :: is_example=
nitc :: MProperty :: lookup_all_definitions
Return all definitions in a linearization ordernitc :: MProperty :: lookup_definitions
Return the most specific property definitions defined or inherited by a type.nitc :: MProperty :: lookup_first_definition
Return the most specific definition in the linearization ofmtype
.
nitc :: MProperty :: lookup_super_definitions
Return the most specific property definitions inherited by a type.nitc :: MProperty :: mpropdefs=
All definitions of the property.nitc :: MProperty :: select_most_specific
Return an array containing olny the most specific property definitionsnitc :: MProperty :: visibility=
The visibility of the propertynitc :: MProperty :: write_synopsis
nitc :: model_collect $ MProperty :: collect_children
Collection all definitions that haveself
as a direct super definition
nitc :: model_collect $ MProperty :: collect_linearization
Collectself
linearization anchored on mainmodule
nitc :: model_collect $ MProperty :: collect_modifiers
Collect modifier keywords likeredef
, private
etc
nitc :: model_collect $ MProperty :: collect_parents
Collect all direct super definitions ofself
nitc :: term_model $ MProperty :: cs_signature
Returnsself
signature formatted for console.
nitc :: html_model $ MProperty :: css_classes
CSS classes used to decorateself
nitc :: html_model $ MProperty :: html_declaration
Returns the complete MEntity declaration decorated with HTMLnitc :: html_model $ MProperty :: html_namespace
Returnsfull_name
decorated with HTML links
nitc :: html_model $ MProperty :: html_signature
Returns the MEntity signature decorated with HTMLnitc :: model_examples $ MProperty :: is_example
Isself
existing for an example purpose?
nitc :: json_model $ MProperty :: json_namespace
Returnself.full_name
as an object that can be serialized to json.
nitc $ MProperty :: mdoc_or_fallback
The documentation associated to the entity or their main nested entity.nitc :: model_index $ MProperty :: mentity_kind_rank
Compare MEntity class kindnitc :: MEntity :: _const_color
nitc :: MEntity :: _css_classes
CSS classes used to decorateself
nitc :: MEntity :: _deprecation
Is the entity deprecated?nitc :: MEntity :: _html_full_name
The MEntityfull_name
escaped for HTML
nitc :: MProperty :: _intro_mclassdef
The classdef that introduce the propertynitc :: MProperty :: _is_after_all
Does self have theafter_all
annotation?
nitc :: MProperty :: _is_autoinit
Is the property usable as an initializer?nitc :: MProperty :: _is_before_all
Does self have thebefore_all
annotation?
nitc :: MEntity :: _is_broken
The indication that the entity did not pass some semantic verifications.nitc :: MProperty :: _is_example
nitc :: MProperty :: _mpropdefs
All definitions of the property.nitc :: MProperty :: _visibility
The visibility of the propertyserialization :: 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
core :: Object :: class_factory
Implementation used byget_class
to create the specific class.
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 :: MEntity :: collect_linearization
Collectself
linearization anchored on mainmodule
nitc :: MEntity :: collect_metrics
nitc :: MEntity :: collect_modifiers
Collect modifier keywords likeredef
, private
etc
nitc :: MProperty :: collect_mpropdefs
Collect all property definitions ofself
nitc :: MEntity :: collect_parents
Collectself
parents (direct ancestors)
nitc :: MEntity :: const_color
nitc :: MEntity :: const_color=
nitc :: MEntity :: core_serialize_base
serialization :: Serializable :: core_serialize_to
Actual serialization ofself
to serializer
nitc :: MEntity :: create_ast_representation
Build a ANode fromself
nitc :: 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 :: HInfoBoxable :: defaultinit
nitc :: MProperty :: defaultinit
nitc :: MEntity :: defaultinit
core :: Object :: defaultinit
nitc :: MEntity :: deprecation=
Is the entity deprecated?nitc :: MEntity :: field_separator
serialization :: Serializable :: from_deserializer
Create an instance of this class from thedeserializer
nitc :: MProperty :: full_name=
The canonical name of the property.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 :: HInfoBoxable :: infobox
An new infobox documenting the entitynitc :: MProperty :: intro_mclassdef
The classdef that introduce the propertynitc :: MProperty :: intro_mclassdef=
The classdef that introduce the propertynitc :: MProperty :: is_after_all=
Does self have theafter_all
annotation?
nitc :: MProperty :: is_autoinit=
Is the property usable as an initializer?nitc :: MProperty :: is_before=
Does self have thebefore
annotation?
nitc :: MProperty :: is_before_all
Does self have thebefore_all
annotation?
nitc :: MProperty :: is_before_all=
Does self have thebefore_all
annotation?
nitc :: MEntity :: is_broken=
The indication that the entity did not pass some semantic verifications.nitc :: MProperty :: is_example=
nitc :: MEntity :: is_fictive=
Isself
created for internal purpose?
core :: 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 :: 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 :: MProperty :: lookup_all_definitions
Return all definitions in a linearization ordernitc :: MProperty :: lookup_definitions
Return the most specific property definitions defined or inherited by a type.nitc :: MProperty :: lookup_first_definition
Return the most specific definition in the linearization ofmtype
.
nitc :: MProperty :: lookup_super_definitions
Return the most specific property definitions inherited by a type.nitc :: MEntity :: mdoc_or_fallback
The documentation associated to the entity or their main nested entity.nitc :: MProperty :: mpropdefs=
All definitions of the property.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).mentity
nitc :: MEntity :: ratings_by_dimension
Get the ratings of adimension
nitc :: MProperty :: select_most_specific
Return an array containing olny the most specific property definitionsserialization :: 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 :: MEntity :: source_url
Render a HTML link for the MEntity locationserialization :: Serializable :: to_pretty_json
Serializeself
to plain pretty JSON
nitc :: MEntity :: tpl_module
Builds a dot UML package diagram entity fromself
nitc :: MProperty :: visibility=
The visibility of the propertyv.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 declarationsnitc :: MProperty :: write_synopsis
Serializer::serialize
invariant
and ensure
).
# A service (global property) that generalize method, attribute, etc.
#
# `MProperty` are global to the model; it means that a `MProperty` is not bound
# to a specific `MModule` nor a specific `MClass`.
#
# A MProperty gather definitions (see `mpropdefs`) ; one for the introduction
# and the other in subclasses and in refinements.
#
# A `MProperty` is used to denotes services in polymorphic way (ie. independent
# of any dynamic type).
# For instance, a call site "x.foo" is associated to a `MProperty`.
abstract class MProperty
super MEntity
# The associated MPropDef subclass.
# The two specialization hierarchy are symmetric.
type MPROPDEF: MPropDef
# The classdef that introduce the property
# While a property is not bound to a specific module, or class,
# the introducing mclassdef is used for naming and visibility
var intro_mclassdef: MClassDef
# The (short) name of the property
redef var name
redef var location
redef fun mdoc_or_fallback
do
# Don’t use `intro.mdoc_or_fallback` because it would create an infinite
# recursion.
return intro.mdoc
end
# The canonical name of the property.
#
# It is currently the short-`name` prefixed by the short-name of the class and the full-name of the module.
# Example: "my_package::my_module::MyClass::my_method"
#
# The full-name of the module is needed because two distinct modules of the same package can
# still refine the same class and introduce homonym properties.
#
# For public properties not introduced by refinement, the module name is not used.
#
# Example: `my_package::MyClass::My_method`
redef var full_name is lazy do
if intro_mclassdef.is_intro then
return "{intro_mclassdef.mmodule.namespace_for(visibility)}::{intro_mclassdef.mclass.name}::{name}"
else
return "{intro_mclassdef.mmodule.full_name}::{intro_mclassdef.mclass.name}::{name}"
end
end
redef var c_name is lazy do
# FIXME use `namespace_for`
return "{intro_mclassdef.mmodule.c_name}__{intro_mclassdef.mclass.name.to_cmangle}__{name.to_cmangle}"
end
# The visibility of the property
redef var visibility
# Is the property usable as an initializer?
var is_autoinit = false is writable
init
do
intro_mclassdef.intro_mproperties.add(self)
var model = intro_mclassdef.mmodule.model
model.mproperties_by_name.add_one(name, self)
model.mproperties.add(self)
end
# All definitions of the property.
# The first is the introduction,
# The other are redefinitions (in refinements and in subclasses)
var mpropdefs = new Array[MPROPDEF]
# The definition that introduces the property.
#
# Warning: such a definition may not exist in the early life of the object.
# In this case, the method will abort.
var intro: MPROPDEF is noinit
redef fun model do return intro.model
# Alias for `name`
redef fun to_s do return name
# Return the most specific property definitions defined or inherited by a type.
# The selection knows that refinement is stronger than specialization;
# however, in case of conflict more than one property are returned.
# If mtype does not know mproperty then an empty array is returned.
#
# If you want the really most specific property, then look at `lookup_first_definition`
#
# REQUIRE: `not mtype.need_anchor` to simplify the API (no `anchor` parameter)
# ENSURE: `not mtype.has_mproperty(mmodule, self) == result.is_empty`
fun lookup_definitions(mmodule: MModule, mtype: MType): Array[MPROPDEF]
do
assert not mtype.need_anchor
mtype = mtype.undecorate
var cache = self.lookup_definitions_cache[mmodule, mtype]
if cache != null then return cache
#print "select prop {mproperty} for {mtype} in {self}"
# First, select all candidates
var candidates = new Array[MPROPDEF]
# Here we have two strategies: iterate propdefs or iterate classdefs.
var mpropdefs = self.mpropdefs
if mpropdefs.length <= 1 or mpropdefs.length < mtype.collect_mclassdefs(mmodule).length then
# Iterate on all definitions of `self`, keep only those inherited by `mtype` in `mmodule`
for mpropdef in mpropdefs do
# If the definition is not imported by the module, then skip
if not mmodule.in_importation <= mpropdef.mclassdef.mmodule then continue
# If the definition is not inherited by the type, then skip
if not mtype.is_subtype(mmodule, null, mpropdef.mclassdef.bound_mtype) then continue
# Else, we keep it
candidates.add(mpropdef)
end
else
# Iterate on all super-classdefs of `mtype`, keep only the definitions of `self`, if any.
for mclassdef in mtype.collect_mclassdefs(mmodule) do
var p = mclassdef.mpropdefs_by_property.get_or_null(self)
if p != null then candidates.add p
end
end
# Fast track for only one candidate
if candidates.length <= 1 then
self.lookup_definitions_cache[mmodule, mtype] = candidates
return candidates
end
# Second, filter the most specific ones
return select_most_specific(mmodule, candidates)
end
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;
# however, in case of conflict more than one property are returned.
# If mtype does not know mproperty then an empty array is returned.
#
# If you want the really most specific property, then look at `lookup_next_definition`
#
# REQUIRE: `not mtype.need_anchor` to simplify the API (no `anchor` parameter)
# ENSURE: `not mtype.has_mproperty(mmodule, self) implies result.is_empty`
fun lookup_super_definitions(mmodule: MModule, mtype: MType): Array[MPROPDEF]
do
assert not mtype.need_anchor
mtype = mtype.undecorate
# First, select all candidates
var candidates = new Array[MPROPDEF]
for mpropdef in self.mpropdefs do
# If the definition is not imported by the module, then skip
if not mmodule.in_importation <= mpropdef.mclassdef.mmodule then continue
# If the definition is not inherited by the type, then skip
if not mtype.is_subtype(mmodule, null, mpropdef.mclassdef.bound_mtype) then continue
# If the definition is defined by the type, then skip (we want the super, so e skip the current)
if mtype == mpropdef.mclassdef.bound_mtype and mmodule == mpropdef.mclassdef.mmodule then continue
# Else, we keep it
candidates.add(mpropdef)
end
# Fast track for only one candidate
if candidates.length <= 1 then return candidates
# Second, filter the most specific ones
return select_most_specific(mmodule, candidates)
end
# Return an array containing olny the most specific property definitions
# This is an helper function for `lookup_definitions` and `lookup_super_definitions`
private fun select_most_specific(mmodule: MModule, candidates: Array[MPROPDEF]): Array[MPROPDEF]
do
var res = new Array[MPROPDEF]
for pd1 in candidates do
var cd1 = pd1.mclassdef
var c1 = cd1.mclass
var keep = true
for pd2 in candidates do
if pd2 == pd1 then continue # do not compare with self!
var cd2 = pd2.mclassdef
var c2 = cd2.mclass
if c2.mclass_type == c1.mclass_type then
if cd2.mmodule.in_importation < cd1.mmodule then
# cd2 refines cd1; therefore we skip pd1
keep = false
break
end
else if cd2.bound_mtype.is_subtype(mmodule, null, cd1.bound_mtype) and cd2.bound_mtype != cd1.bound_mtype then
# cd2 < cd1; therefore we skip pd1
keep = false
break
end
end
if keep then
res.add(pd1)
end
end
if res.is_empty then
print_error "All lost! {candidates.join(", ")}"
# FIXME: should be abort!
end
return res
end
# Return the most specific definition in the linearization of `mtype`.
#
# If you want to know the next properties in the linearization,
# look at `MPropDef::lookup_next_definition`.
#
# FIXME: the linearization is still unspecified
#
# REQUIRE: `not mtype.need_anchor` to simplify the API (no `anchor` parameter)
# REQUIRE: `mtype.has_mproperty(mmodule, self)`
fun lookup_first_definition(mmodule: MModule, mtype: MType): MPROPDEF
do
return lookup_all_definitions(mmodule, mtype).first
end
# Return all definitions in a linearization order
# Most specific first, most general last
#
# REQUIRE: `not mtype.need_anchor` to simplify the API (no `anchor` parameter)
# REQUIRE: `mtype.has_mproperty(mmodule, self)`
fun lookup_all_definitions(mmodule: MModule, mtype: MType): Array[MPROPDEF]
do
mtype = mtype.undecorate
var cache = self.lookup_all_definitions_cache[mmodule, mtype]
if cache != null then return cache
assert not mtype.need_anchor
assert mtype.has_mproperty(mmodule, self)
#print "select prop {mproperty} for {mtype} in {self}"
# First, select all candidates
var candidates = new Array[MPROPDEF]
for mpropdef in self.mpropdefs do
# If the definition is not imported by the module, then skip
if not mmodule.in_importation <= mpropdef.mclassdef.mmodule then continue
# If the definition is not inherited by the type, then skip
if not mtype.is_subtype(mmodule, null, mpropdef.mclassdef.bound_mtype) then continue
# Else, we keep it
candidates.add(mpropdef)
end
# Fast track for only one candidate
if candidates.length <= 1 then
self.lookup_all_definitions_cache[mmodule, mtype] = candidates
return candidates
end
mmodule.linearize_mpropdefs(candidates)
candidates = candidates.reversed
self.lookup_all_definitions_cache[mmodule, mtype] = candidates
return candidates
end
private var lookup_all_definitions_cache = new HashMap2[MModule, MType, Array[MPROPDEF]]
redef var is_test is lazy do return intro.is_test
# Does self have the `before` annotation?
var is_before: Bool is lazy do return intro.is_before
# Does self have the `before_all` annotation?
var is_before_all: Bool is lazy do return intro.is_before_all
# Does self have the `after` annotation?
var is_after: Bool is lazy do return intro.is_after
# Does self have the `after_all` annotation?
var is_after_all: Bool is lazy do return intro.is_after_all
end
src/model/model.nit:2131,1--2409,3
redef class MProperty
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 = make_node(nodes, model_name)
node.labels.add "MProperty"
node["visibility"] = visibility.to_s
node.out_edges.add(new NeoEdge(node, "INTRO_CLASSDEF", intro_mclassdef.to_node(nodes, model_name)))
node.labels.add self.class_name
return node
end
end
src/neo.nit:768,1--778,3
redef class MProperty
redef fun collect_modifiers do return intro.collect_modifiers
redef fun collect_linearization(mainmodule) do
var mpropdefs = self.mpropdefs.to_a
mainmodule.linearize_mpropdefs(mpropdefs)
return mpropdefs
end
# Collect all property definitions of `self`
fun collect_mpropdefs(filter: nullable ModelFilter): Set[MPropDef] do
var res = new HashSet[MPropDef]
for mpropdef in mpropdefs do
if filter == null or filter.accept_mentity(mpropdef) then res.add mpropdef
end
return res
end
# Collect all direct super definitions of `self`
redef fun collect_parents(mainmodule, filter) do
var res = new HashSet[MENTITY]
for mpropdef in mpropdefs do
for parent in mpropdef.collect_parents(mainmodule, filter) do
var mprop = parent.mproperty
if filter == null or filter.accept_mentity(mprop) then res.add mprop
end
end
return res
end
# Collection all definitions that have `self` as a direct super definition
redef fun collect_children(mainmodule, filter) do
var res = new HashSet[MENTITY]
for mpropdef in mpropdefs do
for child in mpropdef.collect_parents(mainmodule, filter) do
var mprop = child.mproperty
if filter == null or filter.accept_mentity(mprop) then res.add mprop
end
end
return res
end
end
src/model/model_collect.nit:1074,1--1115,3
redef class MProperty
super PropertyLayoutElement
end
src/compiler/separate_compiler.nit:2648,1--2650,3
redef class MProperty
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:176,1--179,3
redef class MProperty
private fun write_synopsis(mainmodule: MModule, stream: Writer)
do
if visibility == public_visibility then
stream.write "+ "
else stream.write "~ " # protected_visibility
if self isa MMethod then
if is_new and name != "new" then
stream.write "new "
else if is_init and name != "init" then
stream.write "init "
end
end
stream.write name
if self isa MMethod then
var intro = intro
assert intro isa MMethodDef
var msignature = intro.msignature
if msignature != null then
stream.write msignature.to_s
end
end
var mdoc = intro.mdoc
if mdoc != null then
stream.write " # "
stream.write mdoc.content.first
end
stream.write line_separator
end
end
src/doc/vim_autocomplete.nit:370,1--403,3
redef class MProperty
redef fun mentity_kind_rank do return 6
end
src/model/model_index.nit:666,1--668,3
redef class MProperty
redef fun html_declaration do return intro.html_declaration
redef fun html_signature(short) do return intro.html_signature(short)
redef fun html_icon do return new BSIcon("tag", css_classes)
redef fun css_classes do return super + [visibility.to_s]
redef fun html_namespace do
var tpl = new Template
tpl.add intro_mclassdef.mclass.html_namespace
tpl.add " :: "
tpl.add intro.html_link
return tpl
end
end
src/doc/templates/html_model.nit:206,1--219,3
redef class MProperty
redef fun json_namespace do
var ns = new JsonNamespace
if intro_mclassdef.is_intro then
ns.add_all intro_mclassdef.mmodule.ns_for(visibility)
ns.add "::"
ns.add intro_mclassdef.mclass.to_json_ref
ns.add "::"
ns.add to_json_ref
else
ns.add_all intro_mclassdef.mmodule.json_namespace
ns.add "::"
ns.add intro_mclassdef.mclass.to_json_ref
ns.add "::"
ns.add to_json_ref
end
return ns
end
end
src/doc/templates/json_model.nit:203,1--221,3
redef class MProperty
redef var nitdoc_breadcrumbs is lazy do
var res = new Array[MEntity].from(intro_mclassdef.mclass.nitdoc_breadcrumbs)
res.add self
return res
end
end
src/doc/static/static_base.nit:287,1--293,3
redef class MProperty
redef var html_url is lazy do return "property_{super}"
end
src/doc/static/static_html.nit:399,1--401,3