#
# This is usefull for tools that need a global view of a model like `nitdoc`,
# `nitx` or `nituml`.
-# It shoul not be used for compiling stuffs like computing VFT, where the listed
+# It should not be used for compiling stuffs like computing VFT, where the listed
# entities could not be reachable depending on the modules really imported.
module model_collect
-import model
+import model_views
redef class MEntity
- # Collect mentities with a fully qualified `namespace`.
- fun collect_by_namespace(namespace: String): Array[MEntity] is abstract
+ # FIXME used to bypass RTA limitation on type resolution.
+ type MENTITY: SELF
- private fun lookup_in(mentities: Collection[MEntity], namespace: String, res: Array[MEntity]) do
- var parts = namespace.split_once_on("::")
- var name = parts.shift
- for mentity in mentities do
- if mentity.name != name then continue
- if parts.is_empty then
- res.add mentity
- else
- res.add_all mentity.collect_by_namespace(parts.first)
+ # Collect modifier keywords like `redef`, `private` etc.
+ fun collect_modifiers: Array[String] do
+ return new Array[String]
+ end
+
+ # Collect `self` linearization anchored on `mainmodule`.
+ fun collect_linearization(mainmodule: MModule): nullable Array[MEntity] do
+ return null
+ end
+
+ # Collect `self` ancestors (direct and indirect).
+ #
+ # The concept of ancestor is abstract at this stage.
+ fun collect_ancestors(view: ModelView): Set[MENTITY] do
+ var done = new HashSet[MENTITY]
+ var todo = new Array[MENTITY]
+
+ todo.add_all collect_parents(view)
+ while todo.not_empty do
+ var mentity = todo.pop
+ if mentity == self or done.has(mentity) then continue
+ print "{mentity} == {self}"
+ done.add mentity
+ todo.add_all mentity.collect_parents(view)
+ end
+ return done
+ end
+
+ # Collect `self` parents (direct ancestors).
+ #
+ # The concept of parent is abstract at this stage.
+ fun collect_parents(view: ModelView): Set[MENTITY] is abstract
+
+ # Collect `self` children (direct descendants).
+ #
+ # The concept of child is abstract at this stage.
+ fun collect_children(view: ModelView): Set[MENTITY] is abstract
+
+ # Collect `self` descendants (direct and direct).
+ #
+ # The concept of descendant is abstract at this stage.
+ fun collect_descendants(view: ModelView): Set[MENTITY] do
+ var done = new HashSet[MENTITY]
+ var todo = new Array[MENTITY]
+
+ todo.add_all collect_children(view)
+ while todo.not_empty do
+ var mentity = todo.pop
+ if mentity == self or done.has(mentity) then continue
+ done.add mentity
+ todo.add_all mentity.collect_children(view)
+ end
+ return done
+ end
+
+ # Build a poset representing `self` in it's own hierarchy.
+ #
+ # The notion of hierarchy depends on the type of MEntity.
+ #
+ # Here a recap:
+ # * MPackage: package dependencies
+ # * MGroup: group dependencies
+ # * MModule: modules imports
+ # * MClass: class inheritance (all classdefs flattened)
+ # * MClassDef: classdef inheritance
+ # * MProperty: property definitions graph (all propdefs flattened)
+ # * MPropDef: property definitions graph
+ fun hierarchy_poset(view: ModelView): POSet[MENTITY] do
+ var done = new HashSet[MENTITY]
+ var mentities = new Array[MENTITY]
+ mentities.add self
+ var poset = new POSet[MENTITY]
+ while mentities.not_empty do
+ var mentity = mentities.pop
+ if done.has(mentity) then continue
+ done.add mentity
+ poset.add_node mentity
+ for parent in mentity.collect_parents(view) do
+ poset.add_edge(mentity, parent)
+ mentities.add parent
+ end
+ for child in mentity.collect_children(view) do
+ poset.add_edge(child, mentity)
+ mentities.add child
end
end
+ return poset
end
end
-redef class Model
- redef fun collect_by_namespace(namespace) do
- var res = new Array[MEntity]
- var parts = namespace.split_once_on("::")
- var name = parts.shift
- for mentity in mpackages do
- if mentity.name != name then continue
- if parts.is_empty then
- res.add mentity
- else
- res.add_all mentity.collect_by_namespace(parts.first)
+redef class MPackage
+ redef fun collect_modifiers do
+ var res = super
+ res.add "package"
+ return res
+ end
+
+ # `MPackage` parents are its direct dependencies.
+ redef fun collect_parents(view) do
+ var res = new HashSet[MENTITY]
+ for mgroup in mgroups do
+ for parent in mgroup.collect_parents(view) do
+ var mpackage = parent.mpackage
+ if mpackage == self or not view.accept_mentity(mpackage) then continue
+ res.add(mpackage)
end
end
return res
end
-end
-redef class MPackage
- redef fun collect_by_namespace(namespace) do
- var res = new Array[MEntity]
- var root = self.root
- if root == null then return res
- lookup_in([root], namespace, res)
+ # `MPackage` children are packages that directly depends on `self`.
+ redef fun collect_children(view) do
+ var res = new HashSet[MENTITY]
+ for mpackage in view.mpackages do
+ if mpackage.collect_parents(view).has(self) then res.add mpackage
+ end
return res
end
end
redef class MGroup
- redef fun collect_by_namespace(namespace) do
- var res = new Array[MEntity]
- lookup_in(in_nesting.direct_smallers, namespace, res)
- lookup_in(mmodules, namespace, res)
+ redef fun collect_modifiers do
+ var res = super
+ res.add "group"
+ return res
+ end
+
+ # `MGroup` parents are its direct dependencies.
+ redef fun collect_parents(view) do
+ var res = new HashSet[MENTITY]
+ for mmodule in mmodules do
+ for parent in mmodule.collect_parents(view) do
+ var mgroup = parent.mgroup
+ if mgroup == null or mgroup == self then continue
+ if not view.accept_mentity(mgroup) then continue
+ res.add(mgroup)
+ end
+ end
+ return res
+ end
+
+ # `MGroup` children are mgroups that directly depends on `self`.
+ redef fun collect_children(view) do
+ var res = new HashSet[MENTITY]
+ for mgroup in view.mgroups do
+ if mgroup == self or not view.accept_mentity(mgroup) then continue
+ if mgroup.collect_parents(view).has(self) then res.add mgroup
+ end
return res
end
end
redef class MModule
- redef fun collect_by_namespace(namespace) do
- var res = new Array[MEntity]
- lookup_in(mclassdefs, namespace, res)
+ redef fun collect_modifiers do
+ var res = super
+ res.add "module"
+ return res
+ end
+
+ # `MModule` ancestors are all its transitive imports.
+ redef fun collect_ancestors(view) do
+ var res = new HashSet[MENTITY]
+ for mentity in in_importation.greaters do
+ if mentity == self then continue
+ if not view.accept_mentity(mentity) then continue
+ res.add mentity
+ end
+ return res
+ end
+
+ # `MModule` parents are all its direct imports.
+ redef fun collect_parents(view) do
+ var res = new HashSet[MENTITY]
+ for mentity in in_importation.direct_greaters do
+ if mentity == self then continue
+ if not view.accept_mentity(mentity) then continue
+ res.add mentity
+ end
+ return res
+ end
+
+ # `MModule` children are modules that directly import `self`.
+ redef fun collect_children(view) do
+ var res = new HashSet[MENTITY]
+ for mentity in in_importation.direct_smallers do
+ if mentity == self then continue
+ if not view.accept_mentity(mentity) then continue
+ res.add mentity
+ end
+ return res
+ end
+
+ # `MModule` children are modules that transitively import `self`.
+ redef fun collect_descendants(view) do
+ var res = new HashSet[MENTITY]
+ for mentity in in_importation.smallers do
+ if mentity == self then continue
+ if not view.accept_mentity(mentity) then continue
+ res.add mentity
+ end
return res
end
# Collect mclassdefs introduced in `self` with `visibility >= to min_visibility`.
- fun collect_intro_mclassdefs(min_visibility: MVisibility): Set[MClassDef] do
+ fun collect_intro_mclassdefs(view: ModelView): Set[MClassDef] do
var res = new HashSet[MClassDef]
for mclassdef in mclassdefs do
if not mclassdef.is_intro then continue
- if mclassdef.mclass.visibility < min_visibility then continue
+ if not view.accept_mentity(mclassdef) then continue
res.add mclassdef
end
return res
end
# Collect mclassdefs redefined in `self` with `visibility >= to min_visibility`.
- fun collect_redef_mclassdefs(min_visibility: MVisibility): Set[MClassDef] do
+ fun collect_redef_mclassdefs(view: ModelView): Set[MClassDef] do
var res = new HashSet[MClassDef]
for mclassdef in mclassdefs do
if mclassdef.is_intro then continue
- if mclassdef.mclass.visibility < min_visibility then continue
+ if not view.accept_mentity(mclassdef) then continue
res.add mclassdef
end
return res
end
# Collect mclasses introduced in `self` with `visibility >= to min_visibility`.
- fun collect_intro_mclasses(min_visibility: MVisibility): Set[MClass] do
+ fun collect_intro_mclasses(view: ModelView): Set[MClass] do
var res = new HashSet[MClass]
for mclass in intro_mclasses do
- if mclass.visibility < min_visibility then continue
+ if not view.accept_mentity(mclass) then continue
res.add mclass
end
return res
end
# Collect mclasses redefined in `self` with `visibility >= to min_visibility`.
- fun collect_redef_mclasses(min_visibility: MVisibility): Set[MClass] do
+ fun collect_redef_mclasses(view: ModelView): Set[MClass] do
var mclasses = new HashSet[MClass]
- for c in mclassdefs do
- if c.mclass.visibility < min_visibility then continue
- if not c.is_intro then mclasses.add(c.mclass)
+ for mclassdef in mclassdefs do
+ if not view.accept_mentity(mclassdef) then continue
+ if not mclassdef.is_intro then mclasses.add(mclassdef.mclass)
end
return mclasses
end
redef class MClass
- # Collect direct parents of `self` with `visibility >= to min_visibility`.
- fun collect_parents(min_visibility: MVisibility): Set[MClass] do
- var res = new HashSet[MClass]
- for mclassdef in mclassdefs do
- for mclasstype in mclassdef.supertypes do
- var mclass = mclasstype.mclass
- if mclass.visibility < min_visibility then continue
- res.add(mclass)
- end
- end
- return res
+ 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` with `visibility >= to min_visibility`.
- fun collect_ancestors(min_visibility: MVisibility): Set[MClass] do
- var res = new HashSet[MClass]
- for mclassdef in self.mclassdefs do
- for super_mclassdef in mclassdef.in_hierarchy.greaters do
- if super_mclassdef == mclassdef then continue # skip self
- var mclass = super_mclassdef.mclass
- if mclass.visibility < min_visibility then continue
- res.add(mclass)
+ # `MClass` parents are the direct parents of `self`.
+ #
+ # This method uses a flattened hierarchy containing all the mclassdefs.
+ redef fun collect_parents(view) do
+ var res = new HashSet[MENTITY]
+ for mclassdef in mclassdefs do
+ for parent in mclassdef.collect_parents(view) do
+ var mclass = parent.mclass
+ if mclass == self or not view.accept_mentity(parent) then continue
+ res.add mclass
end
end
return res
end
- # Collect direct children of `self` with `visibility >= to min_visibility`.
- fun collect_children(min_visibility: MVisibility): Set[MClass] do
- var res = new HashSet[MClass]
- for mclassdef in self.mclassdefs do
- for sub_mclassdef in mclassdef.in_hierarchy.direct_smallers do
- if sub_mclassdef == mclassdef then continue # skip self
- var mclass = sub_mclassdef.mclass
- if mclass.visibility < min_visibility then continue
- res.add(mclass)
+ # Collect all ancestors of `self` with `visibility >= to min_visibility`.
+ redef fun collect_ancestors(view) do
+ var res = new HashSet[MENTITY]
+ for mclassdef in mclassdefs do
+ for parent in mclassdef.collect_parents(view) do
+ if not view.accept_mentity(parent) then continue
+ res.add parent.mclass
end
end
return res
end
- # Collect all descendants of `self` with `visibility >= to min_visibility`.
- fun descendants(min_visibility: MVisibility): Set[MClass] do
- var res = new HashSet[MClass]
- for mclassdef in self.mclassdefs do
- for sub_mclassdef in mclassdef.in_hierarchy.smallers do
- if sub_mclassdef == mclassdef then continue # skip self
- var mclass = sub_mclassdef.mclass
- if mclass.visibility < min_visibility then continue
- res.add(mclass)
+ # `MClass` parents are the direct parents of `self`.
+ #
+ # This method uses a flattened hierarchy containing all the mclassdefs.
+ redef fun collect_children(view) do
+ var res = new HashSet[MENTITY]
+ for mclassdef in mclassdefs do
+ for child in mclassdef.collect_children(view) do
+ var mclass = child.mclass
+ if mclass == self or not view.accept_mentity(child) then continue
+ res.add mclass
end
end
return res
end
# Collect all mproperties introduced in 'self' with `visibility >= min_visibility`.
- fun collect_intro_mproperties(min_visibility: MVisibility): Set[MProperty] do
+ fun collect_intro_mproperties(view: ModelView): Set[MProperty] do
var set = new HashSet[MProperty]
for mclassdef in mclassdefs do
for mprop in mclassdef.intro_mproperties do
- if mprop.visibility < min_visibility then continue
+ if not view.accept_mentity(mprop) then continue
set.add(mprop)
end
end
end
# Collect all mproperties redefined in 'self' with `visibility >= min_visibility`.
- fun collect_redef_mproperties(min_visibility: MVisibility): Set[MProperty] do
+ fun collect_redef_mproperties(view: ModelView): Set[MProperty] do
var set = new HashSet[MProperty]
for mclassdef in mclassdefs do
for mpropdef in mclassdef.mpropdefs do
- if mpropdef.mproperty.visibility < min_visibility then continue
- if mpropdef.mproperty.intro_mclassdef.mclass != self then set.add(mpropdef.mproperty)
+ if mpropdef.mproperty.intro_mclassdef.mclass == self then continue
+ if not view.accept_mentity(mpropdef) then continue
+ set.add(mpropdef.mproperty)
end
end
return set
end
# Collect mproperties introduced and redefined in 'self' with `visibility >= min_visibility`.
- fun collect_local_mproperties(min_visibility: MVisibility): Set[MProperty] do
+ fun collect_local_mproperties(view: ModelView): Set[MProperty] do
var set = new HashSet[MProperty]
- set.add_all collect_intro_mproperties(min_visibility)
- set.add_all collect_redef_mproperties(min_visibility)
+ set.add_all collect_intro_mproperties(view)
+ set.add_all collect_redef_mproperties(view)
return set
end
# Collect all mproperties inehrited by 'self' with `visibility >= min_visibility`.
- fun collect_inherited_mproperties(min_visibility: MVisibility): Set[MProperty] do
+ fun collect_inherited_mproperties(view: ModelView): Set[MProperty] do
var set = new HashSet[MProperty]
- for parent in collect_parents(min_visibility) do
- set.add_all(parent.collect_intro_mproperties(min_visibility))
- set.add_all(parent.collect_inherited_mproperties(min_visibility))
+ for parent in collect_parents(view) do
+ set.add_all(parent.collect_intro_mproperties(view))
+ set.add_all(parent.collect_inherited_mproperties(view))
end
return set
end
# Collect all mproperties accessible by 'self' with `visibility >= min_visibility`.
#
# This include introduced, redefined, inherited mproperties.
- fun collect_accessible_mproperties(min_visibility: MVisibility): Set[MProperty] do
+ fun collect_accessible_mproperties(view: ModelView): Set[MProperty] do
var set = new HashSet[MProperty]
- set.add_all(collect_intro_mproperties(min_visibility))
- set.add_all(collect_redef_mproperties(min_visibility))
- set.add_all(collect_inherited_mproperties(min_visibility))
+ set.add_all(collect_intro_mproperties(view))
+ set.add_all(collect_redef_mproperties(view))
+ set.add_all(collect_inherited_mproperties(view))
return set
end
# Collect mmethods introduced in 'self' with `visibility >= min_visibility`.
- fun collect_intro_mmethods(min_visibility: MVisibility): Set[MMethod] do
+ fun collect_intro_mmethods(view: ModelView): Set[MMethod] do
var res = new HashSet[MMethod]
- for mproperty in collect_intro_mproperties(min_visibility) do
+ for mproperty in collect_intro_mproperties(view) do
if mproperty isa MMethod then res.add(mproperty)
end
return res
end
# Collect mmethods redefined in 'self' with `visibility >= min_visibility`.
- fun collect_redef_mmethods(min_visibility: MVisibility): Set[MMethod] do
+ fun collect_redef_mmethods(view: ModelView): Set[MMethod] do
var res = new HashSet[MMethod]
- for mproperty in collect_redef_mproperties(min_visibility) do
+ for mproperty in collect_redef_mproperties(view) do
if mproperty isa MMethod then res.add(mproperty)
end
return res
end
# Collect mmethods introduced and redefined in 'self' with `visibility >= min_visibility`.
- fun collect_local_mmethods(min_visibility: MVisibility): Set[MMethod] do
+ fun collect_local_mmethods(view: ModelView): Set[MMethod] do
var set = new HashSet[MMethod]
- set.add_all collect_intro_mmethods(min_visibility)
- set.add_all collect_redef_mmethods(min_visibility)
+ set.add_all collect_intro_mmethods(view)
+ set.add_all collect_redef_mmethods(view)
+ return set
+ end
+
+ # Collect mmethods inherited by 'self' if accepted by `view`.
+ fun collect_inherited_mmethods(view: ModelView): Set[MMethod] do
+ var res = new HashSet[MMethod]
+ for mproperty in collect_inherited_mproperties(view) do
+ if mproperty isa MMethod then res.add(mproperty)
+ end
+ return res
+ end
+
+ # Collect all mmethods accessible by 'self' with `visibility >= min_visibility`.
+ #
+ # This include introduced, redefined, inherited mmethods.
+ fun collect_accessible_mmethods(view: ModelView): Set[MMethod] do
+ var set = new HashSet[MMethod]
+ set.add_all(collect_intro_mmethods(view))
+ set.add_all(collect_redef_mmethods(view))
+ set.add_all(collect_inherited_mmethods(view))
return set
end
# Collect mattributes introduced in 'self' with `visibility >= min_visibility`.
- fun collect_intro_mattributes(min_visibility: MVisibility): Set[MAttribute] do
+ fun collect_intro_mattributes(view: ModelView): Set[MAttribute] do
var res = new HashSet[MAttribute]
- for mproperty in collect_intro_mproperties(min_visibility) do
+ for mproperty in collect_intro_mproperties(view) do
if mproperty isa MAttribute then res.add(mproperty)
end
return res
end
# Collect mattributes redefined in 'self' with `visibility >= min_visibility`.
- fun collect_redef_mattributes(min_visibility: MVisibility): Set[MAttribute] do
+ fun collect_redef_mattributes(view: ModelView): Set[MAttribute] do
var res = new HashSet[MAttribute]
- for mproperty in collect_redef_mproperties(min_visibility) do
+ for mproperty in collect_redef_mproperties(view) do
if mproperty isa MAttribute then res.add(mproperty)
end
return res
end
# Collect mattributes introduced and redefined in 'self' with `visibility >= min_visibility`.
- fun collect_local_mattributes(min_visibility: MVisibility): Set[MAttribute] do
+ fun collect_local_mattributes(view: ModelView): Set[MAttribute] do
var set = new HashSet[MAttribute]
- set.add_all collect_intro_mattributes(min_visibility)
- set.add_all collect_redef_mattributes(min_visibility)
+ set.add_all collect_intro_mattributes(view)
+ set.add_all collect_redef_mattributes(view)
return set
end
# Collect mattributes inherited by 'self' with `visibility >= min_visibility`.
- fun collect_inherited_mattributes(min_visibility: MVisibility): Set[MAttribute] do
+ fun collect_inherited_mattributes(view: ModelView): Set[MAttribute] do
var res = new HashSet[MAttribute]
- for mproperty in collect_inherited_mproperties(min_visibility) do
+ for mproperty in collect_inherited_mproperties(view) do
if mproperty isa MAttribute then res.add(mproperty)
end
return res
# Collect all mattributes accessible by 'self' with `visibility >= min_visibility`.
#
# This include introduced, redefined, inherited mattributes.
- fun collect_accessible_mattributes(min_visibility: MVisibility): Set[MAttribute] do
+ fun collect_accessible_mattributes(view: ModelView): Set[MAttribute] do
var set = new HashSet[MAttribute]
- set.add_all(collect_intro_mattributes(min_visibility))
- set.add_all(collect_redef_mattributes(min_visibility))
- set.add_all(collect_inherited_mattributes(min_visibility))
+ set.add_all(collect_intro_mattributes(view))
+ set.add_all(collect_redef_mattributes(view))
+ set.add_all(collect_inherited_mattributes(view))
+ return set
+ end
+
+ # Collect init mmethods introduced in 'self' if accepted by `view`.
+ fun collect_intro_inits(view: ModelView): Set[MMethod] do
+ var res = new HashSet[MMethod]
+ for mproperty in collect_intro_mmethods(view) do
+ if mproperty.is_init then res.add(mproperty)
+ end
+ return res
+ end
+
+ # Collect init mmethods redefined in 'self' if accepted by `view`.
+ fun collect_redef_inits(view: ModelView): Set[MMethod] do
+ var res = new HashSet[MMethod]
+ for mproperty in collect_redef_mmethods(view) do
+ if mproperty.is_init then res.add(mproperty)
+ end
+ return res
+ end
+
+ # Collect init mmethods introduced and redefined in 'self' if accepted by `view`.
+ fun collect_local_inits(view: ModelView): Set[MMethod] do
+ var set = new HashSet[MMethod]
+ set.add_all collect_intro_inits(view)
+ set.add_all collect_redef_inits(view)
+ return set
+ end
+
+ # Collect init mmethods inherited by 'self' if accepted by `view`.
+ fun collect_inherited_inits(view: ModelView): Set[MMethod] do
+ var res = new HashSet[MMethod]
+ for mproperty in collect_inherited_mmethods(view) do
+ if mproperty.is_init then res.add(mproperty)
+ end
+ return res
+ end
+
+ # Collect all init mmethods accessible by 'self' if accepted by `view`.
+ #
+ # This include introduced, redefined, inherited inits.
+ fun collect_accessible_inits(view: ModelView): Set[MMethod] do
+ var set = new HashSet[MMethod]
+ set.add_all(collect_intro_inits(view))
+ set.add_all(collect_redef_inits(view))
+ set.add_all(collect_inherited_inits(view))
+ return set
+ end
+
+ # Collect all virtual types accessible by 'self' if accepted by `view`.
+ #
+ # This include introduced, redefined, inherited virtual types.
+ fun collect_accessible_vts(view: ModelView): Set[MVirtualTypeProp] do
+ var set = new HashSet[MVirtualTypeProp]
+ for mproperty in collect_accessible_mproperties(view) do
+ if mproperty isa MVirtualTypeProp then set.add mproperty
+ end
return set
end
end
redef class MClassDef
- redef fun collect_by_namespace(namespace) do
- var res = new Array[MEntity]
- lookup_in(mpropdefs, namespace, res)
+ redef fun collect_linearization(mainmodule) do
+ var mclassdefs = new Array[MClassDef]
+ for mclassdef in in_hierarchy.as(not null).greaters do
+ if mclassdef.mclass == self.mclass then mclassdefs.add mclassdef
+ end
+ mainmodule.linearize_mclassdefs(mclassdefs)
+ return mclassdefs
+ end
+
+ # `MClassDef` ancestors are its direct and transitive super classes.
+ redef fun collect_ancestors(view) do
+ var res = new HashSet[MENTITY]
+ var hierarchy = self.in_hierarchy
+ if hierarchy == null then return res
+ for parent in hierarchy.greaters do
+ if parent == self or not view.accept_mentity(parent) then continue
+ res.add parent
+ end
+ return res
+ end
+
+ # `MClassDef` parents are its direct super classes.
+ redef fun collect_parents(view) do
+ var res = new HashSet[MENTITY]
+ var hierarchy = self.in_hierarchy
+ if hierarchy == null then return res
+ for parent in hierarchy.direct_greaters do
+ if parent == self or not view.accept_mentity(parent) then continue
+ res.add parent
+ end
+ return res
+ end
+
+ # `MClassDef` children are its direct subclasses.
+ redef fun collect_children(view) do
+ var res = new HashSet[MENTITY]
+ var hierarchy = self.in_hierarchy
+ if hierarchy == null then return res
+ for child in hierarchy.direct_smallers do
+ if child == self or not view.accept_mentity(child) then continue
+ res.add child
+ end
return res
end
# Collect mpropdefs in 'self' with `visibility >= min_visibility`.
- fun collect_mpropdefs(min_visibility: MVisibility): Set[MPropDef] do
+ fun collect_mpropdefs(view: ModelView): Set[MPropDef] do
var res = new HashSet[MPropDef]
for mpropdef in mpropdefs do
- if mpropdef.mproperty.visibility < min_visibility then continue
+ if not view.accept_mentity(mpropdef) then continue
res.add mpropdef
end
return res
end
# Collect mpropdefs introduced in 'self' with `visibility >= min_visibility`.
- fun collect_intro_mpropdefs(min_visibility: MVisibility): Set[MPropDef] do
+ fun collect_intro_mpropdefs(view: ModelView): Set[MPropDef] do
var res = new HashSet[MPropDef]
for mpropdef in mpropdefs do
if not mpropdef.is_intro then continue
- if mpropdef.mproperty.visibility < min_visibility then continue
+ if not view.accept_mentity(mpropdef) then continue
res.add mpropdef
end
return res
end
# Collect mpropdefs redefined in 'self' with `visibility >= min_visibility`.
- fun collect_redef_mpropdefs(min_visibility: MVisibility): Set[MPropDef] do
+ fun collect_redef_mpropdefs(view: ModelView): Set[MPropDef] do
var res = new HashSet[MPropDef]
for mpropdef in mpropdefs do
if mpropdef.is_intro then continue
- if mpropdef.mproperty.visibility < min_visibility then continue
+ if not view.accept_mentity(mpropdef) then continue
res.add mpropdef
end
return res
end
- # Collect modifiers like redef, private etc.
- fun collect_modifiers: Array[String] do
- var res = new Array[String]
+ redef fun collect_modifiers do
+ var res = super
if not is_intro then
res.add "redef"
else
end
end
+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 mpropdefs in 'self' with `visibility >= min_visibility`.
+ fun collect_mpropdefs(view: ModelView): Set[MPropDef] do
+ var res = new HashSet[MPropDef]
+ for mpropdef in mpropdefs do
+ if not view.accept_mentity(mpropdef) then continue
+ res.add mpropdef
+ end
+ return res
+ end
+
+ # `MProperty` parents are all direct super definition of `self`.
+ #
+ # This method uses a flattened hierarchy containing all the mpropdefs.
+ redef fun collect_parents(view) do
+ var res = new HashSet[MENTITY]
+ for mpropdef in mpropdefs do
+ for parent in mpropdef.collect_parents(view) do
+ if not view.accept_mentity(parent) then continue
+ res.add parent.mproperty
+ end
+ end
+ return res
+ end
+
+ # `MProperty` parents are all direct sub definition of `self`.
+ #
+ # This method uses a flattened hierarchy containing all the mpropdefs.
+ redef fun collect_children(view) do
+ var res = new HashSet[MENTITY]
+ for mpropdef in mpropdefs do
+ for child in mpropdef.collect_parents(view) do
+ if not view.accept_mentity(child) then continue
+ res.add child.mproperty
+ end
+ end
+ return res
+ end
+end
+
redef class MPropDef
- # Collect modifiers like redef, private, abstract, intern, fun etc.
- fun collect_modifiers: Array[String] do
- var res = new Array[String]
+ redef fun collect_modifiers do
+ var res = super
if not is_intro then
res.add "redef"
else
else
res.add "fun"
end
+ else if mprop isa MAttributeDef then
+ res.add "var"
+ end
+ return res
+ end
+
+ redef fun collect_linearization(mainmodule) do
+ var mpropdefs = new Array[MPropDef]
+ var mentity = self
+ while not mentity.is_intro do
+ mpropdefs.add mentity
+ mentity = mentity.lookup_next_definition(mainmodule, mentity.mclassdef.bound_mtype)
+ end
+ mpropdefs.add mentity
+ mainmodule.linearize_mpropdefs(mpropdefs)
+ return mpropdefs
+ end
+
+ # `MPropDef` parents include only the next definition of `self`.
+ redef fun collect_parents(view) do
+ var res = new HashSet[MENTITY]
+ var mpropdef = self
+ while not mpropdef.is_intro do
+ mpropdef = mpropdef.lookup_next_definition(mclassdef.mmodule, mclassdef.bound_mtype)
+ res.add mpropdef
+ end
+ return res
+ end
+
+ # `MPropdef` children are definitions that directly depends on `self`.
+ redef fun collect_children(view) do
+ var res = new HashSet[MENTITY]
+ for mpropdef in mproperty.collect_mpropdefs(view) do
+ if mpropdef.collect_parents(view).has(self) then res.add mpropdef
end
return res
end