src: use `as_notnullable` in code
[nit.git] / src / model_utils.nit
index f98e90e..bc8d2cb 100644 (file)
 # 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
@@ -61,6 +86,15 @@ redef class MGroup
                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
@@ -166,6 +200,15 @@ 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
@@ -429,6 +472,35 @@ redef class MClassDef
                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
@@ -459,7 +531,6 @@ redef class MPropDef
        end
 end
 
-
 # Sorters
 
 # Sort mentities by their name
@@ -469,37 +540,24 @@ class MEntityNameSorter
        init do end
 end
 
-# 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]
-       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