model_utils: extract mclasses and mclassdefs from MProject and Mgroup
[nit.git] / src / model_utils.nit
index df90150..f73ed8b 100644 (file)
 # Model exploration and traversing facilities
 module model_utils
 
-import toolcontext
-import exprbuilder
+import modelbuilder
+
+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.intro_mclasses
+               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.redef_mclasses
+               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
+end
 
 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]
@@ -40,18 +98,57 @@ redef class MModule
                return mclasses
        end
 
-       # Get all mclasses in 'self' with their state
-       fun mclasses: HashMap[MClass, Int] do
-               var mclasses = new HashMap[MClass, Int]
-               for c in intro_mclasses do mclasses[c] = c_is_intro
-               for r in redef_mclasses do mclasses[r] = c_is_refined
-               for i in imported_mclasses do mclasses[i] = c_is_imported
-               return mclasses
+       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]
@@ -125,6 +222,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]
@@ -138,7 +318,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
@@ -197,7 +376,92 @@ redef class MClass
        end
 end
 
-# MClass State
-fun c_is_intro: Int do return 1
-fun c_is_refined: Int do return 2
-fun c_is_imported: Int do return 3
+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