X-Git-Url: http://nitlanguage.org diff --git a/src/model_utils.nit b/src/model_utils.nit index 545ea69..b2c741b 100644 --- a/src/model_utils.nit +++ b/src/model_utils.nit @@ -17,10 +17,34 @@ # Model exploration and traversing facilities module model_utils -import toolcontext -import exprbuilder +import modelbuilder redef class MModule + + # The list of intro mclassdef in the module. + # with visibility >= to min_visibility + fun intro_mclassdefs(min_visibility: MVisibility): Set[MClassDef] do + var res = new HashSet[MClassDef] + for mclassdef in mclassdefs do + if not mclassdef.is_intro then continue + if mclassdef.mclass.visibility < min_visibility then continue + res.add mclassdef + end + return res + end + + # The list of redef mclassdef in the module. + # with visibility >= to min_visibility + fun redef_mclassdefs(min_visibility: MVisibility): Set[MClassDef] do + var res = new HashSet[MClassDef] + for mclassdef in mclassdefs do + if mclassdef.is_intro then continue + if mclassdef.mclass.visibility < min_visibility then continue + res.add mclassdef + end + return res + end + # Get the list of mclasses refined in 'self'. fun redef_mclasses: Set[MClass] do var mclasses = new HashSet[MClass] @@ -34,14 +58,63 @@ redef class MModule fun imported_mclasses: Set[MClass] do var mclasses = new HashSet[MClass] for m in in_importation.greaters do + if m == self then continue for c in m.mclassdefs do mclasses.add(c.mclass) 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.intro_mclasses 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.redef_mclasses 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 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] @@ -65,6 +138,30 @@ redef class MClass return lst end + # Get direct children of 'self'. + fun children: Set[MClass] do + var lst = new HashSet[MClass] + for mclassdef in self.mclassdefs do + for sub_mclassdef in mclassdef.in_hierarchy.direct_smallers do + if sub_mclassdef == mclassdef then continue # skip self + lst.add(sub_mclassdef.mclass) + end + end + return lst + end + + # Get all children of 'self'. + fun descendants: Set[MClass] do + var lst = new HashSet[MClass] + for mclassdef in self.mclassdefs do + for sub_mclassdef in mclassdef.in_hierarchy.smallers do + if sub_mclassdef == mclassdef then continue # skip self + lst.add(sub_mclassdef.mclass) + end + end + return lst + end + # Get the list of constructors available for 'self'. fun constructors: Set[MMethod] do var res = new HashSet[MMethod] @@ -91,6 +188,89 @@ redef class MClass return res end + # the set of properties introduced in 'self'. + fun intro_mproperties(min_visibility: MVisibility): Set[MProperty] do + var set = new HashSet[MProperty] + for mclassdef in mclassdefs do + for mprop in mclassdef.intro_mproperties do + if mprop.visibility < min_visibility then continue + set.add(mprop) + end + end + 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] + for mclassdef in mclassdefs do + for mpropdef in mclassdef.mpropdefs do + if mpropdef.mproperty.visibility < min_visibility then continue + if mpropdef.mproperty.intro_mclassdef.mclass != self then set.add(mpropdef.mproperty) + end + end + 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] + for parent in in_hierarchy(mainmodule).direct_greaters do + set.add_all(parent.intro_mproperties(min_visibility)) + set.add_all(parent.inherited_mproperties(mainmodule, min_visibility)) + end + return set + end + + # the set of introduced and redefined mproperties + fun local_mproperties(min_visibility: MVisibility): Set[MProperty] do + var set = new HashSet[MProperty] + set.add_all(intro_mproperties(min_visibility)) + set.add_all(redef_mproperties(min_visibility)) + return set + end + + # the set of all accessible mproperties for this class + fun all_mproperties(mainmodule: MModule, min_visibility: MVisibility): Set[MProperty] do + var set = new HashSet[MProperty] + set.add_all(local_mproperties(min_visibility)) + set.add_all(inherited_mproperties(mainmodule, min_visibility)) + return set + end + + # the set of all accessible mattributes for this class + fun all_mattributes(mainmodule: MModule, min_visibility: MVisibility): Set[MAttribute] do + var set = new HashSet[MAttribute] + for mprop in all_mproperties(mainmodule, min_visibility) do + if mprop isa MAttribute then set.add(mprop) + end + return set + end + # Get the list of locally refined methods in 'self'. fun redef_methods: Set[MMethod] do var res = new HashSet[MMethod] @@ -104,7 +284,6 @@ redef class MClass return res end - # Get the list of methods inherited by 'self'. fun inherited_methods: Set[MMethod] do var res = new HashSet[MMethod] for s in ancestors do @@ -162,3 +341,93 @@ redef class MClass return self.kind == abstract_kind end end + +redef class MAttribute + # Is this attribute nullable for sure? + # + # This mean that its introduction is declarred with a nullable static type + # since attributes are invariant this will work on most cases + # attributes with static type anchored with a virtual type are not "nullable for-sure" + # because this type can be redefined in subclasses + fun is_nullable: Bool do return intro.static_mtype isa MNullableType +end + +redef class MClassDef + # modifiers are keywords like redef, private etc. + fun modifiers: Array[String] do + var res = new Array[String] + if not is_intro then + res.add "redef" + else + res.add mclass.visibility.to_s + end + res.add mclass.kind.to_s + return res + end +end + +redef class MPropDef + # modifiers are keywords like redef, private etc. + fun modifiers: Array[String] do + var res = new Array[String] + if not is_intro then + res.add "redef" + else + res.add mproperty.visibility.to_s + end + var mprop = self + if mprop isa MVirtualTypeDef then + res.add "type" + else if mprop isa MMethodDef then + if mprop.is_abstract then + res.add "abstract" + else if mprop.is_intern then + res.add "intern" + end + if mprop.mproperty.is_init then + res.add "init" + else + res.add "fun" + end + end + return res + 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] + 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 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 +end