Merge: doc: fixed some typos and other misc. corrections
[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 filter = new ModelFilter(private_visibility)
41
42 print toolcontext.format_h1("\n# MClasses metrics")
43
44 var metrics = new MetricSet
45 metrics.register(new CNOA(model, mainmodule, filter))
46 metrics.register(new CNOP(model, mainmodule, filter))
47 metrics.register(new CNOC(model, mainmodule, filter))
48 metrics.register(new CNOD(model, mainmodule, filter))
49 metrics.register(new CDIT(model, mainmodule, filter))
50 metrics.register(new CNBP(model, mainmodule, filter))
51 metrics.register(new CNBA(model, mainmodule, filter))
52 metrics.register(new CNBI(model, mainmodule, filter))
53 metrics.register(new CNBM(model, mainmodule, filter))
54 metrics.register(new CNBV(model, mainmodule, filter))
55 metrics.register(new CNBIP(model, mainmodule, filter))
56 metrics.register(new CNBRP(model, mainmodule, filter))
57 metrics.register(new CNBHP(model, mainmodule, filter))
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 used to collect and filter entities
96 var model: Model
97
98 # Mainmodule for class linearization
99 var mainmodule: MModule
100
101 # Filter to apply
102 var filter: nullable ModelFilter
103 end
104
105 # Class Metric: Number of Ancestors
106 class CNOA
107 super MClassMetric
108 super IntMetric
109 redef fun name do return "cnoa"
110 redef fun desc do return "number of ancestor classes"
111
112 redef fun collect(mclasses) do
113 for mclass in mclasses do
114 values[mclass] = mclass.in_hierarchy(mainmodule).greaters.length - 1
115 end
116 end
117 end
118
119 # Class Metric: Number of Parents
120 class CNOP
121 super MClassMetric
122 super IntMetric
123 redef fun name do return "cnop"
124 redef fun desc do return "number of parent classes"
125
126 redef fun collect(mclasses) do
127 for mclass in mclasses do
128 values[mclass] = mclass.in_hierarchy(mainmodule).direct_greaters.length
129 end
130 end
131 end
132
133 # Class Metric: Number of Children
134 class CNOC
135 super MClassMetric
136 super IntMetric
137 redef fun name do return "cnoc"
138 redef fun desc do return "number of child classes"
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 redef fun collect(mclasses) do
155 for mclass in mclasses do
156 values[mclass] = mclass.in_hierarchy(mainmodule).smallers.length - 1
157 end
158 end
159 end
160
161 # Class Metric: Depth in Inheritance Tree
162 class CDIT
163 super MClassMetric
164 super IntMetric
165 redef fun name do return "cdit"
166 redef fun desc do return "depth in class tree"
167
168 redef fun collect(mclasses) do
169 for mclass in mclasses do
170 values[mclass] = mclass.in_hierarchy(mainmodule).depth
171 end
172 end
173 end
174
175 # Class Metric: Number of MProperties
176 class CNBP
177 super MClassMetric
178 super IntMetric
179 redef fun name do return "cnbp"
180 redef fun desc do return "number of accessible properties (inherited + local)"
181
182 redef fun collect(mclasses) do
183 for mclass in mclasses do
184 values[mclass] = mclass.collect_accessible_mproperties(mainmodule, filter).length
185 end
186 end
187 end
188
189 # Class Metric: Number of MAttributes
190 class CNBA
191 super MClassMetric
192 super IntMetric
193 redef fun name do return "cnba"
194 redef fun desc do return "number of accessible attributes (inherited + local)"
195
196 redef fun collect(mclasses) do
197 for mclass in mclasses do
198 values[mclass] = mclass.collect_accessible_mattributes(mainmodule, filter).length
199 end
200 end
201 end
202
203 # Class Metric: Number of MMethods
204 class CNBM
205 super MClassMetric
206 super IntMetric
207 redef fun name do return "cnbm"
208 redef fun desc do return "number of accessible methods (inherited + local)"
209
210 redef fun collect(mclasses) do
211 for mclass in mclasses do
212 values[mclass] = mclass.collect_accessible_mmethods(mainmodule, filter).length
213 end
214 end
215 end
216
217 # Class Metric: Number of Constructors
218 class CNBI
219 super MClassMetric
220 super IntMetric
221 redef fun name do return "cnbi"
222 redef fun desc do return "number of accessible constructors (inherited + local)"
223
224 redef fun collect(mclasses) do
225 for mclass in mclasses do
226 values[mclass] = mclass.collect_accessible_inits(mainmodule, filter).length
227 end
228 end
229 end
230
231 # Class Metric: Number of Virtual Types
232 class CNBV
233 super MClassMetric
234 super IntMetric
235 redef fun name do return "cnbv"
236 redef fun desc do return "number of accessible virtual types (inherited + local)"
237
238 redef fun collect(mclasses) do
239 for mclass in mclasses do
240 values[mclass] = mclass.collect_accessible_vts(mainmodule, filter).length
241 end
242 end
243 end
244
245 # Class Metric: Number of Introduced MProperties
246 class CNBIP
247 super MClassMetric
248 super IntMetric
249 redef fun name do return "cnbip"
250 redef fun desc do return "number of introduced properties"
251
252 redef fun collect(mclasses) do
253 for mclass in mclasses do
254 values[mclass] = mclass.collect_intro_mproperties(filter).length
255 end
256 end
257 end
258
259 # Class Metric: Number of Refined MProperties
260 class CNBRP
261 super MClassMetric
262 super IntMetric
263 redef fun name do return "cnbrp"
264 redef fun desc do return "number of redefined properties"
265
266 redef fun collect(mclasses) do
267 for mclass in mclasses do
268 values[mclass] = mclass.collect_redef_mproperties(filter).length
269 end
270 end
271 end
272
273 # Class Metric: Number of Inherited MProperties
274 class CNBHP
275 super MClassMetric
276 super IntMetric
277 redef fun name do return "cnbhp"
278 redef fun desc do return "number of inherited properties"
279
280 redef fun collect(mclasses) do
281 for mclass in mclasses do
282 values[mclass] = mclass.collect_inherited_mproperties(mainmodule, filter).length
283 end
284 end
285 end
286
287 # Class Metric: Number of Local MProperties (Intro + Redef)
288 class CNBLP
289 super MClassMetric
290 super IntMetric
291 redef fun name do return "cnblp"
292 redef fun desc do return "number of local properties (intro + redef)"
293
294 redef fun collect(mclasses) do
295 for mclass in mclasses do
296 values[mclass] = mclass.collect_local_mproperties(filter).length
297 end
298 end
299 end