Produce better highlights for Windows newlines
diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md
index 74ab342..489f01a 100644
--- a/pkgs/source_span/CHANGELOG.md
+++ b/pkgs/source_span/CHANGELOG.md
@@ -3,6 +3,9 @@
 * Produce better source span highlights for multi-line spans that cover the
   entire last line of the span, including the newline.
 
+* Produce better source span highlights for spans that contain Windows-style
+  newlines.
+
 # 1.5.0
 
 * Improve the output of `SourceSpan.highlight()` and `SourceSpan.message()`:
diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart
index 6270912..3ed1749 100644
--- a/pkgs/source_span/lib/src/highlighter.dart
+++ b/pkgs/source_span/lib/src/highlighter.dart
@@ -59,6 +59,7 @@
     if (color == false) color = null;
 
     var newSpan = _normalizeContext(span);
+    newSpan = _normalizeNewlines(newSpan);
     newSpan = _normalizeTrailingNewline(newSpan);
     newSpan = _normalizeEndOfLine(newSpan);
 
@@ -85,6 +86,29 @@
               span.text,
               span.text);
 
+  /// Normalizes [span] to replace Windows-style newlines with Unix-style
+  /// newlines.
+  static SourceSpanWithContext _normalizeNewlines(SourceSpanWithContext span) {
+    var text = span.text;
+    if (!text.contains("\r\n")) return span;
+
+    var endOffset = span.end.offset;
+    for (var i = 0; i < text.length - 1; i++) {
+      if (text.codeUnitAt(i) == $cr && text.codeUnitAt(i + 1) == $lf) {
+        endOffset--;
+      }
+    }
+
+    return new SourceSpanWithContext(
+        span.start,
+        new SourceLocation(endOffset,
+            sourceUrl: span.sourceUrl,
+            line: span.end.line,
+            column: span.end.column),
+        text.replaceAll("\r\n", "\n"),
+        span.context.replaceAll("\r\n", "\n"));
+  }
+
   /// Normalizes [span] to remove a trailing newline from `span.context`.
   ///
   /// If necessary, also adjust `span.end` so that it doesn't point past where
diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml
index 13fa648..fc5ba2b 100644
--- a/pkgs/source_span/pubspec.yaml
+++ b/pkgs/source_span/pubspec.yaml
@@ -1,5 +1,5 @@
 name: source_span
-version: 1.5.1-dev
+version: 1.5.1
 
 description: A library for identifying source spans and locations.
 author: Dart Team <misc@dartlang.org>
diff --git a/pkgs/source_span/test/highlight_test.dart b/pkgs/source_span/test/highlight_test.dart
index e2536ba..b9e7ded 100644
--- a/pkgs/source_span/test/highlight_test.dart
+++ b/pkgs/source_span/test/highlight_test.dart
@@ -175,6 +175,21 @@
   '"""));
     });
 
+    test("highlights the full last line with a trailing Windows newline", () {
+      var file = new SourceFile.fromString("""
+foo bar baz\r
+whiz bang boom\r
+zip zap zop\r
+""");
+
+      expect(file.span(4, 29).highlight(), equals("""
+  ,
+1 |   foo bar baz
+  | ,-----^
+2 | \\ whiz bang boom
+  '"""));
+    });
+
     test("highlights the full last line at the end of the file", () {
       expect(file.span(4, 39).highlight(), equals("""
   ,
@@ -186,8 +201,8 @@
     });
 
     test(
-        "highlights the full last line at the end of the file with no trailing"
-        " newline", () {
+        "highlights the full last line at the end of the file with no trailing "
+        "newline", () {
       var file = new SourceFile.fromString("""
 foo bar baz
 whiz bang boom