Merge: Loose Tokens
[nit.git] / src / metrics / mendel_metrics.nit
index 65e104f..23daf06 100644 (file)
 #  in Proceedings of the 16th IEEE International Conference on Program Comprehension (OCPC'08)
 module mendel_metrics
 
-import model
 import metrics_base
 import mclasses_metrics
-import phase
-import frontend
+import modelize
 
 redef class ToolContext
+       # Compute MENDEL metrics.
+       #
+       # See `mendel_metrics` module documentation.
        var mendel_metrics_phase: Phase = new MendelMetricsPhase(self, null)
 end
 
@@ -83,28 +84,33 @@ private class MendelMetricsPhase
                metrics.collect(mclasses)
                if csv then metrics.to_csv.save("{out}/mendel.csv")
 
-               print toolcontext.format_h4("\tlarge mclasses (threshold: {cnblp.threshold})")
-               for mclass in cnblp.above_threshold do
-                       print toolcontext.format_p("\t   {mclass.name}: {cnblp.values[mclass]}")
+               var threshold = cnblp.threshold
+               print toolcontext.format_h4("\tlarge mclasses (threshold: {threshold})")
+               for mclass in cnblp.sort do
+                       var val = cnblp.values[mclass]
+                       if val.to_f < threshold then break
+                       print toolcontext.format_p("\t   {mclass.name}: {val}")
                end
 
-               print toolcontext.format_h4("\tbudding mclasses (threshold: {cnvi.threshold})")
-               for mclass in cnvi.above_threshold do
-                       print toolcontext.format_p("\t   {mclass.name}: {cnvi.values[mclass]}")
+               threshold = cnvi.threshold
+               print toolcontext.format_h4("\tbudding mclasses (threshold: {threshold})")
+               for mclass in cnvi.sort do
+                       var val = cnvi.values[mclass]
+                       if val.to_f < threshold then break
+                       print toolcontext.format_p("\t   {mclass.name}: {val}")
                end
 
-               print toolcontext.format_h4("\tblooming mclasses (threshold: {cnvs.threshold})")
-               for mclass in cnvs.above_threshold do
-                       print toolcontext.format_p("\t   {mclass.name}: {cnvs.values[mclass]}")
-               end
-
-               print toolcontext.format_h4("\tblooming mclasses (threshold: {cnvs.threshold})")
-               for mclass in cnvs.above_threshold do
-                       print toolcontext.format_p("\t   {mclass.name}: {cnvs.values[mclass]}")
+               threshold = cnvs.threshold
+               print toolcontext.format_h4("\tblooming mclasses (threshold: {threshold})")
+               for mclass in cnvs.sort do
+                       var val = cnvs.values[mclass]
+                       if val.to_f < threshold then break
+                       print toolcontext.format_p("\t   {mclass.name}: {val}")
                end
 
                if csv then
-                       var csvh = new CSVDocument
+                       var csvh = new CsvDocument
+                       csvh.format = new CsvFormat('"', ';', "\n")
                        csvh.header = ["povr", "ovr", "pext", "ext", "pspe", "spe", "prep", "rep", "eq"]
                        for mclass in mclasses do
                                var povr = mclass.is_pure_overrider(vis).object_id
@@ -116,7 +122,7 @@ private class MendelMetricsPhase
                                var prep = mclass.is_pure_replacer(vis).object_id
                                var rep = mclass.is_replacer(vis).object_id
                                var eq = mclass.is_equal(vis).object_id
-                               csvh.add_line(povr, ovr, pext, ext, pspe, spe, prep, rep, eq)
+                               csvh.add_record(povr, ovr, pext, ext, pspe, spe, prep, rep, eq)
                        end
                        csvh.save("{out}/inheritance_behaviour.csv")
                end
@@ -131,12 +137,12 @@ class CBMS
        redef fun name do return "cbms"
        redef fun desc do return "branch mean size, mean number of introduction available among ancestors"
 
+       # Mainmodule used to compute class hierarchy.
        var mainmodule: MModule
-       init(mainmodule: MModule) do self.mainmodule = mainmodule
 
        redef fun collect(mclasses) do
                for mclass in mclasses do
-                       var totc = mclass.all_mproperties(mainmodule, protected_visibility).length
+                       var totc = mclass.collect_accessible_mproperties(protected_visibility).length
                        var ditc = mclass.in_hierarchy(mainmodule).depth
                        values[mclass] = totc.to_f / (ditc + 1).to_f
                end
@@ -151,8 +157,8 @@ class CNVI
        redef fun name do return "cnvi"
        redef fun desc do return "class novelty index, contribution of the class to its branch in term of introductions"
 
+       # Mainmodule used to compute class hierarchy.
        var mainmodule: MModule
-       init(mainmodule: MModule) do self.mainmodule = mainmodule
 
        redef fun collect(mclasses) do
                var cbms = new CBMS(mainmodule)
@@ -163,7 +169,7 @@ class CNVI
                                cbms.clear
                                cbms.collect(new HashSet[MClass].from(parents))
                                # compute class novelty index
