# Model exploration and traversing facilities
module model_utils
-import modelbuilder
+import model
redef class MConcern
# 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
+ var booster_rank: Int = 0 is writable
# Concern ranking used for ordering
# see: `MConcernRankSorter`
end
redef class MProject
- redef fun concern_rank do
+ redef fun concern_rank is cached do
var max = 0
for mgroup in mgroups do
var mmax = mgroup.concern_rank
return res
end
- redef fun concern_rank do
+ redef fun concern_rank is cached do
var max = 0
for mmodule in collect_mmodules do
var mmax = mmodule.concern_rank
return mclasses
end
- fun in_nesting_intro_mclasses(min_visibility: MVisibility): Set[MClass] do
- var res = new HashSet[MClass]
- for mmodule in in_nesting.greaters do
- for mclass in mmodule.filter_intro_mclasses(min_visibility) do
- if mclass.visibility < min_visibility then continue
- res.add mclass
- end
- end
- return res
- end
-
- fun in_nesting_redef_mclasses(min_visibility: MVisibility): Set[MClass] do
- var res = new HashSet[MClass]
- for mmodule in self.in_nesting.greaters do
- for mclass in mmodule.filter_redef_mclasses(min_visibility) do
- if mclass.visibility < min_visibility then continue
- res.add mclass
- end
- end
- return res
- end
-
- fun in_nesting_intro_mclassdefs(min_visibility: MVisibility): Set[MClassDef] do
- var res = new HashSet[MClassDef]
- for mmodule in in_nesting.greaters do
- res.add_all mmodule.intro_mclassdefs(min_visibility)
- end
- return res
- end
-
- fun in_nesting_redef_mclassdefs(min_visibility: MVisibility): Set[MClassDef] do
- var res = new HashSet[MClassDef]
- for mmodule in self.in_nesting.greaters do
- res.add_all mmodule.redef_mclassdefs(min_visibility)
- end
- return res
- end
-
- redef fun concern_rank do
+ redef fun concern_rank is cached do
var max = 0
for p in in_importation.direct_greaters do
var pmax = p.concern_rank
end
return max + 1
end
-end
-redef class MClass
-
- # Get the public owner of 'self'.
- fun public_owner: MModule do
- var public_owner = self.intro_mmodule.public_owner
- if public_owner == null then
- return self.intro_mmodule
- else
- return public_owner
+ # Find all mmodules nested in `self` if `self` is the default module of a `MGroup`.
+ fun nested_mmodules: Array[MModule] do
+ var res = new Array[MModule]
+ var mgroup = mgroup
+ if mgroup == null or self != mgroup.default_mmodule then return res
+ for mmodule in mgroup.mmodules do
+ if mmodule == self then continue
+ res.add mmodule
end
+ for nested in mgroup.in_nesting.direct_smallers do
+ var default = nested.default_mmodule
+ if default == null then continue
+ res.add default
+ end
+ return res
end
+end
+
+redef class MClass
# Get direct parents of 'self'.
fun parents: Set[MClass] do
# Get the list of all parameter types in 'self'.
fun parameter_types: Map[String, MType] do
var res = new HashMap[String, MType]
- for i in [0..intro.parameter_names.length[ do
- res[intro.parameter_names[i]] = intro.bound_mtype.arguments[i]
+ for p in mparameters do
+ res[p.name] = p
end
return res
end
# Sort mentities by their name
class MEntityNameSorter
- super AbstractSorter[MEntity]
+ super Comparator
+ redef type COMPARED: MEntity
redef fun compare(a, b) do return a.name <=> b.name
- init do end
end
# Sort MConcerns based on the module importation hierarchy ranking
#
# Comparison is made with the formula:
#
-# a.concern_rank + a.booster_rank <=> b.concern_rank + b.booster_ran
+# ~~~nitish
+# 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]
-
- init do end
+ super Comparator
+ redef type COMPARED: MConcern
redef fun compare(a, b) do
if a.concern_rank == b.concern_rank then