src: Updated uses of CSV library
[nit.git] / src / metrics / mmodules_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 modules
18 module mmodules_metrics
19
20 import metrics_base
21
22 redef class ToolContext
23 var mmodules_metrics_phase: Phase = new MModulesMetricsPhase(self, null)
24 end
25
26 # Extract metrics about modules from the model.
27 private class MModulesMetricsPhase
28 super Phase
29 redef fun process_mainmodule(mainmodule, given_mmodules)
30 do
31 if not toolcontext.opt_mmodules.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"}/mmodules"
34 out.mkdir
35
36 print toolcontext.format_h1("\n# MModules metrics")
37
38 var metrics = new MetricSet
39 metrics.register(new MNOA, new MNOP, new MNOC, new MNOD, new MDIT)
40 metrics.register(new MNBI, new MNBR, new MNBCC, new MNBAC, new MNBIC)
41
42 var model = toolcontext.modelbuilder.model
43 var mmodules = new HashSet[MModule]
44 for mpackage in model.mpackages do
45
46 print toolcontext.format_h2("\n ## package {mpackage}")
47 for mgroup in mpackage.mgroups do
48 if mgroup.mmodules.is_empty then continue
49
50 # Scalar metrics
51 print toolcontext.format_h3(" `- group {mgroup.full_name}")
52 mmodules.add_all(mgroup.mmodules)
53 metrics.clear
54 metrics.collect(new HashSet[MModule].from(mgroup.mmodules))
55 metrics.to_console(1, not toolcontext.opt_nocolors.value)
56 if csv then metrics.to_csv.write_to_file("{out}/{mgroup}.csv")
57 end
58 end
59 if not mmodules.is_empty then
60 # Global metrics
61 print toolcontext.format_h2("\n ## global metrics")
62 metrics.clear
63 metrics.collect(mmodules)
64 metrics.to_console(1, not toolcontext.opt_nocolors.value)
65 if csv then metrics.to_csv.write_to_file("{out}/summary.csv")
66 end
67 end
68 end
69
70 # A metric about MModule
71 interface MModuleMetric
72 super Metric
73 redef type ELM: MModule
74 end
75
76 # Module Metric: Number of Ancestors
77 class MNOA
78 super MModuleMetric
79 super IntMetric
80 redef fun name do return "mnoa"
81 redef fun desc do return "number of ancestor modules"
82
83 redef fun collect(mmodules) do
84 for mmodule in mmodules do
85 values[mmodule] = mmodule.in_importation.greaters.length - 1
86 end
87 end
88 end
89
90 # Module Metric: Number of Parents
91 class MNOP
92 super MModuleMetric
93 super IntMetric
94 redef fun name do return "mnop"
95 redef fun desc do return "number of parent modules"
96
97 redef fun collect(mmodules) do
98 for mmodule in mmodules do
99 values[mmodule] = mmodule.in_importation.direct_greaters.length
100 end
101 end
102 end
103
104 # Module Metric: Number of Children
105 class MNOC
106 super MModuleMetric
107 super IntMetric
108 redef fun name do return "mnoc"
109 redef fun desc do return "number of child modules"
110
111 redef fun collect(mmodules) do
112 for mmodule in mmodules do
113 values[mmodule] = mmodule.in_importation.direct_smallers.length
114 end
115 end
116 end
117
118 # Module Metric: Number of Descendants
119 class MNOD
120 super MModuleMetric
121 super IntMetric
122 redef fun name do return "mnod"
123 redef fun desc do return "number of descendant modules"
124
125 redef fun collect(mmodules) do
126 for mmodule in mmodules do
127 values[mmodule] = mmodule.in_importation.smallers.length - 1
128 end
129 end
130 end
131
132 # Module Metric: Depth in Tree
133 class MDIT
134 super MModuleMetric
135 super IntMetric
136 redef fun name do return "mdit"
137 redef fun desc do return "depth in module tree"
138
139 redef fun collect(mmodules) do
140 for mmodule in mmodules do
141 values[mmodule] = mmodule.in_importation.depth
142 end
143 end
144 end
145
146 # Module Metric: Number of Introduction (of all kind)
147 #
148 # count all mclasses introduced by the module
149 class MNBI
150 super MModuleMetric
151 super IntMetric
152 redef fun name do return "mnbi"
153 redef fun desc do return "number of introduction in module"
154
155 redef fun collect(mmodules) do
156 for mmodule in mmodules do
157 values[mmodule] = mmodule.intro_mclasses.length
158 end
159 end
160 end
161
162 # Module Metric: Number of Refinement
163 #
164 # count all mclasses refined in the module
165 class MNBR
166 super MModuleMetric
167 super IntMetric
168 redef fun name do return "mnbr"
169 redef fun desc do return "number of refinement in module"
170
171 redef fun collect(mmodules) do
172 for mmodule in mmodules do
173 var value = 0
174 for mclassdef in mmodule.mclassdefs do
175 if not mclassdef.is_intro then value += 1
176 end
177 values[mmodule] = value
178 end
179 end
180 end
181
182 # Module Metric: Number of Concrete Class in module (intro + redef)
183 class MNBCC
184 super MModuleMetric
185 super IntMetric
186 redef fun name do return "mnbcc"
187 redef fun desc do return "number of concrete class in module (intro + redef)"
188
189 redef fun collect(mmodules) do
190 for mmodule in mmodules do
191 var value = 0
192 for mclassdef in mmodule.mclassdefs do
193 if mclassdef.mclass.kind == concrete_kind then value += 1
194 end
195 values[mmodule] = value
196 end
197 end
198 end
199
200 # Module Metric: Number of Abstract Class in module (intro + redef)
201 class MNBAC
202 super MModuleMetric
203 super IntMetric
204 redef fun name do return "mnbac"
205 redef fun desc do return "number of abstract class in module (intro + redef)"
206
207 redef fun collect(mmodules) do
208 for mmodule in mmodules do
209 var value = 0
210 for mclassdef in mmodule.mclassdefs do
211 if mclassdef.mclass.kind == abstract_kind then value += 1
212 end
213 values[mmodule] = value
214 end
215 end
216 end
217
218 # Module Metric: Number of Interface in module (intro + redef)
219 class MNBIC
220 super MModuleMetric
221 super IntMetric
222 redef fun name do return "mnbic"
223 redef fun desc do return "number of interface in module (intro + redef)"
224
225 redef fun collect(mmodules) do
226 for mmodule in mmodules do
227 var value = 0
228 for mclassdef in mmodule.mclassdefs do
229 if mclassdef.mclass.kind == interface_kind then value += 1
230 end
231 values[mmodule] = value
232 end
233 end
234 end
235
236 # Module Metric: Number of Enum in module (intro + redef)
237 class MNBEC
238 super MModuleMetric
239 super IntMetric
240 redef fun name do return "mnbec"
241 redef fun desc do return "number of enum in module (intro + redef)"
242
243 redef fun collect(mmodules) do
244 for mmodule in mmodules do
245 var value = 0
246 for mclassdef in mmodule.mclassdefs do
247 if mclassdef.mclass.kind == enum_kind then value += 1
248 end
249 values[mmodule] = value
250 end
251 end
252 end
253
254