Bug 1283712 - Part 4: Print error note in js::PrintError. r=jwalden
authorTooru Fujisawa <arai_a@mac.com>
Wed, 15 Feb 2017 23:53:06 +0900
changeset 343088 687e2816ac03e0d4919c50366c0b20a8c26cca05
parent 343087 f827db18261779031504eb8a5fe9f6e1fcc683d2
child 343089 00672a065d8c13e2399c55f0d86226f83afb9393
push id31369
push userkwierso@gmail.com
push dateThu, 16 Feb 2017 00:18:40 +0000
treeherdermozilla-central@e9b926463f9e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwalden
bugs1283712
milestone54.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1283712 - Part 4: Print error note in js::PrintError. r=jwalden
js/src/jscntxt.cpp
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -441,59 +441,26 @@ js::ReportUsageErrorASCII(JSContext* cx,
         RootedString usageStr(cx, usage.toString());
         JSAutoByteString str;
         if (!str.encodeUtf8(cx, usageStr))
             return;
         JS_ReportErrorUTF8(cx, "%s. Usage: %s", msg, str.ptr());
     }
 }
 
-bool
-js::PrintError(JSContext* cx, FILE* file, JS::ConstUTF8CharsZ toStringResult,
-               JSErrorReport* report, bool reportWarnings)
-{
-    MOZ_ASSERT(report);
-
-    /* Conditionally ignore reported warnings. */
-    if (JSREPORT_IS_WARNING(report->flags) && !reportWarnings)
-        return false;
+enum class PrintErrorKind {
+    Error,
+    Warning,
+    StrictWarning,
+    Note
+};
 
-    char* prefix = nullptr;
-    if (report->filename)
-        prefix = JS_smprintf("%s:", report->filename);
-    if (report->lineno) {
-        char* tmp = prefix;
-        prefix = JS_smprintf("%s%u:%u ", tmp ? tmp : "", report->lineno, report->column);
-        JS_free(cx, tmp);
-    }
-    if (JSREPORT_IS_WARNING(report->flags)) {
-        char* tmp = prefix;
-        prefix = JS_smprintf("%s%swarning: ",
-                             tmp ? tmp : "",
-                             JSREPORT_IS_STRICT(report->flags) ? "strict " : "");
-        JS_free(cx, tmp);
-    }
-
-    const char* message = toStringResult ? toStringResult.c_str() : report->message().c_str();
-
-    /* embedded newlines -- argh! */
-    const char* ctmp;
-    while ((ctmp = strchr(message, '\n')) != 0) {
-        ctmp++;
-        if (prefix)
-            fputs(prefix, file);
-        fwrite(message, 1, ctmp - message, file);
-        message = ctmp;
-    }
-
-    /* If there were no filename or lineno, the prefix might be empty */
-    if (prefix)
-        fputs(prefix, file);
-    fputs(message, file);
-
+static void
+PrintErrorLine(JSContext* cx, FILE* file, const char* prefix, JSErrorReport* report)
+{
     if (const char16_t* linebuf = report->linebuf()) {
         size_t n = report->linebufLength();
 
         fputs(":\n", file);
         if (prefix)
             fputs(prefix, file);
 
         for (size_t i = 0; i < n; i++)
@@ -513,19 +480,106 @@ js::PrintError(JSContext* cx, FILE* file
                     fputc('.', file);
                 continue;
             }
             fputc('.', file);
             j++;
         }
         fputc('^', file);
     }
+}
+
+static void
+PrintErrorLine(JSContext* cx, FILE* file, const char* prefix, JSErrorNotes::Note* note)
+{
+}
+
+template <typename T>
+static bool
+PrintSingleError(JSContext* cx, FILE* file, JS::ConstUTF8CharsZ toStringResult,
+                 T* report, PrintErrorKind kind)
+{
+    UniquePtr<char> prefix;
+    if (report->filename)
+        prefix.reset(JS_smprintf("%s:", report->filename));
+
+    if (report->lineno) {
+        UniquePtr<char> tmp(JS_smprintf("%s%u:%u ", prefix ? prefix.get() : "", report->lineno,
+                                        report->column));
+        prefix = Move(tmp);
+    }
+
+    if (kind != PrintErrorKind::Error) {
+        const char* kindPrefix = nullptr;
+        switch (kind) {
+          case PrintErrorKind::Error:
+            break;
+          case PrintErrorKind::Warning:
+            kindPrefix = "warning";
+            break;
+          case PrintErrorKind::StrictWarning:
+            kindPrefix = "strict warning";
+            break;
+          case PrintErrorKind::Note:
+            kindPrefix = "note";
+            break;
+        }
+
+        UniquePtr<char> tmp(JS_smprintf("%s%s: ", prefix ? prefix.get() : "", kindPrefix));
+        prefix = Move(tmp);
+    }
+
+    const char* message = toStringResult ? toStringResult.c_str() : report->message().c_str();
+
+    /* embedded newlines -- argh! */
+    const char* ctmp;
+    while ((ctmp = strchr(message, '\n')) != 0) {
+        ctmp++;
+        if (prefix)
+            fputs(prefix.get(), file);
+        fwrite(message, 1, ctmp - message, file);
+        message = ctmp;
+    }
+
+    /* If there were no filename or lineno, the prefix might be empty */
+    if (prefix)
+        fputs(prefix.get(), file);
+    fputs(message, file);
+
+    PrintErrorLine(cx, file, prefix.get(), report);
     fputc('\n', file);
+
     fflush(file);
-    JS_free(cx, prefix);
+    return true;
+}
+
+bool
+js::PrintError(JSContext* cx, FILE* file, JS::ConstUTF8CharsZ toStringResult,
+               JSErrorReport* report, bool reportWarnings)
+{
+    MOZ_ASSERT(report);
+
+    /* Conditionally ignore reported warnings. */
+    if (JSREPORT_IS_WARNING(report->flags) && !reportWarnings)
+        return false;
+
+    PrintErrorKind kind = PrintErrorKind::Error;
+    if (JSREPORT_IS_WARNING(report->flags)) {
+        if (JSREPORT_IS_STRICT(report->flags))
+            kind = PrintErrorKind::StrictWarning;
+        else
+            kind = PrintErrorKind::Warning;
+    }
+    PrintSingleError(cx, file, toStringResult, report, kind);
+
+    if (report->notes) {
+        for (auto&& note : *report->notes)
+            PrintSingleError(cx, file, JS::ConstUTF8CharsZ(), note.get(), PrintErrorKind::Note);
+    }
+
     return true;
 }
 
 class MOZ_RAII AutoMessageArgs
 {
     size_t totalLength_;
     /* only {0} thru {9} supported */
     mozilla::Array<const char*, JS::MaxNumErrorArguments> args_;