test_parser: add option `-x` to output XML
[nit.git] / src / toolcontext.nit
index 62c184a..5a3e3cb 100644 (file)
@@ -91,6 +91,24 @@ class Message
        end
 end
 
+redef class Location
+       # Errors and warnings associated to this location.
+       var messages: nullable Array[Message]
+
+       # Add a message to `self`
+       #
+       # See `messages`
+       private fun add_message(m: Message)
+       do
+               var ms = messages
+               if ms == null then
+                       ms = new Array[Message]
+                       messages = ms
+               end
+               ms.add m
+       end
+end
+
 # Global context for tools
 class ToolContext
        # Number of errors
@@ -134,13 +152,13 @@ class ToolContext
                return tags.has("all") or tags.has(tag)
        end
 
-       # Output all current stacked messages and display total error informations
+       # Output all current stacked messages
        #
        # Return true if no errors occurred.
        #
        # If some errors occurred, the behavior depends on the value of `keep_going`.
-       # If `keep_going` is false, then the program exits.
-       # Else, the error count and the warning count are reset and false is returned.
+       # If `keep_going` is false, then the total error informations is displayed and the program exits.
+       # Else, false is returned.
        fun check_errors: Bool
        do
                if messages.length > 0 then
@@ -158,32 +176,39 @@ class ToolContext
                end
 
                if error_count > 0 then
-                       errors_info
-                       if not keep_going then exit(1)
+                       if not keep_going then
+                               errors_info
+                               exit(1)
+                       end
                        return false
                end
                return true
        end
 
-       # Display (and reset) total error informations
+       # Display total error informations
        fun errors_info
        do
                if error_count == 0 and warning_count == 0 then return
                if opt_no_color.value then return
                sys.stderr.write "Errors: {error_count}. Warnings: {warning_count}.\n"
-               error_count = 0
-               warning_count = 0
        end
 
        # Display an error
-       fun error(l: nullable Location, s: String)
+       #
+       # Return the message (to add information)
+       fun error(l: nullable Location, s: String): Message
        do
-               messages.add(new Message(l,null,s))
+               var m = new Message(l,null,s)
+               if l != null then l.add_message m
+               messages.add m
                error_count = error_count + 1
                if opt_stop_on_first_error.value then check_errors
+               return m
        end
 
        # Add an error, show errors and quit
+       #
+       # Because the program will quit, nothing is returned.
        fun fatal_error(l: nullable Location, s: String)
        do
                error(l,s)
@@ -200,14 +225,19 @@ class ToolContext
        # * They always are real issues (no false positive)
        #
        # First-level warnings are displayed by default (except if option `-q` is given).
-       fun warning(l: nullable Location, tag: String, text: String)
+       #
+       # Return the message (to add information) or null if the warning is disabled
+       fun warning(l: nullable Location, tag: String, text: String): nullable Message
        do
-               if opt_warning.value.has("no-{tag}") then return
-               if not opt_warning.value.has(tag) and opt_warn.value == 0 then return
-               if is_warning_blacklisted(l, tag) then return
-               messages.add(new Message(l, tag, text))
+               if opt_warning.value.has("no-{tag}") then return null
+               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 l != null then l.add_message m
+               messages.add m
                warning_count = warning_count + 1
                if opt_stop_on_first_error.value then check_errors
+               return m
        end
 
        # Display a second-level warning.
@@ -223,14 +253,19 @@ class ToolContext
        #
        # In order to prevent warning inflation à la Java, second-level warnings are not displayed by
        # default and require an additional option `-W`.
-       fun advice(l: nullable Location, tag: String, text: String)
+       #
+       # Return the message (to add information) or null if the warning is disabled
+       fun advice(l: nullable Location, tag: String, text: String): nullable Message
        do
-               if opt_warning.value.has("no-{tag}") then return
-               if not opt_warning.value.has(tag) and opt_warn.value <= 1 then return
-               if is_warning_blacklisted(l, tag) then return
-               messages.add(new Message(l, tag, text))
+               if opt_warning.value.has("no-{tag}") then return null
+               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 l != null then l.add_message m
+               messages.add m
                warning_count = warning_count + 1
                if opt_stop_on_first_error.value then check_errors
+               return m
        end
 
        # Display an info