# Model exploration and traversing facilities
module model_utils
-import modelbuilder
+import model
+
+redef class MConcern
+
+ # Boost a MConcern rank
+ # see: `MConcernRankSorter`
+ # Use a positive booster to push down a result in the list
+ # A negative booster can be used to push up the result
+ var booster_rank: Int writable = 0
+
+ # Concern ranking used for ordering
+ # see: `MConcernRankSorter`
+ # Rank can be positive or negative
+ fun concern_rank: Int is abstract
+end
+
+redef class MProject
+ redef fun concern_rank do
+ var max = 0
+ for mgroup in mgroups do
+ var mmax = mgroup.concern_rank
+ if mmax > max then max = mmax
+ end
+ return max + 1
+ end
+end
redef class MGroup
fun in_nesting_intro_mclasses(min_visibility: MVisibility): Set[MClass] do
end
return res
end
+
+ redef fun concern_rank do
+ var max = 0
+ for mmodule in collect_mmodules do
+ var mmax = mmodule.concern_rank
+ if mmax > max then max = mmax
+ end
+ return max + 1
+ end
end
redef class MModule
end
return res
end
+
+ redef fun concern_rank do
+ var max = 0
+ for p in in_importation.direct_greaters do
+ var pmax = p.concern_rank
+ if pmax > max then max = pmax
+ end
+ return max + 1
+ end
end
redef class MClass
res.add mclass.kind.to_s
return res
end
+
+ fun collect_mpropdefs(min_visibility: MVisibility): Set[MPropDef] do
+ var res = new HashSet[MPropDef]
+ for mpropdef in mpropdefs do
+ if mpropdef.mproperty.visibility < min_visibility then continue
+ res.add mpropdef
+ end
+ return res
+ end
+
+ fun collect_intro_mpropdefs(min_visibility: MVisibility): 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
+ res.add mpropdef
+ end
+ return res
+ end
+
+ fun collect_redef_mpropdefs(min_visibility: MVisibility): 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
+ res.add mpropdef
+ end
+ return res
+ end
end
redef class MPropDef
end
end
-
# Sorters
-# Sort mmodules by their name
-class MModuleNameSorter
- super AbstractSorter[MModule]
- redef fun compare(a, b) do return a.name <=> b.name
- init do end
-end
-
-# Sort mclasses by their name
-class MClassNameSorter
- super AbstractSorter[MClass]
+# Sort mentities by their name
+class MEntityNameSorter
+ super AbstractSorter[MEntity]
redef fun compare(a, b) do return a.name <=> b.name
init do end
end
-# Sort mclassdefs by their name
-class MClassDefNameSorter
- super AbstractSorter[MClassDef]
- redef fun compare(a, b) do return a.mclass.name <=> b.mclass.name
- init do end
-end
+# Sort MConcerns based on the module importation hierarchy ranking
+# see also: `MConcern::concern_rank` and `MConcern::booster_rank`
+#
+# Comparison is made with the formula:
+#
+# a.concern_rank + a.booster_rank <=> b.concern_rank + b.booster_ran
+#
+# If both `a` and `b` have the same ranking,
+# ordering is based on lexicographic comparison of `a.name` and `b.name`
+class MConcernRankSorter
+ super AbstractSorter[MConcern]
-# Sort mproperties by their name
-class MPropertyNameSorter
- super AbstractSorter[MProperty]
- redef fun compare(a, b) do return a.name <=> b.name
init do end
-end
-# Sort mpropdefs by their name
-class MPropDefNameSorter
- super AbstractSorter[MPropDef]
- redef fun compare(a, b) do return a.mproperty.name <=> b.mproperty.name
- init do end
+ redef fun compare(a, b) do
+ if a.concern_rank == b.concern_rank then
+ return a.name <=> b.name
+ end
+ return a.concern_rank + a.booster_rank <=> b.concern_rank + b.booster_rank
+ end
end