add -v commandline option to improve error reporting, patch by Daniel
authorJuerg Billeter <j@bitron.ch>
Sun, 23 Mar 2008 11:27:55 +0000 (11:27 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Sun, 23 Mar 2008 11:27:55 +0000 (11:27 +0000)
2008-03-23  Juerg Billeter  <j@bitron.ch>

* vala/valareport.vala, vala/valasourcefile.vala,
  compiler/valacompiler.vala: add -v commandline option to improve
  error reporting, patch by Daniel Silverstone, fixes bug 522511

svn path=/trunk/; revision=1156

ChangeLog
compiler/valacompiler.vala
vala/valareport.vala
vala/valasourcefile.vala

index 32a4a86..8a4d52d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2008-03-23  Jürg Billeter  <j@bitron.ch>
 
+       * vala/valareport.vala, vala/valasourcefile.vala,
+         compiler/valacompiler.vala: add -v commandline option to improve
+         error reporting, patch by Daniel Silverstone, fixes bug 522511
+
+2008-03-23  Jürg Billeter  <j@bitron.ch>
+
        * vapi/packages/json-glib-1.0/: add metadata to fix some memory
          leaks and out parameters, fixes bug 523889
 
index 8d0b7c8..32e873d 100644 (file)
@@ -43,6 +43,7 @@ class Vala.Compiler : Object {
        static bool disable_assert;
        static bool disable_checking;
        static bool non_null;
+       static bool verbose;
        static string cc_command;
        [NoArrayLength]
        static string[] cc_options;
@@ -73,6 +74,7 @@ class Vala.Compiler : Object {
                { "Xcc", 'X', 0, OptionArg.STRING_ARRAY, out cc_options, "Pass OPTION to the C compiler", "OPTION..." },
                { "save-temps", 0, 0, OptionArg.NONE, out save_temps, "Keep temporary files", null },
                { "quiet", 'q', 0, OptionArg.NONE, ref quiet_mode, "Do not print messages to the console", null },
+               { "verbose", 'v', 0, OptionArg.NONE, ref verbose, "Include the source line text when reporting errors or warnings." },
                { "", 0, 0, OptionArg.FILENAME_ARRAY, out sources, null, "FILE..." },
                { null }
        };
@@ -143,6 +145,7 @@ class Vala.Compiler : Object {
                context.assert = !disable_assert;
                context.checking = !disable_checking;
                context.non_null = non_null;
+               Report.set_verbose_errors (verbose);
 
                context.ccode_only = ccode_only;
                context.compile_only = compile_only;
index f614ef9..d819408 100644 (file)
@@ -28,8 +28,17 @@ using GLib;
 public static class Vala.Report {
        private static int warnings;
        private static int errors;
+
+       private static bool verbose_errors;
        
        /**
+        * Set the error verbosity.
+        */
+       public static void set_verbose_errors (bool verbose) {
+               verbose_errors = verbose;
+       }
+
+       /**
         * Returns the total number of warnings reported.
         */
        public static int get_warnings () {
@@ -44,6 +53,44 @@ public static class Vala.Report {
        }
 
        /**
+        * Pretty-print the actual line of offending code if possible.
+        */
+       private static void report_source (SourceReference! source) {
+               if (source.first_line != source.last_line) {
+                       // FIXME Cannot report multi-line issues currently
+                       return;
+               }
+
+               string offending_line = source.file.get_source_line (source.first_line);
+
+               if (offending_line != null) {
+                       stderr.printf ("%s\n", offending_line);
+                       int idx;
+                       
+                       /* We loop in this manner so that we don't fall over on differing
+                        * tab widths. This means we get the ^s in the right places.
+                        */
+                       for (idx = 1; idx < source.first_column; ++idx) {
+                               if (offending_line[idx - 1] == '\t') {
+                                       stderr.printf ("\t");
+                               } else {
+                                       stderr.printf (" ");
+                               }
+                       }
+
+                       for (idx = source.first_column; idx <= source.last_column; ++idx) {
+                               if (offending_line[idx - 1] == '\t') {
+                                       stderr.printf ("\t");
+                               } else {
+                                       stderr.printf ("^");
+                               }
+                       }
+
+                       stderr.printf ("\n");
+               }
+       }
+
+       /**
         * Reports the specified message as warning.
         *
         * @param source  reference to source code
@@ -55,6 +102,9 @@ public static class Vala.Report {
                        stderr.printf ("warning: %s\n", message);
                } else {
                        stderr.printf ("%s: warning: %s\n", source.to_string (), message);
+                       if (verbose_errors) {
+                               report_source (source);
+                       }
                }
        }
        
@@ -70,6 +120,9 @@ public static class Vala.Report {
                        stderr.printf ("error: %s\n", message);
                } else {
                        stderr.printf ("%s: error: %s\n", source.to_string (), message);
+                       if (verbose_errors) {
+                               report_source (source);
+                       }
                }
        }
 }
index 8e4d820..db955a6 100644 (file)
@@ -84,7 +84,9 @@ public class Vala.SourceFile : Object {
        
        private Gee.List<weak SourceFile> header_internal_full_dependencies = new ArrayList<weak SourceFile> ();
        private Gee.List<weak SourceFile> header_internal_dependencies = new ArrayList<weak SourceFile> ();
-       
+
+       private Gee.ArrayList<string> source_array = null;
+
        /**
         * Creates a new source file.
         *
@@ -359,6 +361,41 @@ public class Vala.SourceFile : Object {
        public Collection<weak SourceFile> get_header_internal_dependencies () {
                return new ReadOnlyCollection<weak SourceFile> (header_internal_dependencies);
        }
+
+       /**
+        * Returns the requested line from this file, loading it if needed.
+        *
+        * @param lineno 1-based line number
+        * @return       the specified source line
+        */
+       public string get_source_line (int lineno) {
+               if (source_array == null) {
+                       read_source_file ();
+               }
+               if (lineno < 1 || lineno > source_array.size) {
+                       return null;
+               }
+               return source_array.get (lineno - 1);
+       }
+
+       /**
+        * Parses the input file into ::source_array.
+        */
+       private void read_source_file () {
+               string cont;
+               source_array = new Gee.ArrayList<string> ();
+               try {
+                       FileUtils.get_contents (filename, out cont);
+               } catch (FileError fe) {
+                       return;
+               }
+               string[] lines = cont.split ("\n", 0);
+               uint idx;
+               for (idx = 0; lines[idx] != null; ++idx) {
+                       source_array.add (lines[idx]);
+               }
+       }
+
 }
 
 public enum Vala.SourceFileDependencyType {