X-Git-Url: http://nitlanguage.org diff --git a/src/metrics/mmodules_metrics.nit b/src/metrics/mmodules_metrics.nit index f729c75..dc944d8 100644 --- a/src/metrics/mmodules_metrics.nit +++ b/src/metrics/mmodules_metrics.nit @@ -17,146 +17,129 @@ # Collect common metrics about modules module mmodules_metrics -import model import metrics_base -import phase -import frontend redef class ToolContext - var mmodules_metrics_phase = new MModulesMetricsPhase(self, null) + var mmodules_metrics_phase: Phase = new MModulesMetricsPhase(self, null) end # Extract metrics about modules from the model. private class MModulesMetricsPhase super Phase - redef fun process_mainmodule(mainmodule) + redef fun process_mainmodule(mainmodule, given_mmodules) do if not toolcontext.opt_mmodules.value and not toolcontext.opt_all.value then return + var csv = toolcontext.opt_csv.value + var out = "{toolcontext.opt_dir.value or else "metrics"}/mmodules" + out.mkdir - print "\n# MModules metrics".yellow.bold + print toolcontext.format_h1("\n# MModules metrics") - var metrics = new MModuleMetricSet + var metrics = new MetricSet metrics.register(new MNOA, new MNOP, new MNOC, new MNOD, new MDIT) metrics.register(new MNBI, new MNBR, new MNBCC, new MNBAC, new MNBIC) var model = toolcontext.modelbuilder.model var mmodules = new HashSet[MModule] - for mproject in model.mprojects do + for mpackage in model.mpackages do - print "\n ## project {mproject}".bold - - for mgroup in mproject.mgroups do + print toolcontext.format_h2("\n ## package {mpackage}") + for mgroup in mpackage.mgroups do if mgroup.mmodules.is_empty then continue # Scalar metrics - print " `- group {mgroup.full_name}" - + print toolcontext.format_h3(" `- group {mgroup.full_name}") mmodules.add_all(mgroup.mmodules) - metrics.collect(new HashSet[MModule].from(mgroup.mmodules), mainmodule) - for name, metric in metrics.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 + metrics.clear + metrics.collect(new HashSet[MModule].from(mgroup.mmodules)) + metrics.to_console(1, not toolcontext.opt_nocolors.value) + if csv then metrics.to_csv.write_to_file("{out}/{mgroup}.csv") end end if not mmodules.is_empty then # Global metrics - print "\n ## global metrics".bold - - metrics.collect(mmodules, mainmodule) - for name, metric in metrics.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 - end - end -end - -# A MetricSet for metrics about MModules -class MModuleMetricSet - super MetricSet - redef type METRIC: MModuleMetric - - # Collect all the metrics on the set of MModules - 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 + print toolcontext.format_h2("\n ## global metrics") + metrics.clear + metrics.collect(mmodules) + metrics.to_console(1, not toolcontext.opt_nocolors.value) + if csv then metrics.to_csv.write_to_file("{out}/summary.csv") end end end -# An abstract Metric on MModules -abstract class MModuleMetric - super IntMetric[MModule] - # Collect the metric on the MModule - # - # Results are stored in the property `values` - fun collect(mmodule: MModule, mainmodule: MModule) is abstract +# A metric about MModule +interface MModuleMetric + super Metric + redef type ELM: MModule end # Module Metric: Number of Ancestors class MNOA super MModuleMetric + super IntMetric redef fun name do return "mnoa" redef fun desc do return "number of ancestor modules" - redef fun collect(mmodule, main) do - values[mmodule] = mmodule.in_importation.greaters.length - 1 + redef fun collect(mmodules) do + for mmodule in mmodules do + values[mmodule] = mmodule.in_importation.greaters.length - 1 + end end end # Module Metric: Number of Parents class MNOP super MModuleMetric + super IntMetric redef fun name do return "mnop" redef fun desc do return "number of parent modules" - redef fun collect(mmodule, main) do - values[mmodule] = mmodule.in_importation.direct_greaters.length + redef fun collect(mmodules) do + for mmodule in mmodules do + values[mmodule] = mmodule.in_importation.direct_greaters.length + end end end # Module Metric: Number of Children class MNOC super MModuleMetric + super IntMetric redef fun name do return "mnoc" redef fun desc do return "number of child modules" - redef fun collect(mmodule, main) do - values[mmodule] = mmodule.in_importation.direct_smallers.length + redef fun collect(mmodules) do + for mmodule in mmodules do + values[mmodule] = mmodule.in_importation.direct_smallers.length + end end end # Module Metric: Number of Descendants class MNOD super MModuleMetric + super IntMetric redef fun name do return "mnod" redef fun desc do return "number of descendant modules" - redef fun collect(mmodule, main) do - values[mmodule] = mmodule.in_importation.smallers.length - 1 + redef fun collect(mmodules) do + for mmodule in mmodules do + values[mmodule] = mmodule.in_importation.smallers.length - 1 + end end end # Module Metric: Depth in Tree class MDIT super MModuleMetric + super IntMetric redef fun name do return "mdit" redef fun desc do return "depth in module tree" - redef fun collect(mmodule, main) do - values[mmodule] = mmodule.in_importation.depth + redef fun collect(mmodules) do + for mmodule in mmodules do + values[mmodule] = mmodule.in_importation.depth + end end end @@ -165,11 +148,14 @@ end # count all mclasses introduced by the module class MNBI super MModuleMetric + super IntMetric redef fun name do return "mnbi" redef fun desc do return "number of introduction in module" - redef fun collect(mmodule, main) do - values[mmodule] = mmodule.intro_mclasses.length + redef fun collect(mmodules) do + for mmodule in mmodules do + values[mmodule] = mmodule.intro_mclasses.length + end end end @@ -178,13 +164,17 @@ end # count all mclasses refined in the module class MNBR super MModuleMetric + super IntMetric redef fun name do return "mnbr" redef fun desc do return "number of refinement in module" - redef fun collect(mmodule, main) do - values[mmodule] = 0 - for mclassdef in mmodule.mclassdefs do - if not mclassdef.is_intro then values.inc(mmodule) + redef fun collect(mmodules) do + for mmodule in mmodules do + var value = 0 + for mclassdef in mmodule.mclassdefs do + if not mclassdef.is_intro then value += 1 + end + values[mmodule] = value end end end @@ -192,13 +182,17 @@ end # Module Metric: Number of Concrete Class in module (intro + redef) class MNBCC super MModuleMetric + super IntMetric redef fun name do return "mnbcc" redef fun desc do return "number of concrete class in module (intro + redef)" - redef fun collect(mmodule, main) do - values[mmodule] = 0 - for mclassdef in mmodule.mclassdefs do - if mclassdef.mclass.kind == concrete_kind then values.inc(mmodule) + redef fun collect(mmodules) do + for mmodule in mmodules do + var value = 0 + for mclassdef in mmodule.mclassdefs do + if mclassdef.mclass.kind == concrete_kind then value += 1 + end + values[mmodule] = value end end end @@ -206,13 +200,17 @@ end # Module Metric: Number of Abstract Class in module (intro + redef) class MNBAC super MModuleMetric + super IntMetric redef fun name do return "mnbac" redef fun desc do return "number of abstract class in module (intro + redef)" - redef fun collect(mmodule, main) do - values[mmodule] = 0 - for mclassdef in mmodule.mclassdefs do - if mclassdef.mclass.kind == abstract_kind then values.inc(mmodule) + redef fun collect(mmodules) do + for mmodule in mmodules do + var value = 0 + for mclassdef in mmodule.mclassdefs do + if mclassdef.mclass.kind == abstract_kind then value += 1 + end + values[mmodule] = value end end end @@ -220,13 +218,17 @@ end # Module Metric: Number of Interface in module (intro + redef) class MNBIC super MModuleMetric + super IntMetric redef fun name do return "mnbic" redef fun desc do return "number of interface in module (intro + redef)" - redef fun collect(mmodule, main) do - values[mmodule] = 0 - for mclassdef in mmodule.mclassdefs do - if mclassdef.mclass.kind == interface_kind then values.inc(mmodule) + redef fun collect(mmodules) do + for mmodule in mmodules do + var value = 0 + for mclassdef in mmodule.mclassdefs do + if mclassdef.mclass.kind == interface_kind then value += 1 + end + values[mmodule] = value end end end @@ -234,13 +236,17 @@ end # Module Metric: Number of Enum in module (intro + redef) class MNBEC super MModuleMetric + super IntMetric redef fun name do return "mnbec" redef fun desc do return "number of enum in module (intro + redef)" - redef fun collect(mmodule, main) do - values[mmodule] = 0 - for mclassdef in mmodule.mclassdefs do - if mclassdef.mclass.kind == enum_kind then values.inc(mmodule) + redef fun collect(mmodules) do + for mmodule in mmodules do + var value = 0 + for mclassdef in mmodule.mclassdefs do + if mclassdef.mclass.kind == enum_kind then value += 1 + end + values[mmodule] = value end end end