X-Git-Url: http://nitlanguage.org diff --git a/src/model_utils.nit b/src/model_utils.nit index a8be901..51c643c 100644 --- a/src/model_utils.nit +++ b/src/model_utils.nit @@ -17,7 +17,85 @@ # 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 is cached 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 + var res = new HashSet[MClass] + var lst = in_nesting.direct_smallers + for mmodule in mmodules do res.add_all mmodule.filter_intro_mclasses(min_visibility) + for mgrp in lst do res.add_all mgrp.in_nesting_intro_mclasses(min_visibility) + return res + end + + fun in_nesting_redef_mclasses(min_visibility: MVisibility): Set[MClass] do + var res = new HashSet[MClass] + var lst = in_nesting.direct_smallers + for mmodule in mmodules do res.add_all mmodule.filter_redef_mclasses(min_visibility) + for mgrp in lst do res.add_all mgrp.in_nesting_redef_mclasses(min_visibility) + return res + end + + fun in_nesting_intro_mclassdefs(min_visibility: MVisibility): Set[MClassDef] do + var res = new HashSet[MClassDef] + var lst = in_nesting.direct_smallers + for mmodule in mmodules do res.add_all mmodule.intro_mclassdefs(min_visibility) + for mgrp in lst do res.add_all mgrp.in_nesting_intro_mclassdefs(min_visibility) + return res + end + + fun in_nesting_redef_mclassdefs(min_visibility: MVisibility): Set[MClassDef] do + var res = new HashSet[MClassDef] + var lst = in_nesting.direct_smallers + for mmodule in mmodules do res.add_all mmodule.redef_mclassdefs(min_visibility) + for mgrp in lst do res.add_all mgrp.in_nesting_redef_mclassdefs(min_visibility) + return res + end + + # Collect nested modules + fun collect_mmodules: Set[MModule] do + var res = new HashSet[MModule] + res.add_all mmodules + for mgroup in in_nesting.direct_smallers do + res.add_all mgroup.collect_mmodules + end + return res + end + + redef fun concern_rank is cached 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 @@ -45,6 +123,17 @@ redef class MModule return res end + # The list of intro mclass in the module. + # with visibility >= to min_visibility + fun filter_intro_mclasses(min_visibility: MVisibility): Set[MClass] do + var res = new HashSet[MClass] + for mclass in intro_mclasses do + if mclass.visibility < min_visibility then continue + res.add mclass + end + return res + end + # Get the list of mclasses refined in 'self'. fun redef_mclasses: Set[MClass] do var mclasses = new HashSet[MClass] @@ -54,6 +143,16 @@ redef class MModule return mclasses end + # Get the list of mclasses refined in 'self'. + fun filter_redef_mclasses(min_visibility: MVisibility): 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) + end + return mclasses + end + # Get the list of all mclasses imported by 'self'. fun imported_mclasses: Set[MClass] do var mclasses = new HashSet[MClass] @@ -63,6 +162,53 @@ redef class MModule end 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 is cached 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 @@ -162,6 +308,18 @@ redef class MClass return set end + fun intro_mpropdefs(min_visibility: MVisibility): Set[MPropDef] do + var set = new HashSet[MPropDef] + for mclassdef in mclassdefs do + for mpropdef in mclassdef.mpropdefs do + if not mpropdef.is_intro then continue + if mpropdef.mproperty.visibility < min_visibility then continue + set.add(mpropdef) + end + end + return set + end + # the set of locally refined properties in 'self'. fun redef_mproperties(min_visibility: MVisibility): Set[MProperty] do var set = new HashSet[MProperty] @@ -174,6 +332,18 @@ redef class MClass return set end + fun redef_mpropdefs(min_visibility: MVisibility): Set[MPropDef] do + var set = new HashSet[MPropDef] + for mclassdef in mclassdefs do + for mpropdef in mclassdef.mpropdefs do + if mpropdef.is_intro then continue + if mpropdef.mproperty.visibility < min_visibility then continue + set.add(mpropdef) + end + end + return set + end + # the set of methods inherited by 'self'. fun inherited_mproperties(mainmodule: MModule, min_visibility: MVisibility): Set[MProperty] do var set = new HashSet[MProperty] @@ -302,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 @@ -332,40 +531,33 @@ redef class MPropDef end end - # Sorters -# Sort mmodules by their name -class MModuleNameSorter - super AbstractSorter[MModule] +# 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 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