Merge: Hint vararg
authorJean Privat <jean@pryen.org>
Fri, 24 Apr 2015 06:02:47 +0000 (13:02 +0700)
committerJean Privat <jean@pryen.org>
Fri, 24 Apr 2015 06:02:47 +0000 (13:02 +0700)
Improve the error message so that user that try to pass an array as is instead of elements is hinted about the `...` reverse-vararg operator.

~~~
fun foo(xs: Int...) do end
foo(1,2,3) # OK
var a = [1,2,3]
foo(a) # Error, expected `Int`; got `Array[Int]`. Is `...` missing?
foo(a...) # OK
~~~

![](http://i.imgur.com/zmyi8GR.jpg)

close #98 (quite old bug)

Pull-Request: #1294
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>

lib/standard/collection/sorter.nit
src/metrics/mendel_metrics.nit
src/metrics/metrics_base.nit
src/modelbuilder.nit
src/modelize/modelize_class.nit
tests/sav/nitmetrics_args1.res

index 00c45a3..ca16460 100644 (file)
@@ -334,5 +334,25 @@ class DefaultComparator
        redef fun compare(a, b) do return a <=> b
 end
 
+# This comparator uses the operator `<=>` to compare objects in a reverse order.
+#
+# See `default_reverse_comparator` for an easy-to-use general stateless reverse
+# default comparator.
+class DefaultReverseComparator
+       super Comparator
+
+       redef type COMPARED: Comparable
+
+       # Returns `b <=> a`.
+       redef fun compare(a, b) do return b <=> a
+end
+
 # Easy-to-use general stateless default comparator that uses `<=>` to compare things.
 fun default_comparator: DefaultComparator do return once new DefaultComparator
+
+# Easy-to-use general stateless default reverse comparator.
+#
+# Does the same as `default_comparator` but in reverse order.
+fun default_reverse_comparator: DefaultReverseComparator do
+       return once new DefaultReverseComparator
+end
index 1ee1db2..3209720 100644 (file)
@@ -48,6 +48,9 @@ import mclasses_metrics
 import modelize
 
 redef class ToolContext
+       # Compute MENDEL metrics.
+       #
+       # See `mendel_metrics` module documentation.
        var mendel_metrics_phase: Phase = new MendelMetricsPhase(self, null)
 end
 
@@ -81,24 +84,28 @@ private class MendelMetricsPhase
                metrics.collect(mclasses)
                if csv then metrics.to_csv.save("{out}/mendel.csv")
 
-               print toolcontext.format_h4("\tlarge mclasses (threshold: {cnblp.threshold})")
-               for mclass in cnblp.above_threshold do
-                       print toolcontext.format_p("\t   {mclass.name}: {cnblp.values[mclass]}")
+               var threshold = cnblp.threshold
+               print toolcontext.format_h4("\tlarge mclasses (threshold: {threshold})")
+               for mclass in cnblp.sort do
+                       var val = cnblp.values[mclass]
+                       if val.to_f < threshold then break
+                       print toolcontext.format_p("\t   {mclass.name}: {val}")
                end
 
-               print toolcontext.format_h4("\tbudding mclasses (threshold: {cnvi.threshold})")
-               for mclass in cnvi.above_threshold do
-                       print toolcontext.format_p("\t   {mclass.name}: {cnvi.values[mclass]}")
+               threshold = cnvi.threshold
+               print toolcontext.format_h4("\tbudding mclasses (threshold: {threshold})")
+               for mclass in cnvi.sort do
+                       var val = cnvi.values[mclass]
+                       if val.to_f < threshold then break
+                       print toolcontext.format_p("\t   {mclass.name}: {val}")
                end
 
-               print toolcontext.format_h4("\tblooming mclasses (threshold: {cnvs.threshold})")
-               for mclass in cnvs.above_threshold do
-                       print toolcontext.format_p("\t   {mclass.name}: {cnvs.values[mclass]}")
-               end
-
-               print toolcontext.format_h4("\tblooming mclasses (threshold: {cnvs.threshold})")
-               for mclass in cnvs.above_threshold do
-                       print toolcontext.format_p("\t   {mclass.name}: {cnvs.values[mclass]}")
+               threshold = cnvs.threshold
+               print toolcontext.format_h4("\tblooming mclasses (threshold: {threshold})")
+               for mclass in cnvs.sort do
+                       var val = cnvs.values[mclass]
+                       if val.to_f < threshold then break
+                       print toolcontext.format_p("\t   {mclass.name}: {val}")
                end
 
                if csv then
@@ -130,8 +137,8 @@ class CBMS
        redef fun name do return "cbms"
        redef fun desc do return "branch mean size, mean number of introduction available among ancestors"
 
+       # Mainmodule used to compute class hierarchy.
        var mainmodule: MModule
-       init(mainmodule: MModule) do self.mainmodule = mainmodule
 
        redef fun collect(mclasses) do
                for mclass in mclasses do
@@ -150,8 +157,8 @@ class CNVI
        redef fun name do return "cnvi"
        redef fun desc do return "class novelty index, contribution of the class to its branch in term of introductions"
 
+       # Mainmodule used to compute class hierarchy.
        var mainmodule: MModule
-       init(mainmodule: MModule) do self.mainmodule = mainmodule
 
        redef fun collect(mclasses) do
                var cbms = new CBMS(mainmodule)
@@ -179,8 +186,8 @@ class CNVS
        redef fun name do return "cnvs"
        redef fun desc do return "class novelty score, importance of the contribution of the class to its branch"
 
+       # Mainmodule used to compute class hierarchy.
        var mainmodule: MModule
-       init(mainmodule: MModule) do self.mainmodule = mainmodule
 
        redef fun collect(mclasses) do
                var cnvi = new CNVI(mainmodule)
index c51e656..a7ded94 100644 (file)
@@ -57,12 +57,12 @@ redef class ToolContext
        var opt_generate_hyperdoc = new OptionBool("Generate Hyperdoc", "--generate_hyperdoc")
        # --poset
        var opt_poset = new OptionBool("Complete metrics on posets", "--poset")
-
        # --no-colors
        var opt_nocolors = new OptionBool("Disable colors in console outputs", "--no-colors")
-
-
+       # --dir
        var opt_dir = new OptionString("Directory where some statistics files are generated", "-d", "--dir")
+
+       # Output directory for metrics files.
        var output_dir: String = "."
 
        redef init
@@ -98,27 +98,41 @@ redef class ToolContext
                end
        end
 
-       # colorize heading 1 for console output
+       # Format and colorize a string heading of level 1 for console output.
+       #
+       # Default style is yellow and bold.
        fun format_h1(str: String): String do
                if opt_nocolors.value then return str
                return str.yellow.bold
        end
 
+       # Format and colorize a string heading of level 2 for console output.
+       #
+       # Default style is white and bold.
        fun format_h2(str: String): String do
                if opt_nocolors.value then return str
                return str.bold
        end
 
+       # Format and colorize a string heading of level 3 for console output.
+       #
+       # Default style is white and nobold.
        fun format_h3(str: String): String do
                if opt_nocolors.value then return str
                return str
        end
 
+       # Format and colorize a string heading of level 4 for console output.
+       #
+       # Default style is green.
        fun format_h4(str: String): String do
                if opt_nocolors.value then return str
                return str.green
        end
 
+       # Format and colorize a string heading of level 5 for console output.
+       #
+       # Default style is light gray.
        fun format_p(str: String): String do
                if opt_nocolors.value then return str
                return str.light_gray
@@ -144,11 +158,20 @@ end
 #
 # The concept is reified here for a better organization and documentation
 interface Metric
+
+       # Type of elements measured by this metric.
        type ELM: Object
+
+       # Type of values used to measure elements.
        type VAL: Object
+
+       # Type of data representation used to associate elements and values.
        type RES: Map[ELM, VAL]
 
+       # The name of this metric (generally an acronym about the metric).
        fun name: String is abstract
+
+       # A long and understandable description about what is measured by this metric.
        fun desc: String is abstract
 
        # Clear all results for this metric
@@ -197,6 +220,9 @@ interface Metric
                end
        end
 
+       # The sum of all the values.
+       fun sum: VAL is abstract
+
        # The values standard derivation
        fun std_dev: Float is abstract
 
@@ -211,6 +237,11 @@ interface Metric
 
        # The set of element above the threshold
        fun above_threshold: Set[ELM] is abstract
+
+       # Sort the metric keys by values
+       fun sort: Array[ELM] do
+               return values.keys_sorted_by_values(default_reverse_comparator)
+       end
 end
 
 # A Metric that collects integer data
@@ -222,12 +253,14 @@ class IntMetric
        redef type VAL: Int
        redef type RES: Counter[ELM]
 
+       # `IntMetric` uses a Counter to store values in intern.
        protected var values_cache = new Counter[ELM]
+
        redef fun values do return values_cache
 
        redef fun clear do values_cache.clear
 
-       fun sum: Int do return values_cache.sum
+       redef fun sum do return values_cache.sum
 
        redef fun max do
                assert not values_cache.is_empty
@@ -240,9 +273,9 @@ class IntMetric
        end
 
        # Values average
-       redef fun avg: Float do return values_cache.avg
+       redef fun avg do return values_cache.avg
 
-       redef fun std_dev: Float do return values_cache.std_dev
+       redef fun std_dev do return values_cache.std_dev
 
        redef fun above_threshold do
                var above = new HashSet[ELM]
@@ -271,12 +304,15 @@ class FloatMetric
 
        redef type VAL: Float
 
+       # `FloatMetric` uses a Map to store values in intern.
        protected var values_cache = new HashMap[ELM, VAL]
+
        redef fun values do return values_cache
 
        redef fun clear do values_cache.clear
 
-       fun sum: Float do
+
+       redef fun sum do
                var sum = 0.0
                for v in values.values do sum += v
                return sum
@@ -313,7 +349,7 @@ class FloatMetric
                return sum / values.length.to_f
        end
 
-       redef fun std_dev: Float do
+       redef fun std_dev do
                var sum = 0.0
                for value in values.values do
                        sum += (value - avg).pow(2.to_f)
@@ -338,13 +374,14 @@ class FloatMetric
                        print "{"\t" * indent}  sum: {sum}"
                end
        end
-
 end
 
 # A MetricSet is a metric holder
 #
 # It purpose is to be extended with a metric collect service
 class MetricSet
+
+       # Type of element measured by this `MetricSet`.
        type ELM: Object
 
        # Metrics to compute
index 23f7d49..27d6710 100644 (file)
@@ -91,6 +91,7 @@ redef class ModelBuilder
                model.mmodule_importation_hierarchy.sort(mmodules)
                var nmodules = new Array[AModule]
                for mm in mmodules do
+                       if mm.is_fictive then continue
                        nmodules.add(mmodule2node(mm).as(not null))
                end
                toolcontext.run_phases(nmodules)
index 3503bd0..5fd0381 100644 (file)
@@ -448,6 +448,14 @@ redef class ModelBuilder
 
        # Registration of the nclassdef associated to each mclassdef
        private var mclassdef2nclassdef = new HashMap[MClassDef, AClassdef]
+
+       # Retrieve the associated AST node of a mclassdef.
+       #
+       # This method is used to associate model entity with syntactic entities.
+       # If the class definition is not associated with a node, returns `null`.
+       fun mclassdef2node(mclassdef: MClassDef): nullable AClassdef do
+               return mclassdef2nclassdef.get_or_null(mclassdef)
+       end
 end
 
 redef class AModule
index 9bd4a19..73ce784 100644 (file)
@@ -701,8 +701,6 @@ Statistics of type usage:
           Sys: 4.0
        blooming mclasses (threshold: 12.0)
           Sys: 16.0
-       blooming mclasses (threshold: 12.0)
-          Sys: 16.0
 --- Detection of the usage of covariance static type conformance ---
 -- Total --
 - Kinds of the subtype -