Merge: doc: fixed some typos and other misc. corrections
[nit.git] / src / metrics / inheritance_metrics.nit
index 94bbd5f..527ece8 100644 (file)
 # Collect metrics about inheritance usage
 module inheritance_metrics
 
 # Collect metrics about inheritance usage
 module inheritance_metrics
 
-import model
+import metrics_base
 import mmodules_metrics
 import mclasses_metrics
 import mmodules_metrics
 import mclasses_metrics
-import phase
-import frontend
 
 redef class ToolContext
 
 redef class ToolContext
-       var inheritance_metrics_phase = new InheritanceMetricsPhase(self, null)
+
+       # Inheritance related metrics phase
+       var inheritance_metrics_phase: Phase = new InheritanceMetricsPhase(self, null)
 end
 
 # Extract metrics about inheritance from model.
 private class InheritanceMetricsPhase
        super Phase
 end
 
 # Extract metrics about inheritance from model.
 private class InheritanceMetricsPhase
        super Phase
-       redef fun process_mainmodule(mainmodule)
+       redef fun process_mainmodule(mainmodule, given_mmodules)
        do
                if not toolcontext.opt_inheritance.value and not toolcontext.opt_all.value then return
        do
                if not toolcontext.opt_inheritance.value and not toolcontext.opt_all.value then return
-
-               print "\n# Inheritance metrics".yellow.bold
-
-               var hmetrics = new InheritanceMetricSet
-               hmetrics.register(new MDUI, new MDUIC, new MDUII, new MIF, new MIFC, new MIFI)
-               
-               var cmetrics = new MClassMetricSet
-               cmetrics.register(new CNOA, new CNOP, new CNOC, new CNODC)
-               cmetrics.register(new CNOA, new CNOP, new CNOC, new CNODI)
-               cmetrics.register(new CDIT, new CDITI)
+               var csv = toolcontext.opt_csv.value
+               var out = "{toolcontext.opt_dir.value or else "metrics"}/inheritance"
+               out.mkdir
 
                var model = toolcontext.modelbuilder.model
 
                var model = toolcontext.modelbuilder.model
+               var filter = new ModelFilter(min_visibility = private_visibility)
+
+               print toolcontext.format_h1("\n# Inheritance metrics")
+
+               var hmetrics = new MetricSet
+               hmetrics.register(new MDUI(model, mainmodule))
+               hmetrics.register(new MDUIC(model, mainmodule))
+               hmetrics.register(new MDUII(model, mainmodule))
+               hmetrics.register(new MIF(model, mainmodule))
+               hmetrics.register(new MIFC(model, mainmodule))
+               hmetrics.register(new MIFI(model, mainmodule))
+
+               var cmetrics = new MetricSet
+               cmetrics.register(new CNOAC(model, mainmodule, filter))
+               cmetrics.register(new CNOPC(model, mainmodule, filter))
+               cmetrics.register(new CNOCC(model, mainmodule, filter))
+               cmetrics.register(new CNODC(model, mainmodule, filter))
+               cmetrics.register(new CNOPI(model, mainmodule, filter))
+               cmetrics.register(new CNOCI(model, mainmodule, filter))
+               cmetrics.register(new CNODI(model, mainmodule, filter))
+               cmetrics.register(new CDITC(model, mainmodule, filter))
+               cmetrics.register(new CDITI(model, mainmodule, filter))
+
                var mmodules = new HashSet[MModule]
                var mclasses = new HashSet[MClass]
                var mmodules = new HashSet[MModule]
                var mclasses = new HashSet[MClass]
-               for mproject in model.mprojects do
+               for mpackage in model.mpackages do
 
 
-                       print "\n ## project {mproject}".bold
+                       print toolcontext.format_h2("\n ## package {mpackage}")
 
 
-                       for mgroup in mproject.mgroups do
+                       for mgroup in mpackage.mgroups do
                                if mgroup.mmodules.is_empty then continue
 
                                # Scalar metrics
                                if mgroup.mmodules.is_empty then continue
 
                                # Scalar metrics
