X-Git-Url: http://nitlanguage.org diff --git a/src/metrics/mmodules_metrics.nit b/src/metrics/mmodules_metrics.nit index 4075280..335831c 100644 --- a/src/metrics/mmodules_metrics.nit +++ b/src/metrics/mmodules_metrics.nit @@ -17,97 +17,60 @@ # 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 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 toolcontext.format_h2("\n ## project {mproject}") - - 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 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 - if metric isa IntMetric then - print toolcontext.format_h4("\t{name}: {metric.desc}") - print toolcontext.format_p("\t avg: {metric.avg}") - var max = metric.max - print toolcontext.format_p("\t max: {max.first} ({max.second})") - var min = metric.min - print toolcontext.format_p("\t min: {min.first} ({min.second})") - end - 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.save("{out}/{mgroup}.csv") end end if not mmodules.is_empty then # Global metrics print toolcontext.format_h2("\n ## global metrics") - - metrics.collect(mmodules, mainmodule) - for name, metric in metrics.metrics do - if metric isa IntMetric then - print toolcontext.format_h4( "\t{name}: {metric.desc}") - print toolcontext.format_p("\t avg: {metric.avg}") - var max = metric.max - print toolcontext.format_p("\t max: {max.first} ({max.second})") - var min = metric.min - print toolcontext.format_p("\t min: {min.first} ({min.second})") - end - 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 + metrics.clear + metrics.collect(mmodules) + metrics.to_console(1, not toolcontext.opt_nocolors.value) + if csv then metrics.to_csv.save("{out}/summary.csv") end end end -# An abstract Metric on MModules -abstract class MModuleMetric +# A metric about MModule +interface MModuleMetric super Metric redef type ELM: MModule - # Collect the metric on the MModule - # - # Results are stored in the property `values` - fun collect(mmodule: MModule, mainmodule: MModule) is abstract end # Module Metric: Number of Ancestors @@ -117,8 +80,10 @@ class MNOA 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 @@ -129,8 +94,10 @@ class MNOP 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 @@ -141,8 +108,10 @@ class MNOC 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 @@ -153,8 +122,10 @@ class MNOD 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 @@ -165,8 +136,10 @@ class MDIT 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 @@ -179,8 +152,10 @@ class MNBI 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 @@ -193,12 +168,14 @@ class MNBR redef fun name do return "mnbr" redef fun desc do return "number of refinement in module" - redef fun collect(mmodule, main) do - var value = 0 - for mclassdef in mmodule.mclassdefs do - if not mclassdef.is_intro then value += 1 + 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 - values[mmodule] = value end end @@ -209,12 +186,14 @@ class MNBCC 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 - var value = 0 - for mclassdef in mmodule.mclassdefs do - if mclassdef.mclass.kind == concrete_kind then value += 1 + 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 - values[mmodule] = value end end @@ -225,12 +204,14 @@ class MNBAC 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 - var value = 0 - for mclassdef in mmodule.mclassdefs do - if mclassdef.mclass.kind == abstract_kind then value += 1 + 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 - values[mmodule] = value end end @@ -241,12 +222,14 @@ class MNBIC redef fun name do return "mnbic" redef fun desc do return "number of interface in module (intro + redef)" - redef fun collect(mmodule, main) do - var value = 0 - for mclassdef in mmodule.mclassdefs do - if mclassdef.mclass.kind == interface_kind then value += 1 + 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 - values[mmodule] = value end end @@ -257,12 +240,14 @@ class MNBEC redef fun name do return "mnbec" redef fun desc do return "number of enum in module (intro + redef)" - redef fun collect(mmodule, main) do - var value = 0 - for mclassdef in mmodule.mclassdefs do - if mclassdef.mclass.kind == enum_kind then value += 1 + 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 - values[mmodule] = value end end