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
22 redef class ToolContext
23 var mmodules_metrics_phase
: Phase = new MModulesMetricsPhase(self, null)
26 # Extract metrics about modules from the model.
27 private class MModulesMetricsPhase
29 redef fun process_mainmodule
(mainmodule
, given_mmodules
)
31 if not toolcontext
.opt_mmodules
.value
and not toolcontext
.opt_all
.value
then return
32 var csv
= toolcontext
.opt_csv
.value
33 var out
= "{toolcontext.opt_dir.value or else "metrics"}/mmodules"
36 print toolcontext
.format_h1
("\n# MModules metrics")
38 var metrics
= new MetricSet
39 metrics
.register
(new MNOA, new MNOP, new MNOC, new MNOD, new MDIT)
40 metrics
.register
(new MNBI, new MNBR, new MNBCC, new MNBAC, new MNBIC)
42 var model
= toolcontext
.modelbuilder
.model
43 var mmodules
= new HashSet[MModule]
44 for mproject
in model
.mprojects
do
46 print toolcontext
.format_h2
("\n ## project {mproject}")
47 for mgroup
in mproject
.mgroups
do
48 if mgroup
.mmodules
.is_empty
then continue
51 print toolcontext
.format_h3
(" `- group {mgroup.full_name}")
52 mmodules
.add_all
(mgroup
.mmodules
)
54 metrics
.collect
(new HashSet[MModule].from
(mgroup
.mmodules
))
55 metrics
.to_console
(1, not toolcontext
.opt_nocolors
.value
)
56 if csv
then metrics
.to_csv
.save
("{out}/{mgroup}.csv")
59 if not mmodules
.is_empty
then
61 print toolcontext
.format_h2
("\n ## global metrics")
63 metrics
.collect
(mmodules
)
64 metrics
.to_console
(1, not toolcontext
.opt_nocolors
.value
)
65 if csv
then metrics
.to_csv
.save
("{out}/summary.csv")
70 # A metric about MModule
71 interface MModuleMetric
73 redef type ELM: MModule
76 # Module Metric: Number of Ancestors
80 redef fun name
do return "mnoa"
81 redef fun desc
do return "number of ancestor modules"
83 redef fun collect
(mmodules
) do
84 for mmodule
in mmodules
do
85 values
[mmodule
] = mmodule
.in_importation
.greaters
.length
- 1
90 # Module Metric: Number of Parents
94 redef fun name
do return "mnop"
95 redef fun desc
do return "number of parent modules"
97 redef fun collect
(mmodules
) do
98 for mmodule
in mmodules
do
99 values
[mmodule
] = mmodule
.in_importation
.direct_greaters
.length
104 # Module Metric: Number of Children
108 redef fun name
do return "mnoc"
109 redef fun desc
do return "number of child modules"
111 redef fun collect
(mmodules
) do
112 for mmodule
in mmodules
do
113 values
[mmodule
] = mmodule
.in_importation
.direct_smallers
.length
118 # Module Metric: Number of Descendants
122 redef fun name
do return "mnod"
123 redef fun desc
do return "number of descendant modules"
125 redef fun collect
(mmodules
) do
126 for mmodule
in mmodules
do
127 values
[mmodule
] = mmodule
.in_importation
.smallers
.length
- 1
132 # Module Metric: Depth in Tree
136 redef fun name
do return "mdit"
137 redef fun desc
do return "depth in module tree"
139 redef fun collect
(mmodules
) do
140 for mmodule
in mmodules
do
141 values
[mmodule
] = mmodule
.in_importation
.depth
146 # Module Metric: Number of Introduction (of all kind)
148 # count all mclasses introduced by the module
152 redef fun name
do return "mnbi"
153 redef fun desc
do return "number of introduction in module"
155 redef fun collect
(mmodules
) do
156 for mmodule
in mmodules
do
157 values
[mmodule
] = mmodule
.intro_mclasses
.length
162 # Module Metric: Number of Refinement
164 # count all mclasses refined in the module
168 redef fun name
do return "mnbr"
169 redef fun desc
do return "number of refinement in module"
171 redef fun collect
(mmodules
) do
172 for mmodule
in mmodules
do
174 for mclassdef
in mmodule
.mclassdefs
do
175 if not mclassdef
.is_intro
then value
+= 1
177 values
[mmodule
] = value
182 # Module Metric: Number of Concrete Class in module (intro + redef)
186 redef fun name
do return "mnbcc"
187 redef fun desc
do return "number of concrete class in module (intro + redef)"
189 redef fun collect
(mmodules
) do
190 for mmodule
in mmodules
do
192 for mclassdef
in mmodule
.mclassdefs
do
193 if mclassdef
.mclass
.kind
== concrete_kind
then value
+= 1
195 values
[mmodule
] = value
200 # Module Metric: Number of Abstract Class in module (intro + redef)
204 redef fun name
do return "mnbac"
205 redef fun desc
do return "number of abstract class in module (intro + redef)"
207 redef fun collect
(mmodules
) do
208 for mmodule
in mmodules
do
210 for mclassdef
in mmodule
.mclassdefs
do
211 if mclassdef
.mclass
.kind
== abstract_kind
then value
+= 1
213 values
[mmodule
] = value
218 # Module Metric: Number of Interface in module (intro + redef)
222 redef fun name
do return "mnbic"
223 redef fun desc
do return "number of interface in module (intro + redef)"
225 redef fun collect
(mmodules
) do
226 for mmodule
in mmodules
do
228 for mclassdef
in mmodule
.mclassdefs
do
229 if mclassdef
.mclass
.kind
== interface_kind
then value
+= 1
231 values
[mmodule
] = value
236 # Module Metric: Number of Enum in module (intro + redef)
240 redef fun name
do return "mnbec"
241 redef fun desc
do return "number of enum in module (intro + redef)"
243 redef fun collect
(mmodules
) do
244 for mmodule
in mmodules
do
246 for mclassdef
in mmodule
.mclassdefs
do
247 if mclassdef
.mclass
.kind
== enum_kind
then value
+= 1
249 values
[mmodule
] = value