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
24 var mclasses_metrics_phase
: Phase = new MClassesMetricsPhase(self, null)
27 # Extract metrics about mclasses from model.
28 private class MClassesMetricsPhase
30 redef fun process_mainmodule
(mainmodule
, given_mmodules
)
32 if not toolcontext
.opt_mclasses
.value
and not toolcontext
.opt_all
.value
then return
33 var csv
= toolcontext
.opt_csv
.value
34 var out
= "{toolcontext.opt_dir.value or else "metrics"}/mclasses"
38 print toolcontext
.format_h1
("\n# MClasses metrics")
40 var metrics
= new MetricSet
41 var min_vis
= private_visibility
42 metrics
.register
(new CNOA(mainmodule
))
43 metrics
.register
(new CNOP(mainmodule
))
44 metrics
.register
(new CNOC(mainmodule
))
45 metrics
.register
(new CNOD(mainmodule
))
46 metrics
.register
(new CDIT(mainmodule
))
47 metrics
.register
(new CNBP(mainmodule
, min_vis
))
48 metrics
.register
(new CNBA(mainmodule
, min_vis
))
49 metrics
.register
(new CNBIP(mainmodule
, min_vis
))
50 metrics
.register
(new CNBRP(mainmodule
, min_vis
))
51 metrics
.register
(new CNBHP(mainmodule
, min_vis
))
52 #TODO metrics.register(new CNBI) # nb init
53 #TODO metrics.register(new CNBM) # nb methods
54 #TODO metrics.register(new CNBV) # nb vtypes
56 var model
= toolcontext
.modelbuilder
.model
57 var mclasses
= new HashSet[MClass]
58 for mproject
in model
.mprojects
do
60 print toolcontext
.format_h2
("\n ## project {mproject}")
62 for mgroup
in mproject
.mgroups
do
63 if mgroup
.mmodules
.is_empty
then continue
67 print toolcontext
.format_h3
(" `- group {mgroup.full_name}")
68 var mod_mclasses
= new HashSet[MClass]
69 for mmodule
in mgroup
.mmodules
do mod_mclasses
.add_all
(mmodule
.intro_mclasses
)
70 if mod_mclasses
.is_empty
then continue
71 mclasses
.add_all
(mod_mclasses
)
72 metrics
.collect
(new HashSet[MClass].from
(mod_mclasses
))
73 metrics
.to_console
(1, not toolcontext
.opt_nocolors
.value
)
74 if csv
then metrics
.to_csv
.save
("{out}/{mgroup}.csv")
77 if not mclasses
.is_empty
then
80 print toolcontext
.format_h2
("\n ## global metrics")
81 metrics
.collect
(mclasses
)
82 metrics
.to_console
(1, not toolcontext
.opt_nocolors
.value
)
83 if csv
then metrics
.to_csv
.save
("{out}/summary.csv")
88 # A metric about MClass
89 interface MClassMetric
91 redef type ELM: MClass
94 # Class Metric: Number of Ancestors
98 redef fun name
do return "cnoa"
99 redef fun desc
do return "number of ancestor classes"
101 var mainmodule
: MModule
102 init(mainmodule
: MModule) do self.mainmodule
= mainmodule
104 redef fun collect
(mclasses
) do
105 for mclass
in mclasses
do
106 values
[mclass
] = mclass
.in_hierarchy
(mainmodule
).greaters
.length
- 1
111 # Class Metric: Number of Parents
115 redef fun name
do return "cnop"
116 redef fun desc
do return "number of parent classes"
118 var mainmodule
: MModule
119 init(mainmodule
: MModule) do self.mainmodule
= mainmodule
121 redef fun collect
(mclasses
) do
122 for mclass
in mclasses
do
123 values
[mclass
] = mclass
.in_hierarchy
(mainmodule
).direct_greaters
.length
128 # Class Metric: Number of Children
132 redef fun name
do return "cnoc"
133 redef fun desc
do return "number of child classes"
135 var mainmodule
: MModule
136 init(mainmodule
: MModule) do self.mainmodule
= mainmodule
138 redef fun collect
(mclasses
) do
139 for mclass
in mclasses
do
140 values
[mclass
] = mclass
.in_hierarchy
(mainmodule
).direct_smallers
.length
145 # Class Metric: Number of Descendants
149 redef fun name
do return "cnod"
150 redef fun desc
do return "number of descendant classes"
152 var mainmodule
: MModule
153 init(mainmodule
: MModule) do self.mainmodule
= mainmodule
155 redef fun collect
(mclasses
) do
156 for mclass
in mclasses
do
157 values
[mclass
] = mclass
.in_hierarchy
(mainmodule
).smallers
.length
- 1
162 # Class Metric: Depth in Inheritance Tree
166 redef fun name
do return "cdit"
167 redef fun desc
do return "depth in class tree"
169 var mainmodule
: MModule
170 init(mainmodule
: MModule) do self.mainmodule
= mainmodule
172 redef fun collect
(mclasses
) do
173 for mclass
in mclasses
do
174 values
[mclass
] = mclass
.in_hierarchy
(mainmodule
).depth
179 # Class Metric: Number of MProperties
183 redef fun name
do return "cnbp"
184 redef fun desc
do return "number of accessible properties (inherited + local)"
186 var mainmodule
: MModule
187 var min_visibility
: MVisibility
189 init(mainmodule
: MModule, min_visibility
: MVisibility) do
190 self.mainmodule
= mainmodule
191 self.min_visibility
= min_visibility
194 redef fun collect
(mclasses
) do
195 for mclass
in mclasses
do
196 values
[mclass
] = mclass
.collect_accessible_mproperties
(min_visibility
).length
201 # Class Metric: Number of MAttributes
205 redef fun name
do return "cnba"
206 redef fun desc
do return "number of accessible attributes (inherited + local)"
208 var mainmodule
: MModule
209 var min_visibility
: MVisibility
211 init(mainmodule
: MModule, min_visibility
: MVisibility) do
212 self.mainmodule
= mainmodule
213 self.min_visibility
= min_visibility
216 redef fun collect
(mclasses
) do
217 for mclass
in mclasses
do
218 values
[mclass
] = mclass
.collect_accessible_mattributes
(min_visibility
).length
223 # Class Metric: Number of Introduced MProperties
227 redef fun name
do return "cnbip"
228 redef fun desc
do return "number of introduced properties"
230 var mainmodule
: MModule
231 var min_visibility
: MVisibility
233 init(mainmodule
: MModule, min_visibility
: MVisibility) do
234 self.mainmodule
= mainmodule
235 self.min_visibility
= min_visibility
238 redef fun collect
(mclasses
) do
239 for mclass
in mclasses
do
240 values
[mclass
] = mclass
.collect_intro_mproperties
(min_visibility
).length
245 # Class Metric: Number of Refined MProperties
249 redef fun name
do return "cnbrp"
250 redef fun desc
do return "number of redefined properties"
252 var mainmodule
: MModule
253 var min_visibility
: MVisibility
255 init(mainmodule
: MModule, min_visibility
: MVisibility) do
256 self.mainmodule
= mainmodule
257 self.min_visibility
= min_visibility
260 redef fun collect
(mclasses
) do
261 for mclass
in mclasses
do
262 values
[mclass
] = mclass
.collect_redef_mproperties
(min_visibility
).length
267 # Class Metric: Number of Inherited MProperties
271 redef fun name
do return "cnbhp"
272 redef fun desc
do return "number of inherited properties"
274 var mainmodule
: MModule
275 var min_visibility
: MVisibility
277 init(mainmodule
: MModule, min_visibility
: MVisibility) do
278 self.mainmodule
= mainmodule
279 self.min_visibility
= min_visibility
282 redef fun collect
(mclasses
) do
283 for mclass
in mclasses
do
284 values
[mclass
] = mclass
.collect_inherited_mproperties
(min_visibility
).length
289 # Class Metric: Number of Local MProperties (Intro + Redef)
293 redef fun name
do return "cnblp"
294 redef fun desc
do return "number of local properties (intro + redef)"
296 var mainmodule
: MModule
297 var min_visibility
: MVisibility
299 init(mainmodule
: MModule, min_visibility
: MVisibility) do
300 self.mainmodule
= mainmodule
301 self.min_visibility
= min_visibility
304 redef fun collect
(mclasses
) do
305 for mclass
in mclasses
do
306 values
[mclass
] = mclass
.collect_local_mproperties
(min_visibility
).length