module metrics_base
import modelbuilder
+import csv
+import counter
redef class ToolContext
+ # --all
+ var opt_all = new OptionBool("Compute all metrics", "--all")
+
+ # --inheritance
+ var opt_inheritance = new OptionBool("Compute metrics about inheritance usage", "--inheritance")
+ # --genericity
+ var opt_refinement = new OptionBool("Compute metrics about refinement usage", "--refinement")
+ # --self
+ var opt_self = new OptionBool("Compute metrics about the usage of explicit and implicit self", "--self")
+ # --nullables
+ var opt_nullables = new OptionBool("Compute metrics on nullables send", "--nullables")
+ # --static-types
+ var opt_static_types = new OptionBool("Compute explicit static types metrics", "--static-types")
+ # --tables
+ var opt_tables = new OptionBool("Compute tables metrics", "--tables")
+ # --rta
+ var opt_rta = new OptionBool("Compute RTA metrics", "--rta")
+ # --generate-csv
+ var opt_generate_csv = new OptionBool("Generate CVS format metrics", "--generate-csv")
# --generate_hyperdoc
var opt_generate_hyperdoc = new OptionBool("Generate Hyperdoc", "--generate_hyperdoc")
redef init
do
super
+ self.option_context.add_option(opt_all)
+ 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_nullables)
+ 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_generate_hyperdoc)
self.option_context.add_option(opt_dir)
end
end
end
-# A counter counts occurence of things
-# Use this instead of a HashMap[E, Int]
-class Counter[E: Object]
- # Total number of counted occurences
- var total: Int = 0
+redef class Model
- private var map = new HashMap[E, Int]
+ # List of modules in std lib
+ # FIXME this is quite ugly, find a dynamic way...
+ fun std_modules: Set[String] do
+ if self.std_modules_cache == null then
+ self.std_modules_cache = new HashSet[String]
+ self.std_modules_cache.add("collection")
+ self.std_modules_cache.add("abstract_collection")
+ self.std_modules_cache.add("array")
+ self.std_modules_cache.add("hash_collection")
+ self.std_modules_cache.add("list")
+ self.std_modules_cache.add("range")
+ self.std_modules_cache.add("sorter")
+ self.std_modules_cache.add("environ")
+ self.std_modules_cache.add("exec")
+ self.std_modules_cache.add("file")
+ self.std_modules_cache.add("gc")
+ self.std_modules_cache.add("hash")
+ self.std_modules_cache.add("kernel")
+ self.std_modules_cache.add("math")
+ self.std_modules_cache.add("standard")
+ self.std_modules_cache.add("stream")
+ self.std_modules_cache.add("string")
+ self.std_modules_cache.add("string_search")
+ self.std_modules_cache.add("time")
+ end
+ return self.std_modules_cache.as(not null)
+ end
+ private var std_modules_cache: nullable Set[String]
+end
- # The number of counted occurences of `e'
- fun [](e: E): Int
- do
- var map = self.map
- if map.has_key(e) then return map[e]
- return 0
+redef class MClass
+ fun is_class: Bool do
+ return self.kind == concrete_kind or self.kind == abstract_kind
end
- # Count one more occurence of `e'
- fun inc(e: E)
- do
- self.map[e] = self[e] + 1
- total += 1
+ fun is_interface: Bool do
+ return self.kind == interface_kind
end
- # Return an array of elements sorted by occurences
- fun sort: Array[E]
- do
- var res = map.keys.to_a
- var sorter = new CounterSorter[E](self)
- sorter.sort(res)
- #res.sort !cmp a, b = map[a] <=> map[b]
- return res
+ fun is_enum: Bool do
+ return self.kind == enum_kind
+ end
+
+ fun is_abstract: Bool do
+ return self.kind == abstract_kind
end
-end
-private class CounterSorter[E: Object]
- super AbstractSorter[E]
- var counter: Counter[E]
- redef fun compare(a,b) do return self.counter.map[a] <=> self.counter.map[b]
+ fun is_user_defined: Bool do
+ return self.intro_mmodule.is_user_defined
+ end
end
-# Helper function to display n/d and handle division by 0
-fun div(n: Int, d: Int): String
-do
- if d == 0 then return "na"
- return ((100*n/d).to_f/100.0).to_precision(2)
+redef class MModule
+ fun is_user_defined: Bool do
+ return not self.model.std_modules.has(self.name)
+ end
end