Rename REAMDE to README.md
[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
22 redef class ToolContext
23 var mclasses_metrics_phase: Phase = new MClassesMetricsPhase(self, null)
24 end
25
26 # Extract metrics about mclasses from model.
27 private class MClassesMetricsPhase
28 super Phase
29 redef fun process_mainmodule(mainmodule, given_mmodules)
30 do
31 if not toolcontext.opt_mclasses.value and not toolcontext.opt_all.value then return
32 var csv = toolcontext.opt_csv.value
33 var out = "{toolcontext.opt_dir.value or else "metrics"}/mclasses"
34 out.mkdir
35
36
37 print toolcontext.format_h1("\n# MClasses metrics")
38
39 var metrics = new MetricSet
40 var min_vis = private_visibility
41 metrics.register(new CNOA(mainmodule))
42 metrics.register(new CNOP(mainmodule))
43 metrics.register(new CNOC(mainmodule))
44 metrics.register(new CNOD(mainmodule))
45 metrics.register(new CDIT(mainmodule))
46 metrics.register(new CNBP(mainmodule, min_vis))
47 metrics.register(new CNBA(mainmodule, min_vis))
48 metrics.register(new CNBIP(mainmodule, min_vis))
49 metrics.register(new CNBRP(mainmodule, min_vis))
50 metrics.register(new CNBHP(mainmodule, min_vis))
51 #TODO metrics.register(new CNBI) # nb init
52 #TODO metrics.register(new CNBM) # nb methods
53 #TODO metrics.register(new CNBV) # nb vtypes
54
55 var model = toolcontext.modelbuilder.model
56 var mclasses = new HashSet[MClass]
57 for mproject in model.mprojects do
58
59 print toolcontext.format_h2("\n ## project {mproject}")
60
61 for mgroup in mproject.mgroups do
62 if mgroup.mmodules.is_empty then continue
63 metrics.clear
64
65 # Scalar metrics
66 print toolcontext.format_h3(" `- group {mgroup.full_name}")
67 var mod_mclasses = new HashSet[MClass]
68 for mmodule in mgroup.mmodules do mod_mclasses.add_all(mmodule.intro_mclasses)
69 if mod_mclasses.is_empty then continue
70 mclasses.add_all(mod_mclasses)
71 metrics.collect(new HashSet[MClass].from(mod_mclasses))
72 metrics.to_console(1, not toolcontext.opt_nocolors.value)
73 if csv then metrics.to_csv.save("{out}/{mgroup}.csv")
74 end
75 end
76 if not mclasses.is_empty then
77 metrics.clear
78 # Global metrics
79 print toolcontext.format_h2("\n ## global metrics")
80 metrics.collect(mclasses)
81 metrics.to_console(1, not toolcontext.opt_nocolors.value)
82 if csv then metrics.to_csv.save("{out}/summary.csv")
83 end
84 end
85 end
86
87 # A metric about MClass
88 interface MClassMetric
89 super Metric
90 redef type ELM: MClass
91 end
92
93 # Class Metric: Number of Ancestors
94 class CNOA
95 super MClassMetric
96 super IntMetric
97 redef fun name do return "cnoa"
98 redef fun desc do return "number of ancestor classes"
99
100 var mainmodule: MModule
101 init(mainmodule: MModule) do self.mainmodule = mainmodule
102
103 redef fun collect(mclasses) do
104 for mclass in mclasses do
105 values[mclass] = mclass.in_hierarchy(mainmodule).greaters.length - 1
106 end
107 end
108 end
109
110 # Class Metric: Number of Parents
111 class CNOP
112 super MClassMetric
113 super IntMetric
114 redef fun name do return "cnop"
115 redef fun desc do return "number of parent classes"
116
117 var mainmodule: MModule
118 init(mainmodule: MModule) do self.mainmodule = mainmodule
119
120 redef fun collect(mclasses) do
121 for mclass in mclasses do
122 values[mclass] = mclass.in_hierarchy(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 var mainmodule: MModule
135 init(mainmodule: MModule) do self.mainmodule = mainmodule
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 var mainmodule: MModule
152 init(mainmodule: MModule) do self.mainmodule = mainmodule
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 var mainmodule: MModule
169 init(mainmodule: MModule) do self.mainmodule = mainmodule
170
171 redef fun collect(mclasses) do
172 for mclass in mclasses do
173 values[mclass] = mclass.in_hierarchy(mainmodule).depth
174 end
175 end
176 end
177
178 # Class Metric: Number of MProperties
179 class CNBP
180 super MClassMetric
181 super IntMetric
182 redef fun name do return "cnbp"
183 redef fun desc do return "number of accessible properties (inherited + local)"
184
185 var mainmodule: MModule
186 var min_visibility: MVisibility
187
188 init(mainmodule: MModule, min_visibility: MVisibility) do
189 self.mainmodule = mainmodule
190 self.min_visibility = min_visibility
191 end
192
193 redef fun collect(mclasses) do
194 for mclass in mclasses do
195 values[mclass] = mclass.all_mproperties(mainmodule, min_visibility).length
196 end
197 end
198 end
199
200 # Class Metric: Number of MAttributes
201 class CNBA
202 super MClassMetric
203 super IntMetric
204 redef fun name do return "cnba"
205 redef fun desc do return "number of accessible attributes (inherited + local)"
206
207 var mainmodule: MModule
208 var min_visibility: MVisibility
209
210 init(mainmodule: MModule, min_visibility: MVisibility) do
211 self.mainmodule = mainmodule
212 self.min_visibility = min_visibility
213 end
214
215 redef fun collect(mclasses) do
216 for mclass in mclasses do
217 values[mclass] = mclass.all_mattributes(mainmodule, min_visibility).length
218 end
219 end
220 end
221
222 # Class Metric: Number of Introduced MProperties
223 class CNBIP
224 super MClassMetric
225 super IntMetric
226 redef fun name do return "cnbip"
227 redef fun desc do return "number of introduced properties"
228
229 var mainmodule: MModule
230 var min_visibility: MVisibility
231
232 init(mainmodule: MModule, min_visibility: MVisibility) do
233 self.mainmodule = mainmodule
234 self.min_visibility = min_visibility
235 end
236
237 redef fun collect(mclasses) do
238 for mclass in mclasses do
239 values[mclass] = mclass.intro_mproperties(min_visibility).length
240 end
241 end
242 end
243
244 # Class Metric: Number of Refined MProperties
245 class CNBRP
246 super MClassMetric
247 super IntMetric
248 redef fun name do return "cnbrp"
249 redef fun desc do return "number of redefined properties"
250
251 var mainmodule: MModule
252 var min_visibility: MVisibility
253
254 init(mainmodule: MModule, min_visibility: MVisibility) do
255 self.mainmodule = mainmodule
256 self.min_visibility = min_visibility
257 end
258
259 redef fun collect(mclasses) do
260 for mclass in mclasses do
261 values[mclass] = mclass.redef_mproperties(min_visibility).length
262 end
263 end
264 end
265
266 # Class Metric: Number of Inherited MProperties
267 class CNBHP
268 super MClassMetric
269 super IntMetric
270 redef fun name do return "cnbhp"
271 redef fun desc do return "number of inherited properties"
272
273 var mainmodule: MModule
274 var min_visibility: MVisibility
275
276 init(mainmodule: MModule, min_visibility: MVisibility) do
277 self.mainmodule = mainmodule
278 self.min_visibility = min_visibility
279 end
280
281 redef fun collect(mclasses) do
282 for mclass in mclasses do
283 values[mclass] = mclass.inherited_mproperties(mainmodule, min_visibility).length
284 end
285 end
286 end
287
288 # Class Metric: Number of Local MProperties (Intro + Redef)
289 class CNBLP
290 super MClassMetric
291 super IntMetric
292 redef fun name do return "cnblp"
293 redef fun desc do return "number of local properties (intro + redef)"
294
295 var mainmodule: MModule
296 var min_visibility: MVisibility
297
298 init(mainmodule: MModule, min_visibility: MVisibility) do
299 self.mainmodule = mainmodule
300 self.min_visibility = min_visibility
301 end
302
303 redef fun collect(mclasses) do
304 for mclass in mclasses do
305 values[mclass] = mclass.local_mproperties(min_visibility).length
306 end
307 end
308 end