# 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]
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]
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]
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]
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
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