stdlib/strings: Cleaned the old way of defining private attributes (readable var...
[nit.git] / src / metrics / metrics_base.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2012 Jean Privat <jean@pryen.org>
4 # Copyright 2014 Alexandre Terrasa <alexandre@moz-code.org>
5 #
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
9 #
10 # http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17
18 # Helpers for various statistics tools.
19 module metrics_base
20
21 import model_utils
22 import csv
23 import counter
24 import console
25
26 redef class ToolContext
27
28 # --all
29 var opt_all = new OptionBool("Compute all metrics", "--all")
30
31 # --mmodules
32 var opt_mmodules = new OptionBool("Compute metrics about mmodules", "--mmodules")
33 # --mclassses
34 var opt_mclasses = new OptionBool("Compute metrics about mclasses", "--mclasses")
35
36 # --inheritance
37 var opt_inheritance = new OptionBool("Compute metrics about inheritance usage", "--inheritance")
38 # --genericity
39 var opt_refinement = new OptionBool("Compute metrics about refinement usage", "--refinement")
40 # --self
41 var opt_self = new OptionBool("Compute metrics about the usage of explicit and implicit self", "--self")
42 # --ast
43 var opt_ast = new OptionBool("Compute metrics about the usage of nodes and identifiers in the AST", "--ast")
44 # --nullables
45 var opt_nullables = new OptionBool("Compute metrics on nullables send", "--nullables")
46 # --static-types
47 var opt_static_types = new OptionBool("Compute explicit static types metrics", "--static-types")
48 # --tables
49 var opt_tables = new OptionBool("Compute tables metrics", "--tables")
50 # --rta
51 var opt_rta = new OptionBool("Compute RTA metrics", "--rta")
52 # --generate-csv
53 var opt_generate_csv = new OptionBool("Generate CVS format metrics", "--generate-csv")
54 # --generate_hyperdoc
55 var opt_generate_hyperdoc = new OptionBool("Generate Hyperdoc", "--generate_hyperdoc")
56 # --poset
57 var opt_poset = new OptionBool("Complete metrics on posets", "--poset")
58
59 # --no-colors
60 var opt_nocolors = new OptionBool("Disable colors in console outputs", "--no-colors")
61
62
63 var opt_dir = new OptionString("Directory where some statistics files are generated", "-d", "--dir")
64 var output_dir: String = "."
65
66 redef init
67 do
68 super
69 self.option_context.add_option(opt_all)
70 self.option_context.add_option(opt_mmodules)
71 self.option_context.add_option(opt_mclasses)
72 self.option_context.add_option(opt_inheritance)
73 self.option_context.add_option(opt_refinement)
74 self.option_context.add_option(opt_self)
75 self.option_context.add_option(opt_ast)
76 self.option_context.add_option(opt_nullables)
77 self.option_context.add_option(opt_static_types)
78 self.option_context.add_option(opt_tables)
79 self.option_context.add_option(opt_rta)
80 self.option_context.add_option(opt_generate_csv)
81 self.option_context.add_option(opt_generate_hyperdoc)
82 self.option_context.add_option(opt_poset)
83 self.option_context.add_option(opt_dir)
84 self.option_context.add_option(opt_nocolors)
85 end
86
87 redef fun process_options
88 do
89 super
90 var val = self.opt_dir.value
91 if val != null then
92 val = val.simplify_path
93 val.mkdir
94 self.output_dir = val
95 end
96 end
97
98 # colorize heading 1 for console output
99 fun format_h1(str: String): String do
100 if opt_nocolors.value then return str
101 return str.yellow.bold
102 end
103
104 fun format_h2(str: String): String do
105 if opt_nocolors.value then return str
106 return str.bold
107 end
108
109 fun format_h3(str: String): String do
110 if opt_nocolors.value then return str
111 return str
112 end
113
114 fun format_h4(str: String): String do
115 if opt_nocolors.value then return str
116 return str.green
117 end
118
119 fun format_p(str: String): String do
120 if opt_nocolors.value then return str
121 return str.light_gray
122 end
123
124 end
125
126 redef class MClass
127 # is the class imported from standard lib?
128 fun is_standard: Bool do
129 return self.intro_mmodule.mgroup.mproject.name == "standard"
130 end
131 end
132
133 redef class MModule
134 # is the module imported from standard lib?
135 fun is_standard: Bool do
136 return self.mgroup.mproject.name == "standard"
137 end
138 end
139
140 # A Metric is used to collect data about things
141 #
142 # The concept is reified here for a better organization and documentation
143 interface Metric
144 fun name: String is abstract
145 fun desc: String is abstract
146 # clear all results for this metric
147 fun clear is abstract
148 end
149
150 # A Metric that collects integer data
151 #
152 # Used to count things
153 class IntMetric[E: Object]
154 super Metric
155
156 var values = new Counter[E]
157
158 redef fun clear do values.clear
159
160 # Return the couple with the highest value
161 fun max: Couple[E, Int] do
162 assert not values.is_empty
163 var elem = values.max.as(not null)
164 var value = values[elem]
165 return new Couple[E, Int](elem, value)
166 end
167
168 # Return the couple with the lowest value
169 fun min: Couple[E, Int] do
170 assert not values.is_empty
171 var elem = values.min.as(not null)
172 var value = values[elem]
173 return new Couple[E, Int](elem, value)
174 end
175
176 # Values average
177 fun avg: Float do return values.avg
178 end
179
180 # A Metric that collects float datas
181 #
182 # Used sor summarization
183 class FloatMetric[E: Object]
184 super Metric
185
186 var values: Map[E, Float] = new HashMap[E, Float]
187
188 redef fun clear do values.clear
189
190 # Return the couple with the highest value
191 fun max: Couple[E, Float] do
192 assert not values.is_empty
193 var max: nullable Float = null
194 var elem: nullable E = null
195 for e, v in values do
196 if max == null or v > max then
197 max = v
198 elem = e
199 end
200 end
201 return new Couple[E, Float](elem.as(not null), max.as(not null))
202 end
203
204 # Return the couple with the lowest value
205 fun min: Couple[E, Float] do
206 assert not values.is_empty
207 var min: nullable Float = null
208 var elem: nullable E = null
209 for e, v in values do
210 if min == null or v < min then
211 min = v
212 elem = e
213 end
214 end
215 return new Couple[E, Float](elem.as(not null), min.as(not null))
216 end
217
218 # Values average
219 fun avg: Float do
220 if values.is_empty then return 0.0
221 var sum = 0.0
222 for value in values.values do
223 sum += value
224 end
225 return sum / values.length.to_f
226 end
227 end
228
229 # A MetricSet is a metric holder
230 #
231 # It purpose is to be extended with a metric collect service
232 class MetricSet
233 type METRIC: Metric
234
235 # Metrics to compute
236 var metrics: Map[String, METRIC] = new HashMap[String, METRIC]
237
238 # Add a metric to the set
239 fun register(metrics: METRIC...) do for metric in metrics do self.metrics[metric.name] = metric
240
241 # Clear all results for all metrics
242 fun clear do for metric in metrics.values do metric.clear
243 end