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
25 redef class ToolContext
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"
40 print toolcontext
.format_h1
("\n# MClasses metrics")
42 var metrics
= new MetricSet
43 var min_vis
= private_visibility
44 metrics
.register
(new CNOA(mainmodule
))
45 metrics
.register
(new CNOP(mainmodule
))
46 metrics
.register
(new CNOC(mainmodule
))
47 metrics
.register
(new CNOD(mainmodule
))
48 metrics
.register
(new CDIT(mainmodule
))
49 metrics
.register
(new CNBP(mainmodule
, min_vis
))
50 metrics
.register
(new CNBA(mainmodule
, min_vis
))
51 metrics
.register
(new CNBIP(mainmodule
, min_vis
))
52 metrics
.register
(new CNBRP(mainmodule
, min_vis
))
53 metrics
.register
(new CNBHP(mainmodule
, min_vis
))
54 #TODO metrics.register(new CNBI) # nb init
55 #TODO metrics.register(new CNBM) # nb methods
56 #TODO metrics.register(new CNBV) # nb vtypes
58 var model
= toolcontext
.modelbuilder
.model
59 var mclasses
= new HashSet[MClass]
60 for mproject
in model
.mprojects
do
62 print toolcontext
.format_h2
("\n ## project {mproject}")
64 for mgroup
in mproject
.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
.save
("{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
.save
("{out}/summary.csv")
90 # A metric about MClass
91 interface MClassMetric
93 redef type ELM: MClass
96 # Class Metric: Number of Ancestors
100 redef fun name
do return "cnoa"
101 redef fun desc
do return "number of ancestor classes"
103 var mainmodule
: MModule
104 init(mainmodule
: MModule) do self.mainmodule
= mainmodule
106 redef fun collect
(mclasses
) do
107 for mclass
in mclasses
do
108 values
[mclass
] = mclass
.in_hierarchy
(mainmodule
).greaters
.length
- 1
113 # Class Metric: Number of Parents
117 redef fun name
do return "cnop"
118 redef fun desc
do return "number of parent classes"
120 var mainmodule
: MModule
121 init(mainmodule
: MModule) do self.mainmodule
= mainmodule
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 var mainmodule
: MModule
138 init(mainmodule
: MModule) do self.mainmodule
= mainmodule
140 redef fun collect
(mclasses
) do
141 for mclass
in mclasses
do
142 values
[mclass
] = mclass
.in_hierarchy
(mainmodule
).direct_smallers
.length
147 # Class Metric: Number of Descendants
151 redef fun name
do return "cnod"
152 redef fun desc
do return "number of descendant classes"
154 var mainmodule
: MModule
155 init(mainmodule
: MModule) do self.mainmodule
= mainmodule
157 redef fun collect
(mclasses
) do
158 for mclass
in mclasses
do
159 values
[mclass
] = mclass
.in_hierarchy
(mainmodule
).smallers
.length
- 1
164 # Class Metric: Depth in Inheritance Tree
168 redef fun name
do return "cdit"
169 redef fun desc
do return "depth in class tree"
171 var mainmodule
: MModule
172 init(mainmodule
: MModule) do self.mainmodule
= mainmodule
174 redef fun collect
(mclasses
) do
175 for mclass
in mclasses
do
176 values
[mclass
] = mclass
.in_hierarchy
(mainmodule
).depth
181 # Class Metric: Number of MProperties
185 redef fun name
do return "cnbp"
186 redef fun desc
do return "number of accessible properties (inherited + local)"
188 var mainmodule
: MModule
189 var min_visibility
: MVisibility
191 init(mainmodule
: MModule, min_visibility
: MVisibility) do
192 self.mainmodule
= mainmodule
193 self.min_visibility
= min_visibility
196 redef fun collect
(mclasses
) do
197 for mclass
in mclasses
do
198 values
[mclass
] = mclass
.all_mproperties
(mainmodule
, min_visibility
).length
203 # Class Metric: Number of MAttributes
207 redef fun name
do return "cnba"
208 redef fun desc
do return "number of accessible attributes (inherited + local)"
210 var mainmodule
: MModule
211 var min_visibility
: MVisibility
213 init(mainmodule
: MModule, min_visibility
: MVisibility) do
214 self.mainmodule
= mainmodule
215 self.min_visibility
= min_visibility
218 redef fun collect
(mclasses
) do
219 for mclass
in mclasses
do
220 values
[mclass
] = mclass
.all_mattributes
(mainmodule
, min_visibility
).length
225 # Class Metric: Number of Introduced MProperties
229 redef fun name
do return "cnbip"
230 redef fun desc
do return "number of introduced properties"
232 var mainmodule
: MModule
233 var min_visibility
: MVisibility
235 init(mainmodule
: MModule, min_visibility
: MVisibility) do
236 self.mainmodule
= mainmodule
237 self.min_visibility
= min_visibility
240 redef fun collect
(mclasses
) do
241 for mclass
in mclasses
do
242 values
[mclass
] = mclass
.intro_mproperties
(min_visibility
).length
247 # Class Metric: Number of Refined MProperties
251 redef fun name
do return "cnbrp"
252 redef fun desc
do return "number of redefined properties"
254 var mainmodule
: MModule
255 var min_visibility
: MVisibility
257 init(mainmodule
: MModule, min_visibility
: MVisibility) do
258 self.mainmodule
= mainmodule
259 self.min_visibility
= min_visibility
262 redef fun collect
(mclasses
) do
263 for mclass
in mclasses
do
264 values
[mclass
] = mclass
.redef_mproperties
(min_visibility
).length
269 # Class Metric: Number of Inherited MProperties
273 redef fun name
do return "cnbhp"
274 redef fun desc
do return "number of inherited properties"
276 var mainmodule
: MModule
277 var min_visibility
: MVisibility
279 init(mainmodule
: MModule, min_visibility
: MVisibility) do
280 self.mainmodule
= mainmodule
281 self.min_visibility
= min_visibility
284 redef fun collect
(mclasses
) do
285 for mclass
in mclasses
do
286 values
[mclass
] = mclass
.inherited_mproperties
(mainmodule
, min_visibility
).length
291 # Class Metric: Number of Local MProperties (Intro + Redef)
295 redef fun name
do return "cnblp"
296 redef fun desc
do return "number of local properties (intro + redef)"
298 var mainmodule
: MModule
299 var min_visibility
: MVisibility
301 init(mainmodule
: MModule, min_visibility
: MVisibility) do
302 self.mainmodule
= mainmodule
303 self.min_visibility
= min_visibility
306 redef fun collect
(mclasses
) do
307 for mclass
in mclasses
do
308 values
[mclass
] = mclass
.local_mproperties
(min_visibility
).length