1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2012 Jean Privat <jean@pryen.org>
4 # Copyright 2014 Alexandre Terrasa <alexandre@moz-code.org>
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
10 # http://www.apache.org/licenses/LICENSE-2.0
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.
18 # Helpers for various statistics tools.
25 redef class ToolContext
28 var opt_all
= new OptionBool("Compute all metrics", "--all")
31 var opt_mmodules
= new OptionBool("Compute metrics about mmodules", "--mmodules")
33 var opt_inheritance
= new OptionBool("Compute metrics about inheritance usage", "--inheritance")
35 var opt_refinement
= new OptionBool("Compute metrics about refinement usage", "--refinement")
37 var opt_self
= new OptionBool("Compute metrics about the usage of explicit and implicit self", "--self")
39 var opt_ast
= new OptionBool("Compute metrics about the usage of nodes and identifiers in the AST", "--ast")
41 var opt_nullables
= new OptionBool("Compute metrics on nullables send", "--nullables")
43 var opt_static_types
= new OptionBool("Compute explicit static types metrics", "--static-types")
45 var opt_tables
= new OptionBool("Compute tables metrics", "--tables")
47 var opt_rta
= new OptionBool("Compute RTA metrics", "--rta")
49 var opt_generate_csv
= new OptionBool("Generate CVS format metrics", "--generate-csv")
51 var opt_generate_hyperdoc
= new OptionBool("Generate Hyperdoc", "--generate_hyperdoc")
53 var opt_poset
= new OptionBool("Complete metrics on posets", "--poset")
55 var opt_dir
= new OptionString("Directory where some statistics files are generated", "-d", "--dir")
56 var output_dir
: String = "."
61 self.option_context
.add_option
(opt_all
)
62 self.option_context
.add_option
(opt_mmodules
)
63 self.option_context
.add_option
(opt_inheritance
)
64 self.option_context
.add_option
(opt_refinement
)
65 self.option_context
.add_option
(opt_self
)
66 self.option_context
.add_option
(opt_ast
)
67 self.option_context
.add_option
(opt_nullables
)
68 self.option_context
.add_option
(opt_static_types
)
69 self.option_context
.add_option
(opt_tables
)
70 self.option_context
.add_option
(opt_rta
)
71 self.option_context
.add_option
(opt_generate_csv
)
72 self.option_context
.add_option
(opt_generate_hyperdoc
)
73 self.option_context
.add_option
(opt_poset
)
74 self.option_context
.add_option
(opt_dir
)
77 redef fun process_options
80 var val
= self.opt_dir
.value
82 val
= val
.simplify_path
91 # List of modules in std lib
92 # FIXME this is quite ugly, find a dynamic way...
93 fun std_modules
: Set[String] do
94 if self.std_modules_cache
== null then
95 self.std_modules_cache
= new HashSet[String]
96 self.std_modules_cache
.add
("collection")
97 self.std_modules_cache
.add
("abstract_collection")
98 self.std_modules_cache
.add
("array")
99 self.std_modules_cache
.add
("hash_collection")
100 self.std_modules_cache
.add
("list")
101 self.std_modules_cache
.add
("range")
102 self.std_modules_cache
.add
("sorter")
103 self.std_modules_cache
.add
("environ")
104 self.std_modules_cache
.add
("exec")
105 self.std_modules_cache
.add
("file")
106 self.std_modules_cache
.add
("gc")
107 self.std_modules_cache
.add
("hash")
108 self.std_modules_cache
.add
("kernel")
109 self.std_modules_cache
.add
("math")
110 self.std_modules_cache
.add
("standard")
111 self.std_modules_cache
.add
("stream")
112 self.std_modules_cache
.add
("string")
113 self.std_modules_cache
.add
("string_search")
114 self.std_modules_cache
.add
("time")
116 return self.std_modules_cache
.as(not null)
118 private var std_modules_cache
: nullable Set[String]
122 fun is_user_defined
: Bool do
123 return self.intro_mmodule
.is_user_defined
128 fun is_user_defined
: Bool do
129 return not self.model
.std_modules
.has
(self.name
)
133 # A Metric is used to collect data about things
135 # The concept is reified here for a better organization and documentation
137 fun name
: String is abstract
138 fun desc
: String is abstract
139 # clear all results for this metric
140 fun clear
is abstract
143 # A Metric that collects integer data
145 # Used to count things
146 class IntMetric[E
: Object]
149 var values
= new Counter[E
]
151 redef fun clear
do values
.clear
153 # Return the couple with the highest value
154 fun max
: Couple[E
, Int] do
155 assert not values
.is_empty
156 var elem
= values
.max
.as(not null)
157 var value
= values
[elem
]
158 return new Couple[E
, Int](elem
, value
)
161 # Return the couple with the lowest value
162 fun min
: Couple[E
, Int] do
163 assert not values
.is_empty
164 var elem
= values
.min
.as(not null)
165 var value
= values
[elem
]
166 return new Couple[E
, Int](elem
, value
)
170 fun avg
: Float do return values
.avg
173 # A Metric that collects float datas
175 # Used sor summarization
176 class FloatMetric[E
: Object]
179 var values
: Map[E
, Float] = new HashMap[E
, Float]
181 redef fun clear
do values
.clear
183 # Return the couple with the highest value
184 fun max
: Couple[E
, Float] do
185 assert not values
.is_empty
186 var max
: nullable Float = null
187 var elem
: nullable E
= null
188 for e
, v
in values
do
189 if max
== null or v
> max
then
194 return new Couple[E
, Float](elem
.as(not null), max
.as(not null))
197 # Return the couple with the lowest value
198 fun min
: Couple[E
, Float] do
199 assert not values
.is_empty
200 var min
: nullable Float = null
201 var elem
: nullable E
= null
202 for e
, v
in values
do
203 if min
== null or v
< min
then
208 return new Couple[E
, Float](elem
.as(not null), min
.as(not null))
213 if values
.is_empty
then return 0.0
215 for value
in values
.values
do
218 return sum
/ values
.length
.to_f
222 # A MetricSet is a metric holder
224 # It purpose is to be extended with a metric collect service
229 var metrics
: Map[String, METRIC] = new HashMap[String, METRIC]
231 # Add a metric to the set
232 fun register
(metrics
: METRIC...) do for metric
in metrics
do self.metrics
[metric
.name
] = metric
234 # Clear all results for all metrics
235 fun clear
do for metric
in metrics
.values
do metric
.clear