-                               print "  `- group {mgroup.full_name}"
+                               print toolcontext.format_h3("  `- group {mgroup.full_name}")
 
                                var mod_mclasses = new HashSet[MClass]
                                for mmodule in mgroup.mmodules do mod_mclasses.add_all(mmodule.intro_mclasses)
                                if mod_mclasses.is_empty then continue
                                mmodules.add_all(mgroup.mmodules)
                                mclasses.add_all(mod_mclasses)
 
                                var mod_mclasses = new HashSet[MClass]
                                for mmodule in mgroup.mmodules do mod_mclasses.add_all(mmodule.intro_mclasses)
                                if mod_mclasses.is_empty then continue
                                mmodules.add_all(mgroup.mmodules)
                                mclasses.add_all(mod_mclasses)
-                               cmetrics.collect(new HashSet[MClass].from(mod_mclasses), mainmodule)
-                               for name, metric in cmetrics.metrics do
-                                       print "\t{name}: {metric.desc}".green
-                                       print "\t    avg: {metric.avg}".light_gray
-                                       var max = metric.max
-                                       print "\t    max: {max.first} ({max.second})".light_gray
-                                       var min = metric.min
-                                       print "\t    min: {min.first} ({min.second})".light_gray
-                               end
-                               hmetrics.collect(new HashSet[MModule].from(mgroup.mmodules), mainmodule)
-                               for name, metric in hmetrics.metrics do
-                                       print "\t{name}: {metric.desc}".green
-                                       print "\t    avg: {metric.avg}".light_gray
-                                       var max = metric.max
-                                       print "\t    max: {max.first} ({max.second})".light_gray
-                                       var min = metric.min
-                                       print "\t    min: {min.first} ({min.second})".light_gray
-                               end
+                               cmetrics.clear
+                               cmetrics.collect(new HashSet[MClass].from(mod_mclasses))
+                               cmetrics.to_console(1, not toolcontext.opt_nocolors.value)
+                               if csv then cmetrics.to_csv.write_to_file("{out}/{mgroup}_classes.csv")
+                               hmetrics.clear
+                               hmetrics.collect(new HashSet[MModule].from(mgroup.mmodules))
+                               hmetrics.to_console(1, not toolcontext.opt_nocolors.value)
+                               if csv then hmetrics.to_csv.write_to_file("{out}/{mgroup}_inheritance.csv")
                        end
                end
                if not mclasses.is_empty then
                        # Global metrics
                        end
                end
                if not mclasses.is_empty then
                        # Global metrics
-                       print "\n ## global metrics".bold
-                       cmetrics.collect(mclasses, mainmodule)
-                       for name, metric in cmetrics.metrics do
-                               print "\t{name}: {metric.desc}".green
-                               print "\t    avg: {metric.avg}".light_gray
-                               var max = metric.max
-                               print "\t    max: {max.first} ({max.second})".light_gray
-                               var min = metric.min
-                               print "\t    min: {min.first} ({min.second})".light_gray
-                       end
-                       hmetrics.collect(mmodules, mainmodule)
-                       for name, metric in hmetrics.metrics do
-                               print "\t{name}: {metric.desc}".green
-                               print "\t    avg: {metric.avg}".light_gray
-                               var max = metric.max
-                               print "\t    max: {max.first} ({max.second})".light_gray
-                               var min = metric.min
-                               print "\t    min: {min.first} ({min.second})".light_gray
-                       end
+                       print toolcontext.format_h2("\n ## global metrics")
+                       cmetrics.clear
+                       cmetrics.collect(mclasses)
+                       cmetrics.to_console(1, not toolcontext.opt_nocolors.value)
+                       if csv then cmetrics.to_csv.write_to_file("{out}/summary_classes.csv")
+                       hmetrics.clear
+                       hmetrics.collect(mmodules)
+                       hmetrics.to_console(1, not toolcontext.opt_nocolors.value)
+                       if csv then hmetrics.to_csv.write_to_file("{out}/summary_inheritance.csv")
                end
        end
 end
 
                end
        end
 end
 
-# Metric Set used to collect data about inheritance in each module
-class InheritanceMetricSet
-       super MetricSet
-       redef type METRIC: InheritanceMetric
-       fun collect(mmodules: Set[MModule], mainmodule: MModule) do
-               clear
-               for metric in metrics.values do
-                       for mmodule in mmodules do
-                               metric.collect(mmodule, mainmodule)
-                       end
-               end
-       end
-end
-
-# An abstract metric used to collect data about inheritance usage
-#
-# The metric is based on a module
-abstract class InheritanceMetric
-       super FloatMetric[MModule]
-       fun collect(mmodule: MModule, mainmodule: MModule) is abstract
-end
-
 # Module metric: proportion of MClasses Defined Using Inheritance
 #
 # Count MClasses that have another parents than Object
 class MDUI
 # Module metric: proportion of MClasses Defined Using Inheritance
 #
 # Count MClasses that have another parents than Object
 class MDUI
