872d66e20a51a418c403fd54a2e2b8cb3596936a
[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
25 # MClass related metrics phase
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 var model = toolcontext.modelbuilder.model
40 var model_view = model.private_view
41
42 print toolcontext.format_h1("\n# MClasses metrics")
43
44 var metrics = new MetricSet
45 metrics.register(new CNOA(mainmodule, model_view))
46 metrics.register(new CNOP(mainmodule, model_view))
47 metrics.register(new CNOC(mainmodule, model_view))
48 metrics.register(new CNOD(mainmodule, model_view))
49 metrics.register(new CDIT(mainmodule, model_view))
50 metrics.register(new CNBP(mainmodule, model_view))
51 metrics.register(new CNBA(mainmodule, model_view))
52 metrics.register(new CNBI(mainmodule, model_view))
53 metrics.register(new CNBM(mainmodule, model_view))
54 metrics.register(new CNBV(mainmodule, model_view))
55 metrics.register(new CNBIP(mainmodule, model_view))
56 metrics.register(new CNBRP(mainmodule, model_view))
57 metrics.register(new CNBHP(mainmodule, model_view))
58
59 var mclasses = new HashSet[MClass]
60 for mpackage in model.mpackages do
61
62 print toolcontext.format_h2("\n ## package {mpackage}")
63
64 for mgroup in mpackage.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.write_to_file("{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.write_to_file("{out}/summary.csv")
86 end
87 end
88 end
89
90 # A metric about MClass
91 abstract class MClassMetric
92 super Metric
93 redef type ELM: MClass
94
95 # Main module used for class linearization
96 var mainmodule: MModule
97
98 # Model view used to collect and filter entities
99 var model_view: ModelView
100 end
101
102 # Class Metric: Number of Ancestors
103 class CNOA
104 super MClassMetric
105 super IntMetric
106 redef fun name do return "cnoa"
107 redef fun desc do return "number of ancestor classes"
108
109 redef fun collect(mclasses) do
110 for mclass in mclasses do
111 values[mclass] = mclass.in_hierarchy(mainmodule).greaters.length - 1
112 end
113 end
114 end
115
116 # Class Metric: Number of Parents
117 class CNOP
118 super MClassMetric
119 super IntMetric
120 redef fun name do return "cnop"
121 redef fun desc do return "number of parent classes"
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 redef fun collect(mclasses) do
138 for mclass in mclasses do
139 values[mclass] = mclass.in_hierarchy(mainmodule).direct_smallers.length
140 end
141 end
142 end
143
144 # Class Metric: Number of Descendants
145 class CNOD
146 super MClassMetric
147 super IntMetric
148 redef fun name do return "cnod"
149 redef fun desc do return "number of descendant classes"
150
151 redef fun collect(mclasses) do
152 for mclass in mclasses do
153 values[mclass] = mclass.in_hierarchy(mainmodule).smallers.length - 1
154 end
155 end
156 end
157
158 # Class Metric: Depth in Inheritance Tree
159 class CDIT
160 super MClassMetric
161 super IntMetric
162 redef fun name do return "cdit"
163 redef fun desc do return "depth in class tree"
164
165 redef fun collect(mclasses) do
166 for mclass in mclasses do
167 values[mclass] = mclass.in_hierarchy(mainmodule).depth
168 end
169 end
170 end
171
172 # Class Metric: Number of MProperties
173 class CNBP
174 super MClassMetric
175 super IntMetric
176 redef fun name do return "cnbp"
177 redef fun desc do return "number of accessible properties (inherited + local)"
178
179 redef fun collect(mclasses) do
180 for mclass in mclasses do
181 values[mclass] = mclass.collect_accessible_mproperties(model_view).length
182 end
183 end
184 end
185
186 # Class Metric: Number of MAttributes
187 class CNBA
188 super MClassMetric
189 super IntMetric
190 redef fun name do return "cnba"
191 redef fun desc do return "number of accessible attributes (inherited + local)"
192
193 redef fun collect(mclasses) do
194 for mclass in mclasses do
195 values[mclass] = mclass.collect_accessible_mattributes(model_view).length
196 end
197 end
198 end
199
200 # Class Metric: Number of MMethods
201 class CNBM
202 super MClassMetric
203 super IntMetric
204 redef fun name do return "cnbm"
205 redef fun desc do return "number of accessible methods (inherited + local)"
206
207 redef fun collect(mclasses) do
208 for mclass in mclasses do
209 values[mclass] = mclass.collect_accessible_mmethods(model_view).length
210 end
211 end
212 end
213
214 # Class Metric: Number of Constructors
215 class CNBI
216 super MClassMetric
217 super IntMetric
218 redef fun name do return "cnbi"
219 redef fun desc do return "number of accessible constructors (inherited + local)"
220
221 redef fun collect(mclasses) do
222 for mclass in mclasses do
223 values[mclass] = mclass.collect_accessible_inits(model_view).length
224 end
225 end
226 end
227
228 # Class Metric: Number of Virtual Types
229 class CNBV
230 super MClassMetric
231 super IntMetric
232 redef fun name do return "cnbv"
233 redef fun desc do return "number of accessible virtual types (inherited + local)"
234
235 redef fun collect(mclasses) do
236 for mclass in mclasses do
237 values[mclass] = mclass.collect_accessible_vts(model_view).length
238 end
239 end
240 end
241
242 # Class Metric: Number of Introduced MProperties
243 class CNBIP
244 super MClassMetric
245 super IntMetric
246 redef fun name do return "cnbip"
247 redef fun desc do return "number of introduced properties"
248
249 redef fun collect(mclasses) do
250 for mclass in mclasses do
251 values[mclass] = mclass.collect_intro_mproperties(model_view).length
252 end
253 end
254 end
255
256 # Class Metric: Number of Refined MProperties
257 class CNBRP
258 super MClassMetric
259 super IntMetric
260 redef fun name do return "cnbrp"
261 redef fun desc do return "number of redefined properties"
262
263 redef fun collect(mclasses) do
264 for mclass in mclasses do
265 values[mclass] = mclass.collect_redef_mproperties(model_view).length
266 end
267 end
268 end
269
270 # Class Metric: Number of Inherited MProperties
271 class CNBHP
272 super MClassMetric
273 super IntMetric
274 redef fun name do return "cnbhp"
275 redef fun desc do return "number of inherited properties"
276
277 redef fun collect(mclasses) do
278 for mclass in mclasses do
279 values[mclass] = mclass.collect_inherited_mproperties(model_view).length
280 end
281 end
282 end
283
284 # Class Metric: Number of Local MProperties (Intro + Redef)
285 class CNBLP
286 super MClassMetric
287 super IntMetric
288 redef fun name do return "cnblp"
289 redef fun desc do return "number of local properties (intro + redef)"
290
291 redef fun collect(mclasses) do
292 for mclass in mclasses do
293 values[mclass] = mclass.collect_local_mproperties(model_view).length
294 end
295 end
296 end