src: Updated uses of CSV library
[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 metrics_base
21 import model::model_collect
22
23 redef class ToolContext
24 var mclasses_metrics_phase: Phase = new MClassesMetricsPhase(self, null)
25 end
26
27 # Extract metrics about mclasses from model.
28 private class MClassesMetricsPhase
29 super Phase
30 redef fun process_mainmodule(mainmodule, given_mmodules)
31 do
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"
35 out.mkdir
36
37 var model = toolcontext.modelbuilder.model
38 var model_view = model.private_view
39
40 print toolcontext.format_h1("\n# MClasses metrics")
41
42 var metrics = new MetricSet
43 metrics.register(new CNOA(mainmodule))
44 metrics.register(new CNOP(mainmodule))
45 metrics.register(new CNOC(mainmodule))
46 metrics.register(new CNOD(mainmodule))
47 metrics.register(new CDIT(mainmodule))
48 metrics.register(new CNBP(mainmodule, model_view))
49 metrics.register(new CNBA(mainmodule, model_view))
50 metrics.register(new CNBIP(mainmodule, model_view))
51 metrics.register(new CNBRP(mainmodule, model_view))
52 metrics.register(new CNBHP(mainmodule, model_view))
53 #TODO metrics.register(new CNBI) # nb init
54 #TODO metrics.register(new CNBM) # nb methods
55 #TODO metrics.register(new CNBV) # nb vtypes
56
57 var mclasses = new HashSet[MClass]
58 for mpackage in model.mpackages do
59
60 print toolcontext.format_h2("\n ## package {mpackage}")
61
62 for mgroup in mpackage.mgroups do
63 if mgroup.mmodules.is_empty then continue
64 metrics.clear
65
66 # Scalar metrics
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.write_to_file("{out}/{mgroup}.csv")
75 end
76 end
77 if not mclasses.is_empty then
78 metrics.clear
79 # Global metrics
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.write_to_file("{out}/summary.csv")
84 end
85 end
86 end
87
88 # A metric about MClass
89 interface MClassMetric
90 super Metric
91 redef type ELM: MClass
92 end
93
94 # Class Metric: Number of Ancestors
95 class CNOA
96 super MClassMetric
97 super IntMetric
98 redef fun name do return "cnoa"
99 redef fun desc do return "number of ancestor classes"
100
101 var mainmodule: MModule
102 init(mainmodule: MModule) do self.mainmodule = mainmodule
103
104 redef fun collect(mclasses) do
105 for mclass in mclasses do
106 values[mclass] = mclass.in_hierarchy(mainmodule).greaters.length - 1
107 end
108 end
109 end
110
111 # Class Metric: Number of Parents
112 class CNOP
113 super MClassMetric
114 super IntMetric
115 redef fun name do return "cnop"
116 redef fun desc do return "number of parent classes"
117
118 var mainmodule: MModule
119 init(mainmodule: MModule) do self.mainmodule = mainmodule
120
121 redef fun collect(mclasses) do
122 for mclass in mclasses do
123 values[mclass] = mclass.in_hierarchy(mainmodule).direct_greaters.length
124 end
125 end
126 end
127
128 # Class Metric: Number of Children
129 class CNOC
130 super MClassMetric
131 super IntMetric
132 redef fun name do return "cnoc"
133 redef fun desc do return "number of child classes"
134
135 var mainmodule: MModule
136 init(mainmodule: MModule) do self.mainmodule = mainmodule
137
138 redef fun collect(mclasses) do
139 for mclass in mclasses do
140 values[mclass] = mclass.in_hierarchy(mainmodule).direct_smallers.length
141 end
142 end
143 end
144
145 # Class Metric: Number of Descendants
146 class CNOD
147 super MClassMetric
148 super IntMetric
149 redef fun name do return "cnod"
150 redef fun desc do return "number of descendant classes"
151
152 var mainmodule: MModule
153 init(mainmodule: MModule) do self.mainmodule = mainmodule
154
155 redef fun collect(mclasses) do
156 for mclass in mclasses do
157 values[mclass] = mclass.in_hierarchy(mainmodule).smallers.length - 1
158 end
159 end
160 end
161
162 # Class Metric: Depth in Inheritance Tree
163 class CDIT
164 super MClassMetric
165 super IntMetric
166 redef fun name do return "cdit"
167 redef fun desc do return "depth in class tree"
168
169 var mainmodule: MModule
170 init(mainmodule: MModule) do self.mainmodule = mainmodule
171
172 redef fun collect(mclasses) do
173 for mclass in mclasses do
174 values[mclass] = mclass.in_hierarchy(mainmodule).depth
175 end
176 end
177 end
178
179 # Class Metric: Number of MProperties
180 class CNBP
181 super MClassMetric
182 super IntMetric
183 redef fun name do return "cnbp"
184 redef fun desc do return "number of accessible properties (inherited + local)"
185
186 var mainmodule: MModule
187 var model_view: ModelView
188
189 init(mainmodule: MModule, model_view: ModelView) do
190 self.mainmodule = mainmodule
191 self.model_view = model_view
192 end
193
194 redef fun collect(mclasses) do
195 for mclass in mclasses do
196 values[mclass] = mclass.collect_accessible_mproperties(model_view).length
197 end
198 end
199 end
200
201 # Class Metric: Number of MAttributes
202 class CNBA
203 super MClassMetric
204 super IntMetric
205 redef fun name do return "cnba"
206 redef fun desc do return "number of accessible attributes (inherited + local)"
207
208 var mainmodule: MModule
209 var model_view: ModelView
210
211 init(mainmodule: MModule, model_view: ModelView) do
212 self.mainmodule = mainmodule
213 self.model_view = model_view
214 end
215
216 redef fun collect(mclasses) do
217 for mclass in mclasses do
218 values[mclass] = mclass.collect_accessible_mattributes(model_view).length
219 end
220 end
221 end
222
223 # Class Metric: Number of Introduced MProperties
224 class CNBIP
225 super MClassMetric
226 super IntMetric
227 redef fun name do return "cnbip"
228 redef fun desc do return "number of introduced properties"
229
230 var mainmodule: MModule
231 var model_view: ModelView
232
233 init(mainmodule: MModule, model_view: ModelView) do
234 self.mainmodule = mainmodule
235 self.model_view = model_view
236 end
237
238 redef fun collect(mclasses) do
239 for mclass in mclasses do
240 values[mclass] = mclass.collect_intro_mproperties(model_view).length
241 end
242 end
243 end
244
245 # Class Metric: Number of Refined MProperties
246 class CNBRP
247 super MClassMetric
248 super IntMetric
249 redef fun name do return "cnbrp"
250 redef fun desc do return "number of redefined properties"
251
252 var mainmodule: MModule
253 var model_view: ModelView
254
255 init(mainmodule: MModule, model_view: ModelView) do
256 self.mainmodule = mainmodule
257 self.model_view = model_view
258 end
259
260 redef fun collect(mclasses) do
261 for mclass in mclasses do
262 values[mclass] = mclass.collect_redef_mproperties(model_view).length
263 end
264 end
265 end
266
267 # Class Metric: Number of Inherited MProperties
268 class CNBHP
269 super MClassMetric
270 super IntMetric
271 redef fun name do return "cnbhp"
272 redef fun desc do return "number of inherited properties"
273
274 var mainmodule: MModule
275 var model_view: ModelView
276
277 init(mainmodule: MModule, model_view: ModelView) do
278 self.mainmodule = mainmodule
279 self.model_view = model_view
280 end
281
282 redef fun collect(mclasses) do
283 for mclass in mclasses do
284 values[mclass] = mclass.collect_inherited_mproperties(model_view).length
285 end
286 end
287 end
288
289 # Class Metric: Number of Local MProperties (Intro + Redef)
290 class CNBLP
291 super MClassMetric
292 super IntMetric
293 redef fun name do return "cnblp"
294 redef fun desc do return "number of local properties (intro + redef)"
295
296 var mainmodule: MModule
297 var model_view: ModelView
298
299 init(mainmodule: MModule, model_view: ModelView) do
300 self.mainmodule = mainmodule
301 self.model_view = model_view
302 end
303
304 redef fun collect(mclasses) do
305 for mclass in mclasses do
306 values[mclass] = mclass.collect_local_mproperties(model_view).length
307 end
308 end
309 end