-       super InheritanceMetric
+       super MModuleMetric
+       super FloatMetric
        redef fun name do return "mdui"
        redef fun desc do return "proportion of mclass defined using inheritance (has other parent than Object)"
 
        redef fun name do return "mdui"
        redef fun desc do return "proportion of mclass defined using inheritance (has other parent than Object)"
 
-       redef fun collect(mmodule, mainmodule) do
-               var count = 0
-               for mclass in mmodule.intro_mclasses do
-                       if mclass.in_hierarchy(mainmodule).greaters.length > 2 then count += 1
-               end
-               if mmodule.intro_mclasses.is_empty then
-                       values[mmodule] = 0.0
-               else
-                       values[mmodule] = count.to_f / mmodule.intro_mclasses.length.to_f
+       redef fun collect(mmodules) do
+               for mmodule in mmodules do
+                       var count = 0
+                       for mclass in mmodule.intro_mclasses do
+                               if mclass.in_hierarchy(mainmodule).greaters.length > 2 then count += 1
+                       end
+                       if mmodule.intro_mclasses.is_empty then
+                               values[mmodule] = 0.0
+                       else
+                               values[mmodule] = count.to_f / mmodule.intro_mclasses.length.to_f
+                       end
                end
        end
 end
                end
        end
 end
@@ -154,23 +131,26 @@ end
 #
 # Count classes that have another parents than Object
 class MDUIC
 #
 # Count classes that have another parents than Object
 class MDUIC
-       super InheritanceMetric
+       super MModuleMetric
+       super FloatMetric
        redef fun name do return "mduic"
        redef fun desc do return "proportion of class_kind defined using inheritance"
 
        redef fun name do return "mduic"
        redef fun desc do return "proportion of class_kind defined using inheritance"
 
-       redef fun collect(mmodule, mainmodule) do
-               var count = 0
-               var nb = 0
-               for mclass in mmodule.intro_mclasses do
-                       if mclass.kind == abstract_kind or mclass.kind == concrete_kind or mclass.kind == extern_kind then
-                               if mclass.in_hierarchy(mainmodule).greaters.length > 2 then count += 1
+       redef fun collect(mmodules) do
+               for mmodule in mmodules do
+                       var count = 0
+                       var nb = 0
+                       for mclass in mmodule.intro_mclasses do
+                               if mclass.kind == abstract_kind or mclass.kind == concrete_kind or mclass.kind == extern_kind then
+                                       if mclass.in_hierarchy(mainmodule).greaters.length > 2 then count += 1
+                               end
+                               nb += 1
+                       end
+                       if mmodule.intro_mclasses.is_empty then
+                               values[mmodule] = 0.0
+                       else
+                               values[mmodule] = count.to_f / nb.to_f
                        end
                        end
-                       nb += 1
-               end
-               if mmodule.intro_mclasses.is_empty then
-                       values[mmodule] = 0.0
-               else
-                       values[mmodule] = count.to_f / nb.to_f
                end
        end
 end
                end
        end
 end
@@ -179,23 +159,26 @@ end
 #
 # Count interface that have another parents than Object
 class MDUII
 #
 # Count interface that have another parents than Object
 class MDUII
-       super InheritanceMetric
+       super MModuleMetric
+       super FloatMetric
        redef fun name do return "mduii"
        redef fun desc do return "proportion of interface_kind defined using inheritance"
 
        redef fun name do return "mduii"
        redef fun desc do return "proportion of interface_kind defined using inheritance"
 
