Improve handling of locations not from the uris the source map is for.

Make `MappingBundle` distinguish between locations from a file with source maps that do not have a source map entry and locations that are from a file that does not have a source map. This enables more graceful generation of stack traces with mixed Dart and JS stack frames.

Support a new source map bundle format useful for the Dart Dev Compiler. A source map bundle is a JSON array where each entry is a source map.

BUG=
R=sigmund@google.com

Review URL: https://codereview.chromium.org//2564683003 .
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4e32866..e5f3ae2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 0.10.1+4
+
+* Extend `MappingBundle.spanFor` to accept requests for output files that
+  don't have source maps.
+
 ## 0.10.1+3
 
 * Add `MappingBundle` class that handles extended source map format that
diff --git a/lib/parser.dart b/lib/parser.dart
index c651f89..492e6cf 100644
--- a/lib/parser.dart
+++ b/lib/parser.dart
@@ -213,7 +213,17 @@
     if (_mappings.containsKey(name)) {
       return _mappings[name].spanFor(line, column, files: files, uri: name);
     }
-    return null;
+
+    // Note: when there is no source map for an uri, this behaves like an
+    // identity function, returning the requested location as the result.
+
+    // Create a mock offset for the output location. We compute it in terms
+    // of the input line and column to minimize the chances that two different
+    // line and column locations are mapped to the same offset.
+    var offset = line * 1000000 + column;
+    var location = new SourceLocation(offset,
+        line: line, column: column, sourceUrl: Uri.parse(uri));
+    return new SourceMapSpan(location, location, "");
   }
 }
 
diff --git a/pubspec.yaml b/pubspec.yaml
index 33626c5..d0d455f 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: source_maps
-version: 0.10.1+3
+version: 0.10.1+4
 author: Dart Team <misc@dartlang.org>
 description: Library to programmatically manipulate source map files.
 homepage: http://github.com/dart-lang/source_maps
diff --git a/test/parser_test.dart b/test/parser_test.dart
index 9448ea0..a317f7e 100644
--- a/test/parser_test.dart
+++ b/test/parser_test.dart
@@ -178,7 +178,15 @@
     });
 
     test('unmapped path', () {
-      expect(mapping.spanFor(0, 0, uri: "unmapped_output.dart"), isNull);
+      var span = mapping.spanFor(0, 0, uri: "unmapped_output.dart");
+      expect(span.sourceUrl, Uri.parse("unmapped_output.dart"));
+      expect(span.start.line, equals(0));
+      expect(span.start.column, equals(0));
+
+      span = mapping.spanFor(10, 5, uri: "unmapped_output.dart");
+      expect(span.sourceUrl, Uri.parse("unmapped_output.dart"));
+      expect(span.start.line, equals(10));
+      expect(span.start.column, equals(5));
     });
 
     test('missing path', () {