6381726ca7324f6a56e4d52d0bd4d3d90689cfe5
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
= new MModulesMetricsPhase(self, null)
29 # Extract metrics about modules from the model.
30 private class MModulesMetricsPhase
32 redef fun process_mainmodule
(mainmodule
)
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
)
56 metrics
.collect
(new HashSet[MModule].from
(mgroup
.mmodules
))
57 metrics
.to_console
(1, not toolcontext
.opt_nocolors
.value
)
58 if csv
then metrics
.to_csv
.save
("{out}/{mgroup}.csv")
61 if not mmodules
.is_empty
then
63 print toolcontext
.format_h2
("\n ## global metrics")
65 metrics
.collect
(mmodules
)
66 metrics
.to_console
(1, not toolcontext
.opt_nocolors
.value
)
67 if csv
then metrics
.to_csv
.save
("{out}/summary.csv")
72 # A metric about MModule
73 interface MModuleMetric
75 redef type ELM: MModule
78 # Module Metric: Number of Ancestors
82 redef fun name
do return "mnoa"
83 redef fun desc
do return "number of ancestor modules"
85 redef fun collect
(mmodules
) do
86 for mmodule
in mmodules
do
87 values
[mmodule
] = mmodule
.in_importation
.greaters
.length
- 1
92 # Module Metric: Number of Parents
96 redef fun name
do return "mnop"
97 redef fun desc
do return "number of parent modules"
99 redef fun collect
(mmodules
) do
100 for mmodule
in mmodules
do
101 values
[mmodule
] = mmodule
.in_importation
.direct_greaters
.length
106 # Module Metric: Number of Children
110 redef fun name
do return "mnoc"
111 redef fun desc
do return "number of child modules"
113 redef fun collect
(mmodules
) do
114 for mmodule
in mmodules
do
115 values
[mmodule
] = mmodule
.in_importation
.direct_smallers
.length
120 # Module Metric: Number of Descendants
124 redef fun name
do return "mnod"
125 redef fun desc
do return "number of descendant modules"
127 redef fun collect
(mmodules
) do
128 for mmodule
in mmodules
do
129 values
[mmodule
] = mmodule
.in_importation
.smallers
.length
- 1
134 # Module Metric: Depth in Tree
138 redef fun name
do return "mdit"
139 redef fun desc
do return "depth in module tree"
141 redef fun collect
(mmodules
) do
142 for mmodule
in mmodules
do
143 values
[mmodule
] = mmodule
.in_importation
.depth
148 # Module Metric: Number of Introduction (of all kind)
150 # count all mclasses introduced by the module
154 redef fun name
do return "mnbi"
155 redef fun desc
do return "number of introduction in module"
157 redef fun collect
(mmodules
) do
158 for mmodule
in mmodules
do
159 values
[mmodule
] = mmodule
.intro_mclasses
.length
164 # Module Metric: Number of Refinement
166 # count all mclasses refined in the module
170 redef fun name
do return "mnbr"
171 redef fun desc
do return "number of refinement in module"
173 redef fun collect
(mmodules
) do
174 for mmodule
in mmodules
do
176 for mclassdef
in mmodule
.mclassdefs
do
177 if not mclassdef
.is_intro
then value
+= 1
179 values
[mmodule
] = value
184 # Module Metric: Number of Concrete Class in module (intro + redef)
188 redef fun name
do return "mnbcc"
189 redef fun desc
do return "number of concrete class in module (intro + redef)"
191 redef fun collect
(mmodules
) do
192 for mmodule
in mmodules
do
194 for mclassdef
in mmodule
.mclassdefs
do
195 if mclassdef
.mclass
.kind
== concrete_kind
then value
+= 1
197 values
[mmodule
] = value
202 # Module Metric: Number of Abstract Class in module (intro + redef)
206 redef fun name
do return "mnbac"
207 redef fun desc
do return "number of abstract class in module (intro + redef)"
209 redef fun collect
(mmodules
) do
210 for mmodule
in mmodules
do
212 for mclassdef
in mmodule
.mclassdefs
do
213 if mclassdef
.mclass
.kind
== abstract_kind
then value
+= 1
215 values
[mmodule
] = value
220 # Module Metric: Number of Interface in module (intro + redef)
224 redef fun name
do return "mnbic"
225 redef fun desc
do return "number of interface in module (intro + redef)"
227 redef fun collect
(mmodules
) do
228 for mmodule
in mmodules
do
230 for mclassdef
in mmodule
.mclassdefs
do
231 if mclassdef
.mclass
.kind
== interface_kind
then value
+= 1
233 values
[mmodule
] = value
238 # Module Metric: Number of Enum in module (intro + redef)
242 redef fun name
do return "mnbec"
243 redef fun desc
do return "number of enum in module (intro + redef)"
245 redef fun collect
(mmodules
) do
246 for mmodule
in mmodules
do
248 for mclassdef
in mmodule
.mclassdefs
do
249 if mclassdef
.mclass
.kind
== enum_kind
then value
+= 1
251 values
[mmodule
] = value