-       redef fun collect(mmodule, mainmodule) do
-               var count = 0
-               var nb = 0
-               for mclass in mmodule.intro_mclasses do
-                       if mclass.kind == interface_kind then
-                               if mclass.in_hierarchy(mainmodule).greaters.length > 2 then count += 1
+       redef fun collect(mmodules) do
+               for mmodule in mmodules do
+                       var count = 0
+                       var nb = 0
+                       for mclass in mmodule.intro_mclasses do
+                               if mclass.kind == interface_kind then
+                                       if mclass.in_hierarchy(mainmodule).greaters.length > 2 then count += 1
+                               end
+                               nb += 1
+                       end
+                       if mmodule.intro_mclasses.is_empty then
+                               values[mmodule] = 0.0
+                       else
+                               values[mmodule] = count.to_f / nb.to_f
                        end
                        end
-                       nb += 1
-               end
-               if mmodule.intro_mclasses.is_empty then
-                       values[mmodule] = 0.0
-               else
-                       values[mmodule] = count.to_f / nb.to_f
                end
        end
 end
                end
        end
 end
@@ -204,19 +187,22 @@ end
 #
 # Count classes that have at least a child
 class MIF
 #
 # Count classes that have at least a child
 class MIF
-       super InheritanceMetric
+       super MModuleMetric
+       super FloatMetric
        redef fun name do return "mif"
        redef fun desc do return "proportion of mclass inherited from"
 
        redef fun name do return "mif"
        redef fun desc do return "proportion of mclass inherited from"
 
-       redef fun collect(mmodule, mainmodule) do
-               var count = 0
-               for mclass in mmodule.intro_mclasses do
-                       if mclass.in_hierarchy(mainmodule).direct_smallers.length > 0 then count += 1
-               end
-               if mmodule.intro_mclasses.is_empty then
-                       values[mmodule] = 0.0
-               else
-                       values[mmodule] = count.to_f / mmodule.intro_mclasses.length.to_f
+       redef fun collect(mmodules) do
+               for mmodule in mmodules do
+                       var count = 0
+                       for mclass in mmodule.intro_mclasses do
+                               if mclass.in_hierarchy(mainmodule).direct_smallers.length > 0 then count += 1
+                       end
+                       if mmodule.intro_mclasses.is_empty then
+                               values[mmodule] = 0.0
+                       else
+                               values[mmodule] = count.to_f / mmodule.intro_mclasses.length.to_f
+                       end
                end
        end
 end
                end
        end
 end
@@ -225,23 +211,26 @@ end
 #
 # Count classes that have at least a child
 class MIFC
 #
 # Count classes that have at least a child
 class MIFC
-       super InheritanceMetric
+       super MModuleMetric
+       super FloatMetric
        redef fun name do return "mifc"
        redef fun desc do return "proportion of class_kind inherited from"
 
        redef fun name do return "mifc"
        redef fun desc do return "proportion of class_kind inherited from"
 
-       redef fun collect(mmodule, mainmodule) do
-               var count = 0
-               var nb = 0
-               for mclass in mmodule.intro_mclasses do
-                       if mclass.kind == abstract_kind or mclass.kind == concrete_kind or mclass.kind == extern_kind then
-                               if mclass.in_hierarchy(mainmodule).direct_smallers.length > 0 then count += 1
+       redef fun collect(mmodules) do
+               for mmodule in mmodules do
+                       var count = 0
+                       var nb = 0
+                       for mclass in mmodule.intro_mclasses do
+                               if mclass.kind == abstract_kind or mclass.kind == concrete_kind or mclass.kind == extern_kind then
+                                       if mclass.in_hierarchy(mainmodule).direct_smallers.length > 0 then count += 1
+                               end
+                               nb += 1
+                       end
+                       if mmodule.intro_mclasses.is_empty then
+                               values[mmodule] = 0.0
+                       else
+                               values[mmodule] = count.to_f / nb.to_f
                        end
                        end
-                       nb += 1
-               end
-               if mmodule.intro_mclasses.is_empty then
-                       values[mmodule] = 0.0
-               else
-                       values[mmodule] = count.to_f / nb.to_f
                end
        end
 end
                end
        end
 end
@@ -250,23 +239,26 @@ end
 #
 # Count interfaces that have at least a child
 class MIFI
 #
 # Count interfaces that have at least a child
 class MIFI
-       super InheritanceMetric
+       super MModuleMetric
+       super FloatMetric
        redef fun name do return "mifi"
        redef fun desc do return "proportion of interface_kind inherited from"
 
        redef fun name do return "mifi"
        redef fun desc do return "proportion of interface_kind inherited from"
 
