module metrics_base
import model_utils
+import modelbuilder
import csv
import counter
import console
var opt_mmodules = new OptionBool("Compute metrics about mmodules", "--mmodules")
# --mclassses
var opt_mclasses = new OptionBool("Compute metrics about mclasses", "--mclasses")
-
+ # --mendel
+ var opt_mendel = new OptionBool("Compute mendel metrics", "--mendel")
# --inheritance
var opt_inheritance = new OptionBool("Compute metrics about inheritance usage", "--inheritance")
# --genericity
# --rta
var opt_rta = new OptionBool("Compute RTA metrics", "--rta")
# --generate-csv
- var opt_generate_csv = new OptionBool("Generate CVS format metrics", "--generate-csv")
+ var opt_csv = new OptionBool("Export metrics in CSV format", "--csv")
# --generate_hyperdoc
var opt_generate_hyperdoc = new OptionBool("Generate Hyperdoc", "--generate_hyperdoc")
# --poset
self.option_context.add_option(opt_all)
self.option_context.add_option(opt_mmodules)
self.option_context.add_option(opt_mclasses)
+ self.option_context.add_option(opt_mendel)
self.option_context.add_option(opt_inheritance)
self.option_context.add_option(opt_refinement)
self.option_context.add_option(opt_self)
self.option_context.add_option(opt_static_types)
self.option_context.add_option(opt_tables)
self.option_context.add_option(opt_rta)
- self.option_context.add_option(opt_generate_csv)
+ self.option_context.add_option(opt_csv)
self.option_context.add_option(opt_generate_hyperdoc)
self.option_context.add_option(opt_poset)
self.option_context.add_option(opt_dir)
self.option_context.add_option(opt_nocolors)
end
- redef fun process_options
+ redef fun process_options(args)
do
super
var val = self.opt_dir.value
# Pretty print the metric results in console
fun to_console(indent: Int, colors: Bool) do
+ if values.is_empty then
+ if colors then
+ print "{"\t" * indent}{name}: {desc} -- nothing".green
+ else
+ print "{"\t" * indent}{name}: {desc} -- nothing"
+ end
+ return
+ end
+
var max = self.max
var min = self.min
if colors then
# The values standard derivation
fun std_dev: Float is abstract
+
+ # The element with the highest value
+ fun max: ELM is abstract
+
+ # The element with the lowest value
+ fun min: ELM is abstract
+
+ # The value threshold above what elements are considered as 'interesting'
+ fun threshold: Float do return avg + std_dev
+
+ # The set of element above the threshold
+ fun above_threshold: Set[ELM] is abstract
end
# A Metric that collects integer data
redef fun clear do values_cache.clear
- # Return the couple with the highest value
- fun max: Couple[ELM, Int] do
+ fun sum: Int do return values_cache.sum
+
+ redef fun max do
assert not values_cache.is_empty
- var elem = values_cache.max.as(not null)
- var value = values_cache[elem]
- return new Couple[ELM, Int](elem, value)
+ return values_cache.max.as(not null)
end
- # Return the couple with the lowest value
- fun min: Couple[ELM, Int] do
+ redef fun min do
assert not values_cache.is_empty
- var elem = values_cache.min.as(not null)
- var value = values_cache[elem]
- return new Couple[ELM, Int](elem, value)
+ return values_cache.min.as(not null)
end
# Values average
redef fun avg: Float do return values_cache.avg
redef fun std_dev: Float do return values_cache.std_dev
+
+ redef fun above_threshold do
+ var above = new HashSet[ELM]
+ var threshold = threshold
+ for element, value in values do
+ if value.to_f > threshold then above.add(element)
+ end
+ return above
+ end
+
+ redef fun to_console(indent, colors) do
+ super
+ if colors then
+ print "{"\t" * indent} sum: {sum}".light_gray
+ else
+ print "{"\t" * indent} sum: {sum}"
+ end
+ end
end
# A Metric that collects float datas
redef fun clear do values_cache.clear
- # Return the couple with the highest value
- fun max: Couple[ELM, Float] do
+ fun sum: Float do
+ var sum = 0.0
+ for v in values.values do sum += v
+ return sum
+ end
+
+ redef fun max do
assert not values.is_empty
var max: nullable Float = null
var elem: nullable ELM = null
elem = e
end
end
- return new Couple[ELM, Float](elem.as(not null), max.as(not null))
+ return elem.as(not null)
end
- # Return the couple with the lowest value
- fun min: Couple[ELM, Float] do
+ redef fun min do
assert not values.is_empty
var min: nullable Float = null
var elem: nullable ELM = null
elem = e
end
end
- return new Couple[ELM, Float](elem.as(not null), min.as(not null))
+ return elem.as(not null)
end
redef fun avg do
if values.is_empty then return 0.0
- var sum = 0.0
- for value in values.values do
- sum += value
- end
return sum / values.length.to_f
end
end
return (sum / values.length.to_f).sqrt
end
+
+ redef fun above_threshold do
+ var above = new HashSet[ELM]
+ var threshold = threshold
+ for element, value in values do
+ if value > threshold then above.add(element)
+ end
+ return above
+ end
+
+ redef fun to_console(indent, colors) do
+ super
+ if colors then
+ print "{"\t" * indent} sum: {sum}".light_gray
+ else
+ print "{"\t" * indent} sum: {sum}"
+ end
+ end
+
end
# A MetricSet is a metric holder
for metric in metrics do metric.to_console(indent, colors)
end
+ # Export the metric set in CSV format
+ fun to_csv: CsvDocument do
+ var csv = new CsvDocument
+
+ csv.format = new CsvFormat('"', ';', "\n")
+
+ # set csv headers
+ csv.header.add("entry")
+ for metric in metrics do csv.header.add(metric.name)
+
+ # collect all entries to merge metric results
+ var entries = new HashSet[ELM]
+ for metric in metrics do
+ for entry in metric.values.keys do entries.add(entry)
+ end
+
+ # collect results
+ for entry in entries do
+ var line = [entry.to_s]
+ for metric in metrics do
+ if metric.has_element(entry) then
+ line.add(metric[entry].to_s)
+ else
+ line.add("n/a")
+ end
+ end
+ csv.records.add(line)
+ end
+ return csv
+ end
end