update code to comply with new superstring policy
[nit.git] / src / metrics / mclasses_metrics.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2014 Alexandre Terrasa <alexandre@moz-code.org>
4 #
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
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
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.
16
17 # Collect common metrics about mclasses
18 module mclasses_metrics
19
20 import model
21 import metrics_base
22 import phase
23 import frontend
24
25 redef class ToolContext
26 var mclasses_metrics_phase: Phase = new MClassesMetricsPhase(self, null)
27 end
28
29 # Extract metrics about mclasses from model.
30 private class MClassesMetricsPhase
31 super Phase
32 redef fun process_mainmodule(mainmodule, given_mmodules)
33 do
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"
37 out.mkdir
38
39
40 print toolcontext.format_h1("\n# MClasses metrics")
41
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
57
58 var model = toolcontext.modelbuilder.model
59 var mclasses = new HashSet[MClass]
60 for mproject in model.mprojects do
61
62 print toolcontext.format_h2("\n ## project {mproject}")
63
64 for mgroup in mproject.mgroups do
65 if mgroup.mmodules.is_empty then continue
66 metrics.clear
67
68 # Scalar metrics
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")
77 end
78 end
79 if not mclasses.is_empty then
80 metrics.clear
81 # Global metrics
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")
86 end
87 end
88 end
89
90 # A metric about MClass
91 interface MClassMetric
92 super Metric
93 redef type ELM: MClass
94 end
95
96 # Class Metric: Number of Ancestors
97 class CNOA
98 super MClassMetric
99 super IntMetric
100 redef fun name do return "cnoa"
101 redef fun desc do return "number of ancestor classes"
102
103 var mainmodule: MModule
104 init(mainmodule: MModule) do self.mainmodule = mainmodule
105
106 redef fun collect(mclasses) do
107 for mclass in mclasses do
108 values[mclass] = mclass.in_hierarchy(mainmodule).greaters.length - 1
109 end
110 end
111 end
112
113 # Class Metric: Number of Parents
114 class CNOP
115 super MClassMetric
116 super IntMetric
117 redef fun name do return "cnop"
118 redef fun desc do return "number of parent classes"
119
120 var mainmodule: MModule
121 init(mainmodule: MModule) do self.mainmodule = mainmodule
122
123 redef fun collect(mclasses) do
124 for mclass in mclasses do
125 values[mclass] = mclass.in_hierarchy(mainmodule).direct_greaters.length
126 end
127 end
128 end
129
130 # Class Metric: Number of Children
131 class CNOC
132 super MClassMetric
133 super IntMetric
134 redef fun name do return "cnoc"
135 redef fun desc do return "number of child classes"
136
137 var mainmodule: MModule
138 init(mainmodule: MModule) do self.mainmodule = mainmodule
139
140 redef fun collect(mclasses) do
141 for mclass in mclasses do
142 values[mclass] = mclass.in_hierarchy(mainmodule).direct_smallers.length
143 end
144 end
145 end
146
147 # Class Metric: Number of Descendants
148 class CNOD
149 super MClassMetric
150 super IntMetric
151 redef fun name do return "cnod"
152 redef fun desc do return "number of descendant classes"
153
154 var mainmodule: MModule
155 init(mainmodule: MModule) do self.mainmodule = mainmodule
156
157 redef fun collect(mclasses) do
158 for mclass in mclasses do
159 values[mclass] = mclass.in_hierarchy(mainmodule).smallers.length - 1
160 end
161 end
162 end
163
164 # Class Metric: Depth in Inheritance Tree
165 class CDIT
166 super MClassMetric
167 super IntMetric
168 redef fun name do return "cdit"
169 redef fun desc do return "depth in class tree"
170
171 var mainmodule: MModule
172 init(mainmodule: MModule) do self.mainmodule = mainmodule
173
174 redef fun collect(mclasses) do
175 for mclass in mclasses do
176 values[mclass] = mclass.in_hierarchy(mainmodule).depth
177 end
178 end
179 end
180
181 # Class Metric: Number of MProperties
182 class CNBP
183 super MClassMetric
184 super IntMetric
185 redef fun name do return "cnbp"
186 redef fun desc do return "number of accessible properties (inherited + local)"
187
188 var mainmodule: MModule
189 var min_visibility: MVisibility
190
191 init(mainmodule: MModule, min_visibility: MVisibility) do
192 self.mainmodule = mainmodule
193 self.min_visibility = min_visibility
194 end
195
196 redef fun collect(mclasses) do
197 for mclass in mclasses do
198 values[mclass] = mclass.all_mproperties(mainmodule, min_visibility).length
199 end
200 end
201 end
202
203 # Class Metric: Number of MAttributes
204 class CNBA
205 super MClassMetric
206 super IntMetric
207 redef fun name do return "cnba"
208 redef fun desc do return "number of accessible attributes (inherited + local)"
209
210 var mainmodule: MModule
211 var min_visibility: MVisibility
212
213 init(mainmodule: MModule, min_visibility: MVisibility) do
214 self.mainmodule = mainmodule
215 self.min_visibility = min_visibility
216 end
217
218 redef fun collect(mclasses) do
219 for mclass in mclasses do
220 values[mclass] = mclass.all_mattributes(mainmodule, min_visibility).length
221 end
222 end
223 end
224
225 # Class Metric: Number of Introduced MProperties
226 class CNBIP
227 super MClassMetric
228 super IntMetric
229 redef fun name do return "cnbip"
230 redef fun desc do return "number of introduced properties"
231
232 var mainmodule: MModule
233 var min_visibility: MVisibility
234
235 init(mainmodule: MModule, min_visibility: MVisibility) do
236 self.mainmodule = mainmodule
237 self.min_visibility = min_visibility
238 end
239
240 redef fun collect(mclasses) do
241 for mclass in mclasses do
242 values[mclass] = mclass.intro_mproperties(min_visibility).length
243 end
244 end
245 end
246
247 # Class Metric: Number of Refined MProperties
248 class CNBRP
249 super MClassMetric
250 super IntMetric
251 redef fun name do return "cnbrp"
252 redef fun desc do return "number of redefined properties"
253
254 var mainmodule: MModule
255 var min_visibility: MVisibility
256
257 init(mainmodule: MModule, min_visibility: MVisibility) do
258 self.mainmodule = mainmodule
259 self.min_visibility = min_visibility
260 end
261
262 redef fun collect(mclasses) do
263 for mclass in mclasses do
264 values[mclass] = mclass.redef_mproperties(min_visibility).length
265 end
266 end
267 end
268
269 # Class Metric: Number of Inherited MProperties
270 class CNBHP
271 super MClassMetric
272 super IntMetric
273 redef fun name do return "cnbhp"
274 redef fun desc do return "number of inherited properties"
275
276 var mainmodule: MModule
277 var min_visibility: MVisibility
278
279 init(mainmodule: MModule, min_visibility: MVisibility) do
280 self.mainmodule = mainmodule
281 self.min_visibility = min_visibility
282 end
283
284 redef fun collect(mclasses) do
285 for mclass in mclasses do
286 values[mclass] = mclass.inherited_mproperties(mainmodule, min_visibility).length
287 end
288 end
289 end
290
291 # Class Metric: Number of Local MProperties (Intro + Redef)
292 class CNBLP
293 super MClassMetric
294 super IntMetric
295 redef fun name do return "cnblp"
296 redef fun desc do return "number of local properties (intro + redef)"
297
298 var mainmodule: MModule
299 var min_visibility: MVisibility
300
301 init(mainmodule: MModule, min_visibility: MVisibility) do
302 self.mainmodule = mainmodule
303 self.min_visibility = min_visibility
304 end
305
306 redef fun collect(mclasses) do
307 for mclass in mclasses do
308 values[mclass] = mclass.local_mproperties(min_visibility).length
309 end
310 end
311 end