-       redef fun collect(mmodule, mainmodule) do
-               var count = 0
-               var nb = 0
-               for mclass in mmodule.intro_mclasses do
-                       if mclass.kind == interface_kind then
-                               if mclass.in_hierarchy(mainmodule).direct_smallers.length > 0 then count += 1
+       redef fun collect(mmodules) do
+               for mmodule in mmodules do
+                       var count = 0
+                       var nb = 0
+                       for mclass in mmodule.intro_mclasses do
+                               if mclass.kind == interface_kind then
+                                       if mclass.in_hierarchy(mainmodule).direct_smallers.length > 0 then count += 1
+                               end
+                               nb += 1
+                       end
+                       if mmodule.intro_mclasses.is_empty then
+                               values[mmodule] = 0.0
+                       else
+                               values[mmodule] = count.to_f / nb.to_f
                        end
                        end
-                       nb += 1
-               end
-               if mmodule.intro_mclasses.is_empty then
-                       values[mmodule] = 0.0
-               else
-                       values[mmodule] = count.to_f / nb.to_f
                end
        end
 end
                end
        end
 end
@@ -276,18 +268,21 @@ end
 # Count only absrtract, concrete and extern classes
 class CNOAC
        super MClassMetric
 # Count only absrtract, concrete and extern classes
 class CNOAC
        super MClassMetric
+       super IntMetric
        redef fun name do return "cnoac"
        redef fun desc do return "number of class_kind ancestor"
 
        redef fun name do return "cnoac"
        redef fun desc do return "number of class_kind ancestor"
 
-       redef fun collect(mclass, mainmodule) do
-               var count = 0
-               for parent in mclass.in_hierarchy(mainmodule).greaters do
-                       if parent == mclass then continue
-                       if parent.kind == abstract_kind or parent.kind == concrete_kind or parent.kind == extern_kind then
-                               count += 1
+       redef fun collect(mclasses) do
+               for mclass in mclasses do
+                       var count = 0
+                       for parent in mclass.in_hierarchy(mainmodule).greaters do
+                               if parent == mclass then continue
+                               if parent.kind == abstract_kind or parent.kind == concrete_kind or parent.kind == extern_kind then
+                                       count += 1
+                               end
                        end
                        end
+                       values[mclass] = count
                end
                end
-               values[mclass] = count
        end
 end
 
        end
 end
 
@@ -296,18 +291,21 @@ end
 # Count only absrtract, concrete and extern classes
 class CNOPC
        super MClassMetric
 # Count only absrtract, concrete and extern classes
 class CNOPC
        super MClassMetric
+       super IntMetric
        redef fun name do return "cnopc"
        redef fun desc do return "number of class_kind parent"
 
        redef fun name do return "cnopc"
        redef fun desc do return "number of class_kind parent"
 
-       redef fun collect(mclass, mainmodule) do
-               var count = 0
-               for parent in mclass.in_hierarchy(mainmodule).direct_greaters do
-                       if parent == mclass then continue
-                       if parent.kind == abstract_kind or parent.kind == concrete_kind or parent.kind == extern_kind then
-                               count += 1
+       redef fun collect(mclasses) do
+               for mclass in mclasses do
+                       var count = 0
+                       for parent in mclass.in_hierarchy(mainmodule).direct_greaters do
+                               if parent == mclass then continue
+                               if parent.kind == abstract_kind or parent.kind == concrete_kind or parent.kind == extern_kind then
+                                       count += 1
+                               end
                        end
                        end
+                       values[mclass] = count
                end
                end
-               values[mclass] = count
        end
 end
 
        end
 end
 
@@ -316,18 +314,21 @@ end
 # Count only absrtract, concrete and extern classes
 class CNOCC
        super MClassMetric
 # Count only absrtract, concrete and extern classes
 class CNOCC
        super MClassMetric
+       super IntMetric
        redef fun name do return "cnocc"
        redef fun desc do return "number of class_kind children"
 
        redef fun name do return "cnocc"
        redef fun desc do return "number of class_kind children"
 
