modelbuilder: add parameter `given_mmodules` to `Phase::process_mainmodule`
[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 model
21 import metrics_base
22 import phase
23 import frontend
24
25 redef class ToolContext
26 var mclasses_metrics_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
40 print toolcontext.format_h1("\n# MClasses metrics")
41
42 var metrics = new MetricSet
43 var min_vis = private_visibility
44 metrics.register(new CNOA(mainmodule))
45 metrics.register(new CNOP(mainmodule))
46 metrics.register(new CNOC(mainmodule))
47 metrics.register(new CNOD(mainmodule))
48 metrics.register(new CDIT(mainmodule))
49 metrics.register(new CNBIP(mainmodule, min_vis))
50 metrics.register(new CNBRP(mainmodule, min_vis))
51 metrics.register(new CNBHP(mainmodule, min_vis))
52 #TODO metrics.register(new CNBI) # nb init
53 #TODO metrics.register(new CNBA) # nb attrs
54 #TODO metrics.register(new CNBM) # nb methods
55 #TODO metrics.register(new CNBV) # nb vtypes
56
57 var model = toolcontext.modelbuilder.model
58 var mclasses = new HashSet[MClass]
59 for mproject in model.mprojects do
60
61 print toolcontext.format_h2("\n ## project {mproject}")
62
63 for mgroup in mproject.mgroups do
64 if mgroup.mmodules.is_empty then continue
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.save("{out}/{mgroup}.csv")
75 end
76 end
77 if not mclasses.is_empty then
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 Introduced MProperties
179 class CNBIP
180 super MClassMetric
181 super IntMetric
182 redef fun name do return "cnbip"
183 redef fun desc do return "number of introduced properties"
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.intro_mproperties(min_visibility).length
196 end
197 end
198 end
199
200 # Class Metric: Number of Refined MProperties
201 class CNBRP
202 super MClassMetric
203 super IntMetric
204 redef fun name do return "cnbrp"
205 redef fun desc do return "number of redefined properties"
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.redef_mproperties(min_visibility).length
218 end
219 end
220 end
221
222 # Class Metric: Number of Inherited MProperties
223 class CNBHP
224 super MClassMetric
225 super IntMetric
226 redef fun name do return "cnbhp"
227 redef fun desc do return "number of inherited 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.inherited_mproperties(mainmodule, min_visibility).length
240 end
241 end
242 end
243
244 # Class Metric: Number of Local MProperties (Intro + Redef)
245 class CNBLP
246 super MClassMetric
247 super IntMetric
248 redef fun name do return "cnblp"
249 redef fun desc do return "number of local properties (intro + redef)"
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.local_mproperties(min_visibility).length
262 end
263 end
264 end