-                               var locc = mclass.local_mproperties(protected_visibility).length
+                               var locc = mclass.collect_accessible_mproperties(protected_visibility).length
                                values[mclass] = locc.to_f / cbms.avg
                        else
                                values[mclass] = 0.0
@@ -180,14 +186,14 @@ class CNVS
        redef fun name do return "cnvs"
        redef fun desc do return "class novelty score, importance of the contribution of the class to its branch"
 
+       # Mainmodule used to compute class hierarchy.
        var mainmodule: MModule
-       init(mainmodule: MModule) do self.mainmodule = mainmodule
 
        redef fun collect(mclasses) do
                var cnvi = new CNVI(mainmodule)
                cnvi.collect(mclasses)
                for mclass in mclasses do
-                       var locc = mclass.local_mproperties(protected_visibility).length
+                       var locc = mclass.collect_local_mproperties(protected_visibility).length
                        values[mclass] = cnvi.values[mclass] * locc.to_f
                end
        end
@@ -222,34 +228,34 @@ redef class MClass
 
        # pure overriders contain only redefinitions
        private fun is_pure_overrider(min_visibility: MVisibility): Bool do
-               var news = intro_mproperties(min_visibility).length
-               var locs = local_mproperties(min_visibility).length
+               var news = collect_intro_mproperties(min_visibility).length
+               var locs = collect_local_mproperties(min_visibility).length
                if news == 0 and locs > 0 then return true
                return false
        end
 
        # overriders contain more definitions than introductions
        private fun is_overrider(min_visibility: MVisibility): Bool do
-               var rdfs = redef_mproperties(min_visibility).length
-               var news = intro_mproperties(min_visibility).length
-               var locs = local_mproperties(min_visibility).length
+               var rdfs = collect_redef_mproperties(min_visibility).length
+               var news = collect_intro_mproperties(min_visibility).length
+               var locs = collect_local_mproperties(min_visibility).length
                if rdfs >= news and locs > 0 then return true
                return false
        end
 
        # pure extenders contain only introductions
        private fun is_pure_extender(min_visibility: MVisibility): Bool do
-               var rdfs = redef_mproperties(min_visibility).length
-               var locs = local_mproperties(min_visibility).length
+               var rdfs = collect_redef_mproperties(min_visibility).length
+               var locs = collect_local_mproperties(min_visibility).length
                if rdfs == 0 and locs > 0 then return true
                return false
        end
 
        # extenders contain more introduction than redefinitions
        private fun is_extender(min_visibility: MVisibility): Bool do
-               var rdfs = redef_mproperties(min_visibility).length
-               var news = intro_mproperties(min_visibility).length
-               var locs = local_mproperties(min_visibility).length
+               var rdfs = collect_redef_mproperties(min_visibility).length
+               var news = collect_intro_mproperties(min_visibility).length
+               var locs = collect_local_mproperties(min_visibility).length
                if news > rdfs and locs > 0 then return true
                return false
        end
@@ -257,7 +263,7 @@ redef class MClass
        # pure specializers always call to super in its redefinitions
        private fun is_pure_specializer(min_visibility: MVisibility): Bool do
                var ovrs = overriden_mproperties(min_visibility).length
-               var rdfs = redef_mproperties(min_visibility).length
+               var rdfs = collect_redef_mproperties(min_visibility).length
                if ovrs == 0 and rdfs > 0 then return true
                return false
        end
@@ -266,7 +272,7 @@ redef class MClass
        private fun is_specializer(min_visibility: MVisibility): Bool do
                var spcs = extended_mproperties(min_visibility).length
                var ovrs = overriden_mproperties(min_visibility).length
-               var rdfs = redef_mproperties(min_visibility).length
+               var rdfs = collect_redef_mproperties(min_visibility).length
                if spcs > ovrs and rdfs > 0 then return true
                return false
        end
@@ -274,7 +280,7 @@ redef class MClass
        # pure replacers never call to super in its redefinitions
        private fun is_pure_replacer(min_visibility: MVisibility): Bool do
                var spcs = extended_mproperties(min_visibility).length
-               var rdfs = redef_mproperties(min_visibility).length
+               var rdfs = collect_redef_mproperties(min_visibility).length
                if spcs == 0 and rdfs > 0 then return true
                return false
        end
@@ -283,7 +289,7 @@ redef class MClass
        private fun is_replacer(min_visibility: MVisibility): Bool do
                var spcs = extended_mproperties(min_visibility).length
                var ovrs = overriden_mproperties(min_visibility).length
-               var rdfs = redef_mproperties(min_visibility).length
+               var rdfs = collect_redef_mproperties(min_visibility).length
                if ovrs > spcs and rdfs > 0 then return true
                return false
        end
@@ -292,7 +298,7 @@ redef class MClass
        private fun is_equal(min_visibility: MVisibility): Bool do
                var spcs = extended_mproperties(min_visibility).length
                var ovrs = overriden_mproperties(min_visibility).length
-               var rdfs = redef_mproperties(min_visibility).length
+               var rdfs = collect_redef_mproperties(min_visibility).length
                if spcs == ovrs and rdfs > 0 then return true
                return false
        end