-       redef fun collect(mclass, mainmodule) do
-               var count = 0
-               for parent in mclass.in_hierarchy(mainmodule).direct_smallers do
-                       if parent == mclass then continue
-                       if parent.kind == abstract_kind or parent.kind == concrete_kind or parent.kind == extern_kind then
-                               count += 1
+       redef fun collect(mclasses) do
+               for mclass in mclasses do
+                       var count = 0
+                       for parent in mclass.in_hierarchy(mainmodule).direct_smallers do
+                               if parent == mclass then continue
+                               if parent.kind == abstract_kind or parent.kind == concrete_kind or parent.kind == extern_kind then
+                                       count += 1
+                               end
                        end
                        end
+                       values[mclass] = count
                end
                end
-               values[mclass] = count
        end
 end
 
        end
 end
 
@@ -336,18 +337,44 @@ end
 # Count only absrtract, concrete and extern classes
 class CNODC
        super MClassMetric
 # Count only absrtract, concrete and extern classes
 class CNODC
        super MClassMetric
+       super IntMetric
        redef fun name do return "cnodc"
        redef fun desc do return "number of class_kind descendants"
 
        redef fun name do return "cnodc"
        redef fun desc do return "number of class_kind descendants"
 
-       redef fun collect(mclass, mainmodule) do
-               var count = 0
-               for parent in mclass.in_hierarchy(mainmodule).smallers do
-                       if parent == mclass then continue
-                       if parent.kind == abstract_kind or parent.kind == concrete_kind or parent.kind == extern_kind then
-                               count += 1
+       redef fun collect(mclasses) do
+               for mclass in mclasses do
+                       var count = 0
+                       for parent in mclass.in_hierarchy(mainmodule).smallers do
+                               if parent == mclass then continue
+                               if parent.kind == abstract_kind or parent.kind == concrete_kind or parent.kind == extern_kind then
+                                       count += 1
+                               end
+                       end
+                       values[mclass] = count
+               end
+       end
+end
+
+# MClass metric: Number of Abstract Class Ancestors
+#
+# Count only absrtract classes
+class CNOAA
+       super MClassMetric
+       super IntMetric
+       redef fun name do return "cnoaa"
+       redef fun desc do return "number of abstract class ancestors"
+
+       redef fun collect(mclasses) do
+               for mclass in mclasses do
+                       var count = 0
+                       for parent in mclass.in_hierarchy(mainmodule).greaters do
+                               if parent == mclass then continue
+                               if parent.kind == abstract_kind then
+                                       count += 1
+                               end
                        end
                        end
+                       values[mclass] = count
                end
                end
-               values[mclass] = count
        end
 end
 
        end
 end
 
@@ -356,18 +383,21 @@ end
 # Count only interfaces
 class CNOAI
        super MClassMetric
 # Count only interfaces
 class CNOAI
        super MClassMetric
+       super IntMetric
        redef fun name do return "cnoai"
        redef fun desc do return "number of interface_kind ancestor"
 
        redef fun name do return "cnoai"
        redef fun desc do return "number of interface_kind ancestor"
 
-       redef fun collect(mclass, mainmodule) do
-               var count = 0
-               for parent in mclass.in_hierarchy(mainmodule).greaters do
-                       if parent == mclass then continue
-                       if parent.kind == interface_kind then
-                               count += 1
+       redef fun collect(mclasses) do
+               for mclass in mclasses do
+                       var count = 0
+                       for parent in mclass.in_hierarchy(mainmodule).greaters do
+                               if parent == mclass then continue
+                               if parent.kind == interface_kind then
+                                       count += 1
+                               end
                        end
                        end
+                       values[mclass] = count
                end
                end
-               values[mclass] = count
        end
 end
 
        end
 end
 
@@ -376,18 +406,21 @@ end
 # Count only interfaces
 class CNOPI
        super MClassMetric
 # Count only interfaces
 class CNOPI
        super MClassMetric
+       super IntMetric
        redef fun name do return "cnopi"
        redef fun desc do return "number of interface_kind parent"
 
        redef fun name do return "cnopi"
        redef fun desc do return "number of interface_kind parent"
 
-       redef fun collect(mclass, mainmodule) do
-               var count = 0
-               for parent in mclass.in_hierarchy(mainmodule).direct_greaters do
-                       if parent == mclass then continue
-                       if parent.kind == interface_kind then
-                               count += 1
+       redef fun collect(mclasses) do
+               for mclass in mclasses do
+                       var count = 0
+                       for parent in mclass.in_hierarchy(mainmodule).direct_greaters do
+                               if parent == mclass then continue
+                               if parent.kind == interface_kind then
+                                       count += 1
+                               end
                        end
                        end
