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 mclasses
18 module mclasses_metrics
21 import model
::model_collect
23 redef class ToolContext
25 # MClass related metrics phase
26 var mclasses_metrics_phase
: Phase = new MClassesMetricsPhase(self, null)
29 # Extract metrics about mclasses from model.
30 private class MClassesMetricsPhase
32 redef fun process_mainmodule
(mainmodule
, given_mmodules
)
34 if not toolcontext
.opt_mclasses
.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"}/mclasses"
39 var model
= toolcontext
.modelbuilder
.model
40 var model_view
= model
.private_view
42 print toolcontext
.format_h1
("\n# MClasses metrics")
44 var metrics
= new MetricSet
45 metrics
.register
(new CNOA(mainmodule
, model_view
))
46 metrics
.register
(new CNOP(mainmodule
, model_view
))
47 metrics
.register
(new CNOC(mainmodule
, model_view
))
48 metrics
.register
(new CNOD(mainmodule
, model_view
))
49 metrics
.register
(new CDIT(mainmodule
, model_view
))
50 metrics
.register
(new CNBP(mainmodule
, model_view
))
51 metrics
.register
(new CNBA(mainmodule
, model_view
))
52 metrics
.register
(new CNBI(mainmodule
, model_view
))
53 metrics
.register
(new CNBM(mainmodule
, model_view
))
54 metrics
.register
(new CNBV(mainmodule
, model_view
))
55 metrics
.register
(new CNBIP(mainmodule
, model_view
))
56 metrics
.register
(new CNBRP(mainmodule
, model_view
))
57 metrics
.register
(new CNBHP(mainmodule
, model_view
))
59 var mclasses
= new HashSet[MClass]
60 for mpackage
in model
.mpackages
do
62 print toolcontext
.format_h2
("\n ## package {mpackage}")
64 for mgroup
in mpackage
.mgroups
do
65 if mgroup
.mmodules
.is_empty
then continue
69 print toolcontext
.format_h3
(" `- group {mgroup.full_name}")
70 var mod_mclasses
= new HashSet[MClass]
71 for mmodule
in mgroup
.mmodules
do mod_mclasses
.add_all
(mmodule
.intro_mclasses
)
72 if mod_mclasses
.is_empty
then continue
73 mclasses
.add_all
(mod_mclasses
)
74 metrics
.collect
(new HashSet[MClass].from
(mod_mclasses
))
75 metrics
.to_console
(1, not toolcontext
.opt_nocolors
.value
)
76 if csv
then metrics
.to_csv
.write_to_file
("{out}/{mgroup}.csv")
79 if not mclasses
.is_empty
then
82 print toolcontext
.format_h2
("\n ## global metrics")
83 metrics
.collect
(mclasses
)
84 metrics
.to_console
(1, not toolcontext
.opt_nocolors
.value
)
85 if csv
then metrics
.to_csv
.write_to_file
("{out}/summary.csv")
90 # A metric about MClass
91 abstract class MClassMetric
93 redef type ELM: MClass
95 # Main module used for class linearization
96 var mainmodule
: MModule
98 # Model view used to collect and filter entities
99 var model_view
: ModelView
102 # Class Metric: Number of Ancestors
106 redef fun name
do return "cnoa"
107 redef fun desc
do return "number of ancestor classes"
109 redef fun collect
(mclasses
) do
110 for mclass
in mclasses
do
111 values
[mclass
] = mclass
.in_hierarchy
(mainmodule
).greaters
.length
- 1
116 # Class Metric: Number of Parents
120 redef fun name
do return "cnop"
121 redef fun desc
do return "number of parent classes"
123 redef fun collect
(mclasses
) do
124 for mclass
in mclasses
do
125 values
[mclass
] = mclass
.in_hierarchy
(mainmodule
).direct_greaters
.length
130 # Class Metric: Number of Children
134 redef fun name
do return "cnoc"
135 redef fun desc
do return "number of child classes"
137 redef fun collect
(mclasses
) do
138 for mclass
in mclasses
do
139 values
[mclass
] = mclass
.in_hierarchy
(mainmodule
).direct_smallers
.length
144 # Class Metric: Number of Descendants
148 redef fun name
do return "cnod"
149 redef fun desc
do return "number of descendant classes"
151 redef fun collect
(mclasses
) do
152 for mclass
in mclasses
do
153 values
[mclass
] = mclass
.in_hierarchy
(mainmodule
).smallers
.length
- 1
158 # Class Metric: Depth in Inheritance Tree
162 redef fun name
do return "cdit"
163 redef fun desc
do return "depth in class tree"
165 redef fun collect
(mclasses
) do
166 for mclass
in mclasses
do
167 values
[mclass
] = mclass
.in_hierarchy
(mainmodule
).depth
172 # Class Metric: Number of MProperties
176 redef fun name
do return "cnbp"
177 redef fun desc
do return "number of accessible properties (inherited + local)"
179 redef fun collect
(mclasses
) do
180 for mclass
in mclasses
do
181 values
[mclass
] = mclass
.collect_accessible_mproperties
(model_view
).length
186 # Class Metric: Number of MAttributes
190 redef fun name
do return "cnba"
191 redef fun desc
do return "number of accessible attributes (inherited + local)"
193 redef fun collect
(mclasses
) do
194 for mclass
in mclasses
do
195 values
[mclass
] = mclass
.collect_accessible_mattributes
(model_view
).length
200 # Class Metric: Number of MMethods
204 redef fun name
do return "cnbm"
205 redef fun desc
do return "number of accessible methods (inherited + local)"
207 redef fun collect
(mclasses
) do
208 for mclass
in mclasses
do
209 values
[mclass
] = mclass
.collect_accessible_mmethods
(model_view
).length
214 # Class Metric: Number of Constructors
218 redef fun name
do return "cnbi"
219 redef fun desc
do return "number of accessible constructors (inherited + local)"
221 redef fun collect
(mclasses
) do
222 for mclass
in mclasses
do
223 values
[mclass
] = mclass
.collect_accessible_inits
(model_view
).length
228 # Class Metric: Number of Virtual Types
232 redef fun name
do return "cnbv"
233 redef fun desc
do return "number of accessible virtual types (inherited + local)"
235 redef fun collect
(mclasses
) do
236 for mclass
in mclasses
do
237 values
[mclass
] = mclass
.collect_accessible_vts
(model_view
).length
242 # Class Metric: Number of Introduced MProperties
246 redef fun name
do return "cnbip"
247 redef fun desc
do return "number of introduced properties"
249 redef fun collect
(mclasses
) do
250 for mclass
in mclasses
do
251 values
[mclass
] = mclass
.collect_intro_mproperties
(model_view
).length
256 # Class Metric: Number of Refined MProperties
260 redef fun name
do return "cnbrp"
261 redef fun desc
do return "number of redefined properties"
263 redef fun collect
(mclasses
) do
264 for mclass
in mclasses
do
265 values
[mclass
] = mclass
.collect_redef_mproperties
(model_view
).length
270 # Class Metric: Number of Inherited MProperties
274 redef fun name
do return "cnbhp"
275 redef fun desc
do return "number of inherited properties"
277 redef fun collect
(mclasses
) do
278 for mclass
in mclasses
do
279 values
[mclass
] = mclass
.collect_inherited_mproperties
(model_view
).length
284 # Class Metric: Number of Local MProperties (Intro + Redef)
288 redef fun name
do return "cnblp"
289 redef fun desc
do return "number of local properties (intro + redef)"
291 redef fun collect
(mclasses
) do
292 for mclass
in mclasses
do
293 values
[mclass
] = mclass
.collect_local_mproperties
(model_view
).length