metrics: update ModelView
[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 = new ModelView(model, mainmodule)
41
42 print toolcontext.format_h1("\n# MClasses metrics")
43
44 var metrics = new MetricSet
45 metrics.register(new CNOA(model_view))
46 metrics.register(new CNOP(model_view))
47 metrics.register(new CNOC(model_view))
48 metrics.register(new CNOD(model_view))
49 metrics.register(new CDIT(model_view))
50 metrics.register(new CNBP(model_view))
51 metrics.register(new CNBA(model_view))
52 metrics.register(new CNBI(model_view))
53 metrics.register(new CNBM(model_view))
54 metrics.register(new CNBV(model_view))
55 metrics.register(new CNBIP(model_view))
56 metrics.register(new CNBRP(model_view))
57 metrics.register(new CNBHP(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 # Model view used to collect and filter entities
96 var model_view: ModelView
97 end
98
99 # Class Metric: Number of Ancestors
100 class CNOA
101 super MClassMetric
102 super IntMetric
103 redef fun name do return "cnoa"
104 redef fun desc do return "number of ancestor classes"
105
106 redef fun collect(mclasses) do
107 for mclass in mclasses do
108 values[mclass] = mclass.in_hierarchy(model_view.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 redef fun collect(mclasses) do
121 for mclass in mclasses do
122 values[mclass] = mclass.in_hierarchy(model_view.mainmodule).direct_greaters.length
123 end
124 end
125 end
126
127 # Class Metric: Number of Children
128 class CNOC
129 super MClassMetric
130 super IntMetric
131 redef fun name do return "cnoc"
132 redef fun desc do return "number of child classes"
133
134 redef fun collect(mclasses) do
135 for mclass in mclasses do
136 values[mclass] = mclass.in_hierarchy(model_view.mainmodule).direct_smallers.length
137 end
138 end
139 end
140
141 # Class Metric: Number of Descendants
142 class CNOD
143 super MClassMetric
144 super IntMetric
145 redef fun name do return "cnod"
146 redef fun desc do return "number of descendant classes"
147
148 redef fun collect(mclasses) do
149 for mclass in mclasses do
150 values[mclass] = mclass.in_hierarchy(model_view.mainmodule).smallers.length - 1
151 end
152 end
153 end
154
155 # Class Metric: Depth in Inheritance Tree
156 class CDIT
157 super MClassMetric
158 super IntMetric
159 redef fun name do return "cdit"
160 redef fun desc do return "depth in class tree"
161
162 redef fun collect(mclasses) do
163 for mclass in mclasses do
164 values[mclass] = mclass.in_hierarchy(model_view.mainmodule).depth
165 end
166 end
167 end
168
169 # Class Metric: Number of MProperties
170 class CNBP
171 super MClassMetric
172 super IntMetric
173 redef fun name do return "cnbp"
174 redef fun desc do return "number of accessible properties (inherited + local)"
175
176 redef fun collect(mclasses) do
177 for mclass in mclasses do
178 values[mclass] = mclass.collect_accessible_mproperties(model_view).length
179 end
180 end
181 end
182
183 # Class Metric: Number of MAttributes
184 class CNBA
185 super MClassMetric
186 super IntMetric
187 redef fun name do return "cnba"
188 redef fun desc do return "number of accessible attributes (inherited + local)"
189
190 redef fun collect(mclasses) do
191 for mclass in mclasses do
192 values[mclass] = mclass.collect_accessible_mattributes(model_view).length
193 end
194 end
195 end
196
197 # Class Metric: Number of MMethods
198 class CNBM
199 super MClassMetric
200 super IntMetric
201 redef fun name do return "cnbm"
202 redef fun desc do return "number of accessible methods (inherited + local)"
203
204 redef fun collect(mclasses) do
205 for mclass in mclasses do
206 values[mclass] = mclass.collect_accessible_mmethods(model_view).length
207 end
208 end
209 end
210
211 # Class Metric: Number of Constructors
212 class CNBI
213 super MClassMetric
214 super IntMetric
215 redef fun name do return "cnbi"
216 redef fun desc do return "number of accessible constructors (inherited + local)"
217
218 redef fun collect(mclasses) do
219 for mclass in mclasses do
220 values[mclass] = mclass.collect_accessible_inits(model_view).length
221 end
222 end
223 end
224
225 # Class Metric: Number of Virtual Types
226 class CNBV
227 super MClassMetric
228 super IntMetric
229 redef fun name do return "cnbv"
230 redef fun desc do return "number of accessible virtual types (inherited + local)"
231
232 redef fun collect(mclasses) do
233 for mclass in mclasses do
234 values[mclass] = mclass.collect_accessible_vts(model_view).length
235 end
236 end
237 end
238
239 # Class Metric: Number of Introduced MProperties
240 class CNBIP
241 super MClassMetric
242 super IntMetric
243 redef fun name do return "cnbip"
244 redef fun desc do return "number of introduced properties"
245
246 redef fun collect(mclasses) do
247 for mclass in mclasses do
248 values[mclass] = mclass.collect_intro_mproperties(model_view).length
249 end
250 end
251 end
252
253 # Class Metric: Number of Refined MProperties
254 class CNBRP
255 super MClassMetric
256 super IntMetric
257 redef fun name do return "cnbrp"
258 redef fun desc do return "number of redefined properties"
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 redef fun collect(mclasses) do
275 for mclass in mclasses do
276 values[mclass] = mclass.collect_inherited_mproperties(model_view).length
277 end
278 end
279 end
280
281 # Class Metric: Number of Local MProperties (Intro + Redef)
282 class CNBLP
283 super MClassMetric
284 super IntMetric
285 redef fun name do return "cnblp"
286 redef fun desc do return "number of local properties (intro + redef)"
287
288 redef fun collect(mclasses) do
289 for mclass in mclasses do
290 values[mclass] = mclass.collect_local_mproperties(model_view).length
291 end
292 end
293 end