+                       values[mclass] = count
                end
                end
-               values[mclass] = count
        end
 end
 
        end
 end
 
@@ -396,18 +429,21 @@ end
 # Count only interfaces
 class CNOCI
        super MClassMetric
 # Count only interfaces
 class CNOCI
        super MClassMetric
+       super IntMetric
        redef fun name do return "cnoci"
        redef fun desc do return "number of interface_kind children"
 
        redef fun name do return "cnoci"
        redef fun desc do return "number of interface_kind children"
 
-       redef fun collect(mclass, mainmodule) do
-               var count = 0
-               for parent in mclass.in_hierarchy(mainmodule).direct_smallers do
-                       if parent == mclass then continue
-                       if parent.kind == interface_kind then
-                               count += 1
+       redef fun collect(mclasses) do
+               for mclass in mclasses do
+                       var count = 0
+                       for parent in mclass.in_hierarchy(mainmodule).direct_smallers do
+                               if parent == mclass then continue
+                               if parent.kind == interface_kind then
+                                       count += 1
+                               end
                        end
                        end
+                       values[mclass] = count
                end
                end
-               values[mclass] = count
        end
 end
 
        end
 end
 
@@ -416,18 +452,21 @@ end
 # Count only interfaces
 class CNODI
        super MClassMetric
 # Count only interfaces
 class CNODI
        super MClassMetric
+       super IntMetric
        redef fun name do return "cnodi"
        redef fun desc do return "number of interface_kind descendants"
 
        redef fun name do return "cnodi"
        redef fun desc do return "number of interface_kind descendants"
 
-       redef fun collect(mclass, mainmodule) do
-               var count = 0
-               for parent in mclass.in_hierarchy(mainmodule).smallers do
-                       if parent == mclass then continue
-                       if parent.kind == interface_kind then
-                               count += 1
+       redef fun collect(mclasses) do
+               for mclass in mclasses do
+                       var count = 0
+                       for parent in mclass.in_hierarchy(mainmodule).smallers do
+                               if parent == mclass then continue
+                               if parent.kind == interface_kind then
+                                       count += 1
+                               end
                        end
                        end
+                       values[mclass] = count
                end
                end
-               values[mclass] = count
        end
 end
 
        end
 end
 
@@ -436,11 +475,14 @@ end
 # Following the longest path composed only of extends edges from self to Object
 class CDITC
        super MClassMetric
 # Following the longest path composed only of extends edges from self to Object
 class CDITC
        super MClassMetric
+       super IntMetric
        redef fun name do return "cditc"
        redef fun desc do return "depth in class tree following only class, abstract, extern kind"
 
        redef fun name do return "cditc"
        redef fun desc do return "depth in class tree following only class, abstract, extern kind"
 
-       redef fun collect(mclass, mainmodule) do
-               values[mclass] = mclass.ditc(mainmodule)
+       redef fun collect(mclasses) do
+               for mclass in mclasses do
+                       values[mclass] = mclass.ditc(mainmodule)
+               end
        end
 end
 
        end
 end
 
@@ -449,18 +491,21 @@ end
 # Following the longest path composed only of implements edges from self to Object
 class CDITI
        super MClassMetric
 # Following the longest path composed only of implements edges from self to Object
 class CDITI
        super MClassMetric
+       super IntMetric
        redef fun name do return "cditi"
        redef fun desc do return "depth in class tree following only interface_kind"
 
        redef fun name do return "cditi"
        redef fun desc do return "depth in class tree following only interface_kind"
 
-       redef fun collect(mclass, mainmodule) do
-               values[mclass] = mclass.diti(mainmodule)
+       redef fun collect(mclasses) do
+               for mclass in mclasses do
+                       values[mclass] = mclass.diti(mainmodule)
+               end
        end
 end
 
 # model redef
 
 redef class MClass
        end
 end
 
 # model redef
 
 redef class MClass
-               
+
        # Class Depth in Inheritance Tree
        #
        # Following the longest path composed only of extends edges from self to Object
        # Class Depth in Inheritance Tree
        #
        # Following the longest path composed only of extends edges from self to Object
@@ -499,4 +544,3 @@ redef class MClass
                return min
        end
 end
                return min
        end
 end
-