formatter: Remove colon line prefix with no source

If a diagnostic has no Source information, don't start the diagnostic line with a colon.

Bug: tint:282
Change-Id: I80c4103e31556b2769d4b4c2a98dce21a2e1c233
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/31662
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/diagnostic/formatter.cc b/src/diagnostic/formatter.cc
index 6257425..a5a3f18 100644
--- a/src/diagnostic/formatter.cc
+++ b/src/diagnostic/formatter.cc
@@ -137,13 +137,17 @@
 
   state.set_style({Color::kDefault, true});
 
+  bool emit_colon = true;
   if (style_.print_file && src.file != nullptr && !src.file->path.empty()) {
     state << src.file->path;
     if (rng.begin.line > 0) {
       state << ":" << rng.begin;
     }
-  } else {
+  } else if (rng.begin.line > 0) {
     state << rng.begin;
+  } else {
+    // No position infomation was printed, so don't start the line with a colon.
+    emit_colon = false;
   }
   if (style_.print_severity) {
     switch (diag.severity) {
@@ -157,11 +161,16 @@
       default:
         break;
     }
-    state << " " << diag.severity;
+    state << " " << diag.severity << ": ";
+    // A colon was just printed, don't repeat it.
+    emit_colon = false;
   }
 
   state.set_style({Color::kDefault, true});
-  state << ": " << diag.message;
+  if (emit_colon) {
+    state << ": ";
+  }
+  state << diag.message;
 
   if (style_.print_line && src.file != nullptr && rng.begin.line > 0) {
     state.newline();
diff --git a/src/diagnostic/formatter_test.cc b/src/diagnostic/formatter_test.cc
index 582557b..273c1bb 100644
--- a/src/diagnostic/formatter_test.cc
+++ b/src/diagnostic/formatter_test.cc
@@ -53,6 +53,14 @@
   ASSERT_EQ(expect, got);
 }
 
+TEST_F(DiagFormatterTest, SimpleNoSource) {
+  Formatter fmt{{false, false, false}};
+  Diagnostic diag{Severity::Info, Source{}, "no source!"};
+  auto got = fmt.format(List{diag});
+  auto* expect = "no source!";
+  ASSERT_EQ(expect, got);
+}
+
 TEST_F(DiagFormatterTest, WithFile) {
   Formatter fmt{{true, false, false}};
   auto got = fmt.format(List{diag_info, diag_warn, diag_err, diag_fatal});