nitc :: MProperty :: lookup_definitions
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
# 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
src/model/model.nit:2220,2--2269,4