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
22 redef class ToolContext
23 var mclasses_metrics_phase
: Phase = new MClassesMetricsPhase(self, null)
26 # Extract metrics about mclasses from model.
27 private class MClassesMetricsPhase
29 redef fun process_mainmodule
(mainmodule
, given_mmodules
)
31 if not toolcontext
.opt_mclasses
.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"}/mclasses"
37 print toolcontext
.format_h1
("\n# MClasses metrics")
39 var metrics
= new MetricSet
40 var min_vis
= private_visibility
41 metrics
.register
(new CNOA(mainmodule
))
42 metrics
.register
(new CNOP(mainmodule
))
43 metrics
.register
(new CNOC(mainmodule
))
44 metrics
.register
(new CNOD(mainmodule
))
45 metrics
.register
(new CDIT(mainmodule
))
46 metrics
.register
(new CNBP(mainmodule
, min_vis
))
47 metrics
.register
(new CNBA(mainmodule
, min_vis
))
48 metrics
.register
(new CNBIP(mainmodule
, min_vis
))
49 metrics
.register
(new CNBRP(mainmodule
, min_vis
))
50 metrics
.register
(new CNBHP(mainmodule
, min_vis
))
51 #TODO metrics.register(new CNBI) # nb init
52 #TODO metrics.register(new CNBM) # nb methods
53 #TODO metrics.register(new CNBV) # nb vtypes
55 var model
= toolcontext
.modelbuilder
.model
56 var mclasses
= new HashSet[MClass]
57 for mproject
in model
.mprojects
do
59 print toolcontext
.format_h2
("\n ## project {mproject}")
61 for mgroup
in mproject
.mgroups
do
62 if mgroup
.mmodules
.is_empty
then continue
66 print toolcontext
.format_h3
(" `- group {mgroup.full_name}")
67 var mod_mclasses
= new HashSet[MClass]
68 for mmodule
in mgroup
.mmodules
do mod_mclasses
.add_all
(mmodule
.intro_mclasses
)
69 if mod_mclasses
.is_empty
then continue
70 mclasses
.add_all
(mod_mclasses
)
71 metrics
.collect
(new HashSet[MClass].from
(mod_mclasses
))
72 metrics
.to_console
(1, not toolcontext
.opt_nocolors
.value
)
73 if csv
then metrics
.to_csv
.save
("{out}/{mgroup}.csv")
76 if not mclasses
.is_empty
then
79 print toolcontext
.format_h2
("\n ## global metrics")
80 metrics
.collect
(mclasses
)
81 metrics
.to_console
(1, not toolcontext
.opt_nocolors
.value
)
82 if csv
then metrics
.to_csv
.save
("{out}/summary.csv")
87 # A metric about MClass
88 interface MClassMetric
90 redef type ELM: MClass
93 # Class Metric: Number of Ancestors
97 redef fun name
do return "cnoa"
98 redef fun desc
do return "number of ancestor classes"
100 var mainmodule
: MModule
101 init(mainmodule
: MModule) do self.mainmodule
= mainmodule
103 redef fun collect
(mclasses
) do
104 for mclass
in mclasses
do
105 values
[mclass
] = mclass
.in_hierarchy
(mainmodule
).greaters
.length
- 1
110 # Class Metric: Number of Parents
114 redef fun name
do return "cnop"
115 redef fun desc
do return "number of parent classes"
117 var mainmodule
: MModule
118 init(mainmodule
: MModule) do self.mainmodule
= mainmodule
120 redef fun collect
(mclasses
) do
121 for mclass
in mclasses
do
122 values
[mclass
] = mclass
.in_hierarchy
(mainmodule
).direct_greaters
.length
127 # Class Metric: Number of Children
131 redef fun name
do return "cnoc"
132 redef fun desc
do return "number of child classes"
134 var mainmodule
: MModule
135 init(mainmodule
: MModule) do self.mainmodule
= mainmodule
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 var mainmodule
: MModule
152 init(mainmodule
: MModule) do self.mainmodule
= mainmodule
154 redef fun collect
(mclasses
) do
155 for mclass
in mclasses
do
156 values
[mclass
] = mclass
.in_hierarchy
(mainmodule
).smallers
.length
- 1
161 # Class Metric: Depth in Inheritance Tree
165 redef fun name
do return "cdit"
166 redef fun desc
do return "depth in class tree"
168 var mainmodule
: MModule
169 init(mainmodule
: MModule) do self.mainmodule
= mainmodule
171 redef fun collect
(mclasses
) do
172 for mclass
in mclasses
do
173 values
[mclass
] = mclass
.in_hierarchy
(mainmodule
).depth
178 # Class Metric: Number of MProperties
182 redef fun name
do return "cnbp"
183 redef fun desc
do return "number of accessible properties (inherited + local)"
185 var mainmodule
: MModule
186 var min_visibility
: MVisibility
188 init(mainmodule
: MModule, min_visibility
: MVisibility) do
189 self.mainmodule
= mainmodule
190 self.min_visibility
= min_visibility
193 redef fun collect
(mclasses
) do
194 for mclass
in mclasses
do
195 values
[mclass
] = mclass
.all_mproperties
(mainmodule
, min_visibility
).length
200 # Class Metric: Number of MAttributes
204 redef fun name
do return "cnba"
205 redef fun desc
do return "number of accessible attributes (inherited + local)"
207 var mainmodule
: MModule
208 var min_visibility
: MVisibility
210 init(mainmodule
: MModule, min_visibility
: MVisibility) do
211 self.mainmodule
= mainmodule
212 self.min_visibility
= min_visibility
215 redef fun collect
(mclasses
) do
216 for mclass
in mclasses
do
217 values
[mclass
] = mclass
.all_mattributes
(mainmodule
, min_visibility
).length
222 # Class Metric: Number of Introduced MProperties
226 redef fun name
do return "cnbip"
227 redef fun desc
do return "number of introduced properties"
229 var mainmodule
: MModule
230 var min_visibility
: MVisibility
232 init(mainmodule
: MModule, min_visibility
: MVisibility) do
233 self.mainmodule
= mainmodule
234 self.min_visibility
= min_visibility
237 redef fun collect
(mclasses
) do
238 for mclass
in mclasses
do
239 values
[mclass
] = mclass
.intro_mproperties
(min_visibility
).length
244 # Class Metric: Number of Refined MProperties
248 redef fun name
do return "cnbrp"
249 redef fun desc
do return "number of redefined properties"
251 var mainmodule
: MModule
252 var min_visibility
: MVisibility
254 init(mainmodule
: MModule, min_visibility
: MVisibility) do
255 self.mainmodule
= mainmodule
256 self.min_visibility
= min_visibility
259 redef fun collect
(mclasses
) do
260 for mclass
in mclasses
do
261 values
[mclass
] = mclass
.redef_mproperties
(min_visibility
).length
266 # Class Metric: Number of Inherited MProperties
270 redef fun name
do return "cnbhp"
271 redef fun desc
do return "number of inherited properties"
273 var mainmodule
: MModule
274 var min_visibility
: MVisibility
276 init(mainmodule
: MModule, min_visibility
: MVisibility) do
277 self.mainmodule
= mainmodule
278 self.min_visibility
= min_visibility
281 redef fun collect
(mclasses
) do
282 for mclass
in mclasses
do
283 values
[mclass
] = mclass
.inherited_mproperties
(mainmodule
, min_visibility
).length
288 # Class Metric: Number of Local MProperties (Intro + Redef)
292 redef fun name
do return "cnblp"
293 redef fun desc
do return "number of local properties (intro + redef)"
295 var mainmodule
: MModule
296 var min_visibility
: MVisibility
298 init(mainmodule
: MModule, min_visibility
: MVisibility) do
299 self.mainmodule
= mainmodule
300 self.min_visibility
= min_visibility
303 redef fun collect
(mclasses
) do
304 for mclass
in mclasses
do
305 values
[mclass
] = mclass
.local_mproperties
(min_visibility
).length