nitc :: MPropDef :: defaultinit
# A definition of a property (local property)
#
# Unlike `MProperty`, a `MPropDef` is a local definition that belong to a
# specific class definition (which belong to a specific module)
abstract class MPropDef
super MEntity
# The associated `MProperty` subclass.
# the two specialization hierarchy are symmetric
type MPROPERTY: MProperty
# Self class
type MPROPDEF: MPropDef
# The class definition where the property definition is
var mclassdef: MClassDef
# The associated global property
var mproperty: MPROPERTY
redef var location
redef fun visibility do return mproperty.visibility
init
do
mclassdef.mpropdefs.add(self)
mproperty.mpropdefs.add(self)
mclassdef.mpropdefs_by_property[mproperty] = self
if mproperty.intro_mclassdef == mclassdef then
assert not isset mproperty._intro
mproperty.intro = self
end
self.to_s = "{mclassdef}${mproperty}"
end
# Actually the name of the `mproperty`
redef fun name do return mproperty.name
# The full-name of mpropdefs combine the information about the `classdef` and the `mproperty`.
#
# Therefore the combination of identifiers is awful,
# the worst case being
#
# * a property "p::m::A::x"
# * redefined in a refinement of a class "q::n::B"
# * in a module "r::o"
# * so "r::o$q::n::B$p::m::A::x"
#
# Fortunately, the full-name is simplified when entities are repeated.
# For the previous case, the simplest form is "p$A$x".
redef var full_name is lazy do
var res = new FlatBuffer
# The first part is the mclassdef. Worst case is "r::o$q::n::B"
res.append mclassdef.full_name
res.append "$"
if mclassdef.mclass == mproperty.intro_mclassdef.mclass then
# intro are unambiguous in a class
res.append name
else
# Just try to simplify each part
if mclassdef.mmodule.mpackage != mproperty.intro_mclassdef.mmodule.mpackage then
# precise "p::m" only if "p" != "r"
res.append mproperty.intro_mclassdef.mmodule.namespace_for(mproperty.visibility)
res.append "::"
else if mproperty.visibility <= private_visibility then
# Same package ("p"=="q"), but private visibility,
# does the module part ("::m") need to be displayed
if mclassdef.mmodule.namespace_for(mclassdef.mclass.visibility) != mproperty.intro_mclassdef.mmodule.mpackage then
res.append "::"
res.append mproperty.intro_mclassdef.mmodule.name
res.append "::"
end
end
# precise "B" because it is not the same class than "A"
res.append mproperty.intro_mclassdef.name
res.append "::"
# Always use the property name "x"
res.append mproperty.name
end
return res.to_s
end
redef var c_name is lazy do
var res = new FlatBuffer
res.append mclassdef.c_name
res.append "___"
if mclassdef.mclass == mproperty.intro_mclassdef.mclass then
res.append name.to_cmangle
else
if mclassdef.mmodule != mproperty.intro_mclassdef.mmodule then
res.append mproperty.intro_mclassdef.mmodule.c_name
res.append "__"
end
res.append mproperty.intro_mclassdef.name.to_cmangle
res.append "__"
res.append mproperty.name.to_cmangle
end
return res.to_s
end
redef fun model do return mclassdef.model
# Internal name combining the module, the class and the property
# Example: "mymodule$MyClass$mymethod"
redef var to_s is noinit
# Is self the definition that introduce the property?
fun is_intro: Bool do return isset mproperty._intro and mproperty.intro == self
# Return the next definition in linearization of `mtype`.
#
# This method is used to determine what method is called by a super.
#
# REQUIRE: `not mtype.need_anchor`
fun lookup_next_definition(mmodule: MModule, mtype: MType): MPROPDEF
do
assert not mtype.need_anchor
var mpropdefs = self.mproperty.lookup_all_definitions(mmodule, mtype)
var i = mpropdefs.iterator
while i.is_ok and i.item != self do i.next
assert has_property: i.is_ok
i.next
assert has_next_property: i.is_ok
return i.item
end
redef fun mdoc_or_fallback do return mdoc or else mproperty.mdoc_or_fallback
# Does self have the `before` annotation?
var is_before = false is writable
# Does self have the `before_all` annotation?
var is_before_all = false is writable
# Does self have the `after` annotation?
var is_after = false is writable
# Does self have the `after_all` annotation?
var is_after_all = false is writable
end
src/model/model.nit:2504,1--2648,3