Rename REAMDE to README.md
[nit.git] / src / toolcontext.nit
index 5a3e3cb..8196aeb 100644 (file)
@@ -41,9 +41,21 @@ class Message
 
        # The human-readable description of the message.
        #
-       # It should be short and fit on a single line.
-       # It should also have meaningful information first in case
-       # on truncation by an IDE for instance.
+       # eg. "Error: cannot find method `foo`."
+       #
+       # A good message should:
+       #
+       # * start with a message type like "Error:", "Syntax Error:", "Warning:".
+       #   The type is capitalized and terminated by a column.
+       #   The rest on the message starts with a lowercase letter and is terminated with a dot.
+       #
+       # * be short and fit on a single line.
+       #
+       # * have meaningful information first.
+       #   This helps the reader and remain usable
+       #   when truncated, by an IDE for instance.
+       #
+       # * enclose identifiers, keywords and pieces of code with back-quotes.
        var text: String
 
        # Comparisons are made on message locations.
@@ -54,6 +66,11 @@ class Message
                return location.as(not null) < other.location.as(not null)
        end
 
+       redef fun ==(other): Bool do
+               if not other isa Message then return false
+               return location == other.location and tag == other.tag and text == other.text
+       end
+
        redef fun to_s: String
        do
                var l = location
@@ -199,6 +216,7 @@ class ToolContext
        fun error(l: nullable Location, s: String): Message
        do
                var m = new Message(l,null,s)
+               if messages.has(m) then return m
                if l != null then l.add_message m
                messages.add m
                error_count = error_count + 1
@@ -233,6 +251,7 @@ class ToolContext
                if not opt_warning.value.has(tag) and opt_warn.value == 0 then return null
                if is_warning_blacklisted(l, tag) then return null
                var m = new Message(l, tag, text)
+               if messages.has(m) then return null
                if l != null then l.add_message m
                messages.add m
                warning_count = warning_count + 1
@@ -261,6 +280,7 @@ class ToolContext
                if not opt_warning.value.has(tag) and opt_warn.value <= 1 then return null
                if is_warning_blacklisted(l, tag) then return null
                var m = new Message(l, tag, text)
+               if messages.has(m) then return null
                if l != null then l.add_message m
                messages.add m
                warning_count = warning_count + 1
@@ -345,6 +365,9 @@ class ToolContext
        # Option --stop-on-first-error
        var opt_stop_on_first_error = new OptionBool("Stop on first error", "--stop-on-first-error")
 
+       # Option --keep-going
+       var opt_keep_going = new OptionBool("Continue after errors, whatever the consequences", "--keep-going")
+
        # Option --no-color
        var opt_no_color = new OptionBool("Do not use color to display errors and warnings", "--no-color")
 
@@ -359,7 +382,7 @@ class ToolContext
 
        init
        do
-               option_context.add_option(opt_warn, opt_warning, opt_quiet, opt_stop_on_first_error, opt_no_color, opt_log, opt_log_dir, opt_nit_dir, opt_help, opt_version, opt_set_dummy_tool, opt_verbose, opt_bash_completion, opt_stub_man)
+               option_context.add_option(opt_warn, opt_warning, opt_quiet, opt_stop_on_first_error, opt_keep_going, opt_no_color, opt_log, opt_log_dir, opt_nit_dir, opt_help, opt_version, opt_set_dummy_tool, opt_verbose, opt_bash_completion, opt_stub_man)
 
                # Hide some internal options
                opt_stub_man.hidden = true
@@ -465,6 +488,8 @@ The Nit language documentation and the source code of its tools and libraries ma
                # Set verbose level
                verbose_level = opt_verbose.value
 
+               if opt_keep_going.value then keep_going = true
+
                if self.opt_quiet.value then self.opt_warn.value = 0
 
                if opt_log_dir.value != null then log_directory = opt_log_dir.value.as(not null)
@@ -502,7 +527,7 @@ The Nit language documentation and the source code of its tools and libraries ma
                var res = opt_nit_dir.value
                if res != null then
                        if not check_nit_dir(res) then
-                               fatal_error(null, "Fatal Error: the value of --nit-dir does not seem to be a valid base Nit directory: {res}")
+                               fatal_error(null, "Fatal Error: the value of --nit-dir does not seem to be a valid base Nit directory: {res}.")
                        end
                        return res
                end
@@ -511,7 +536,7 @@ The Nit language documentation and the source code of its tools and libraries ma
                res = "NIT_DIR".environ
                if not res.is_empty then
                        if not check_nit_dir(res) then
-                               fatal_error(null, "Fatal Error: the value of NIT_DIR does not seem to be a valid base Nit directory: {res}")
+                               fatal_error(null, "Fatal Error: the value of NIT_DIR does not seem to be a valid base Nit directory: {res}.")
                        end
                        return res
                end
@@ -535,7 +560,7 @@ The Nit language documentation and the source code of its tools and libraries ma
                        if check_nit_dir(res) then return res.simplify_path
                end
 
-               fatal_error(null, "Fatal Error: Cannot locate a valid base nit directory. It is quite unexpected. Try to set the environment variable `NIT_DIR` or to use the `--nit-dir` option.")
+               fatal_error(null, "Fatal Error: cannot locate a valid base Nit directory. It is quite unexpected. Try to set the environment variable `NIT_DIR` or to use the `--nit-dir` option.")
                abort
        end