metrics: add Counter#print_summary
[nit.git] / src / metrics / metrics_base.nit
index 950b956..c7e381b 100644 (file)
 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")
 
@@ -32,7 +51,15 @@ redef class ToolContext
        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
@@ -49,49 +76,62 @@ redef class ToolContext
        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