1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2014 Alexandre Terrasa <alexandre@moz-code.org>
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
17 # Collect common metrics about modules
18 module mmodules_metrics
25 redef class ToolContext
26 var mmodules_metrics_phase
: Phase = new MModulesMetricsPhase(self, null)
29 # Extract metrics about modules from the model.
30 private class MModulesMetricsPhase
32 redef fun process_mainmodule
(mainmodule
, given_mmodules
)
34 if not toolcontext
.opt_mmodules
.value
and not toolcontext
.opt_all
.value
then return
35 var csv
= toolcontext
.opt_csv
.value
36 var out
= "{toolcontext.opt_dir.value or else "metrics"}/mmodules"
39 print toolcontext
.format_h1
("\n# MModules metrics")
41 var metrics
= new MetricSet
42 metrics
.register
(new MNOA, new MNOP, new MNOC, new MNOD, new MDIT)
43 metrics
.register
(new MNBI, new MNBR, new MNBCC, new MNBAC, new MNBIC)
45 var model
= toolcontext
.modelbuilder
.model
46 var mmodules
= new HashSet[MModule]
47 for mproject
in model
.mprojects
do
49 print toolcontext
.format_h2
("\n ## project {mproject}")
50 for mgroup
in mproject
.mgroups
do
51 if mgroup
.mmodules
.is_empty
then continue
54 print toolcontext
.format_h3
(" `- group {mgroup.full_name}")
55 mmodules
.add_all
(mgroup
.mmodules
)
57 metrics
.collect
(new HashSet[MModule].from
(mgroup
.mmodules
))
58 metrics
.to_console
(1, not toolcontext
.opt_nocolors
.value
)
59 if csv
then metrics
.to_csv
.save
("{out}/{mgroup}.csv")
62 if not mmodules
.is_empty
then
64 print toolcontext
.format_h2
("\n ## global metrics")
66 metrics
.collect
(mmodules
)
67 metrics
.to_console
(1, not toolcontext
.opt_nocolors
.value
)
68 if csv
then metrics
.to_csv
.save
("{out}/summary.csv")
73 # A metric about MModule
74 interface MModuleMetric
76 redef type ELM: MModule
79 # Module Metric: Number of Ancestors
83 redef fun name
do return "mnoa"
84 redef fun desc
do return "number of ancestor modules"
86 redef fun collect
(mmodules
) do
87 for mmodule
in mmodules
do
88 values
[mmodule
] = mmodule
.in_importation
.greaters
.length
- 1
93 # Module Metric: Number of Parents
97 redef fun name
do return "mnop"
98 redef fun desc
do return "number of parent modules"
100 redef fun collect
(mmodules
) do
101 for mmodule
in mmodules
do
102 values
[mmodule
] = mmodule
.in_importation
.direct_greaters
.length
107 # Module Metric: Number of Children
111 redef fun name
do return "mnoc"
112 redef fun desc
do return "number of child modules"
114 redef fun collect
(mmodules
) do
115 for mmodule
in mmodules
do
116 values
[mmodule
] = mmodule
.in_importation
.direct_smallers
.length
121 # Module Metric: Number of Descendants
125 redef fun name
do return "mnod"
126 redef fun desc
do return "number of descendant modules"
128 redef fun collect
(mmodules
) do
129 for mmodule
in mmodules
do
130 values
[mmodule
] = mmodule
.in_importation
.smallers
.length
- 1
135 # Module Metric: Depth in Tree
139 redef fun name
do return "mdit"
140 redef fun desc
do return "depth in module tree"
142 redef fun collect
(mmodules
) do
143 for mmodule
in mmodules
do
144 values
[mmodule
] = mmodule
.in_importation
.depth
149 # Module Metric: Number of Introduction (of all kind)
151 # count all mclasses introduced by the module
155 redef fun name
do return "mnbi"
156 redef fun desc
do return "number of introduction in module"
158 redef fun collect
(mmodules
) do
159 for mmodule
in mmodules
do
160 values
[mmodule
] = mmodule
.intro_mclasses
.length
165 # Module Metric: Number of Refinement
167 # count all mclasses refined in the module
171 redef fun name
do return "mnbr"
172 redef fun desc
do return "number of refinement in module"
174 redef fun collect
(mmodules
) do
175 for mmodule
in mmodules
do
177 for mclassdef
in mmodule
.mclassdefs
do
178 if not mclassdef
.is_intro
then value
+= 1
180 values
[mmodule
] = value
185 # Module Metric: Number of Concrete Class in module (intro + redef)
189 redef fun name
do return "mnbcc"
190 redef fun desc
do return "number of concrete class in module (intro + redef)"
192 redef fun collect
(mmodules
) do
193 for mmodule
in mmodules
do
195 for mclassdef
in mmodule
.mclassdefs
do
196 if mclassdef
.mclass
.kind
== concrete_kind
then value
+= 1
198 values
[mmodule
] = value
203 # Module Metric: Number of Abstract Class in module (intro + redef)
207 redef fun name
do return "mnbac"
208 redef fun desc
do return "number of abstract class in module (intro + redef)"
210 redef fun collect
(mmodules
) do
211 for mmodule
in mmodules
do
213 for mclassdef
in mmodule
.mclassdefs
do
214 if mclassdef
.mclass
.kind
== abstract_kind
then value
+= 1
216 values
[mmodule
] = value
221 # Module Metric: Number of Interface in module (intro + redef)
225 redef fun name
do return "mnbic"
226 redef fun desc
do return "number of interface in module (intro + redef)"
228 redef fun collect
(mmodules
) do
229 for mmodule
in mmodules
do
231 for mclassdef
in mmodule
.mclassdefs
do
232 if mclassdef
.mclass
.kind
== interface_kind
then value
+= 1
234 values
[mmodule
] = value
239 # Module Metric: Number of Enum in module (intro + redef)
243 redef fun name
do return "mnbec"
244 redef fun desc
do return "number of enum in module (intro + redef)"
246 redef fun collect
(mmodules
) do
247 for mmodule
in mmodules
do
249 for mclassdef
in mmodule
.mclassdefs
do
250 if mclassdef
.mclass
.kind
== enum_kind
then value
+= 1
252 values
[mmodule
] = value