Make source map location information more readable.

This changes "file:1:2" to "line 1, column 2 of file" and ":1:2" to
"line 1, column 2" in [SourceFile.getLocationMessage]. The more
machine-readable colon-separated format doesn't make sense for a
message intended for humans.

Since [Location.formatString] seems more likely to be consumed by
machines, its format was left as-is.

This also prepares version 0.9.1 for release.

R=sigmund@google.com

Review URL: https://codereview.chromium.org//300583002

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@36603 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..e278458
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,5 @@
+## 0.9.1
+
+* Support unmapped areas in source maps.
+
+* Increase the readability of location messages.
diff --git a/lib/span.dart b/lib/span.dart
index 17ccd27..f47e08e 100644
--- a/lib/span.dart
+++ b/lib/span.dart
@@ -7,6 +7,8 @@
 
 import 'dart:math' show min, max;
 
+import 'package:path/path.dart' as p;
+
 import 'src/utils.dart';
 
 /// A simple class that describe a segment of source text.
@@ -252,8 +254,8 @@
     var line = getLine(start);
     var column = getColumn(line, start);
 
-    var src = url == null ? '' : url;
-    var msg = '$src:${line + 1}:${column + 1}: $message';
+    var source = url == null ? '' : ' of ${p.prettyUri(url)}';
+    var msg = 'line ${line + 1}, column ${column + 1}$source: $message';
 
     if (_decodedChars == null) {
       // We don't have any text to include, so exit.
diff --git a/pubspec.yaml b/pubspec.yaml
index 71cbfb5..3c946e0 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,8 +1,10 @@
 name: source_maps
-version: 0.9.1-dev
+version: 0.9.1
 author: Dart Team <misc@dartlang.org>
 description: Library to programmatically manipulate source map files.
 homepage: http://www.dartlang.org
+dependencies:
+  path: '>=1.2.0 <2.0.0'
 environment:
   sdk: '>=0.8.10+6 <2.0.0'
 dev_dependencies:
diff --git a/test/span_test.dart b/test/span_test.dart
index da3e063..190b7a6 100644
--- a/test/span_test.dart
+++ b/test/span_test.dart
@@ -72,7 +72,7 @@
   group('location message', () {
     test('first line', () {
       expect(file.getLocationMessage('the message', 1, 3),
-          'file:1:2: the message\n'
+          'line 1, column 2 of file: the message\n'
           '+23456789_\n'
           ' ^^');
     });
@@ -81,7 +81,7 @@
       // fifth line (including 4 new lines), columns 2 .. 11
       var line = 10 + 80 + 31 + 27 + 4;
       expect(file.getLocationMessage('the message', line + 2, line + 11),
-          'file:5:3: the message\n'
+          'line 5, column 3 of file: the message\n'
           '1234+6789_1234\n'
           '  ^^^^^^^^^');
     });
@@ -90,7 +90,7 @@
       var line = 10 + 80 + 31 + 27 + 4;
       expect(new SourceFile.text(null, TEST_FILE).getLocationMessage(
           'the message', line + 2, line + 11),
-          ':5:3: the message\n'
+          'line 5, column 3: the message\n'
           '1234+6789_1234\n'
           '  ^^^^^^^^^');
     });
@@ -100,7 +100,7 @@
       int index = TEST_FILE.lastIndexOf('\n');
       var start = TEST_FILE.lastIndexOf('\n', index - 1) - 3;
       expect(file.getLocationMessage('the message', start, start + 2),
-          'file:11:41: the message\n'
+          'line 11, column 41 of file: the message\n'
           '123456789_+23456789_123456789_123456789_123\n'
           '                                        ^^');
     });
@@ -108,7 +108,7 @@
     test('last line', () {
       var start = TEST_FILE.lastIndexOf('\n') - 2;
       expect(file.getLocationMessage('the message', start, start + 1),
-          'file:12:28: the message\n'
+          'line 12, column 28 of file: the message\n'
           '123456789_1+3456789_123456789\n'
           '                           ^');
     });
@@ -120,7 +120,7 @@
       test('penultimate line', () {
         var start = text.lastIndexOf('\n') - 3;
         expect(file2.getLocationMessage('the message', start, start + 2),
-            'file:11:41: the message\n'
+            'line 11, column 41 of file: the message\n'
             '123456789_+23456789_123456789_123456789_123\n'
             '                                        ^^');
       });
@@ -128,7 +128,7 @@
       test('last line', () {
         var start = text.length - 2;
         expect(file2.getLocationMessage('the message', start, start + 1),
-            'file:12:28: the message\n'
+            'line 12, column 28 of file: the message\n'
             '123456789_1+3456789_123456789\n'
             '                           ^');
       });
@@ -139,7 +139,7 @@
       int start = text.indexOf(' ') + 1;
       var file2 = new SourceFile.text('file', text);
       expect(file2.getLocationMessage('the message', start, start + 2),
-            'file:1:${start + 1}: the message\n'
+            'line 1, column ${start + 1} of file: the message\n'
             'this is a single line\n'
             '     ^^');
     });
@@ -178,7 +178,7 @@
 
     var line = 10 + 80 + 31 + 27 + 4;
     expect(span(line + 2, line + 11).getLocationMessage('the message'),
-        'file:5:3: the message\n'
+        'line 5, column 3 of file: the message\n'
         '1234+6789_1234\n'
         '  ^^^^^^^^^');
 
@@ -226,7 +226,7 @@
   test('range check for large offsets', () {
     var start = TEST_FILE.length;
     expect(file.getLocationMessage('the message', start, start + 9),
-        'file:13:1: the message\n');
+        'line 13, column 1 of file: the message\n');
   });
 
   group('file segment', () {
@@ -296,7 +296,7 @@
       test('past segment, past its line', () {
         var start = TEST_FILE.length - 2;
         expect(file.getLocationMessage('the message', start, start + 1),
-          'file:12:29: the message\n'
+          'line 12, column 29 of file: the message\n'
           '123456789_1+3456789_123456789\n'
           '                            ^');
 
@@ -304,7 +304,7 @@
         // about the 10 lines it has (and nothing about the possible extra lines
         // afterwards)
         expect(segment.getLocationMessage('the message', start, start + 1),
-          'file:11:1: the message\n');
+          'line 11, column 1 of file: the message\n');
       });
     });
   });