X-Git-Url: http://nitlanguage.org diff --git a/src/model_utils.nit b/src/model_utils.nit index be3fd4d..24105e6 100644 --- a/src/model_utils.nit +++ b/src/model_utils.nit @@ -17,7 +17,32 @@ # 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 = 0 is writable + + # Concern ranking used for ordering + # see: `MConcernRankSorter` + # Rank can be positive or negative + fun concern_rank: Int is abstract +end + +redef class MProject + redef var concern_rank is lazy 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 var concern_rank is lazy 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 @@ -129,40 +163,28 @@ redef class MModule 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 + redef var concern_rank is lazy 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 res + return max + 1 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) + # 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 - 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) + 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 @@ -170,16 +192,6 @@ 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 - end - end - # Get direct parents of 'self'. fun parents: Set[MClass] do var ret = new HashSet[MClass] @@ -384,8 +396,8 @@ redef class MClass # 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 @@ -429,6 +441,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,40 +500,34 @@ redef class MPropDef end end - # Sorters -# Sort mmodules by their name -class MModuleNameSorter - super AbstractSorter[MModule] +# Sort mentities by their name +class MEntityNameSorter + super Comparator + redef type COMPARED: MEntity 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 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 MConcerns based on the module importation hierarchy ranking +# see also: `MConcern::concern_rank` and `MConcern::booster_rank` +# +# Comparison is made with the formula: +# +# ~~~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 Comparator + redef type COMPARED: MConcern -# 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