| Index: lib/parser.dart
|
| diff --git a/lib/parser.dart b/lib/parser.dart
|
| index 369c27d0ad7a0cc8fa0f557cfa893cba17aaf290..a9fcff57840ec6d4cef109b24770db20c16a9440 100644
|
| --- a/lib/parser.dart
|
| +++ b/lib/parser.dart
|
| @@ -16,15 +16,23 @@ import 'src/utils.dart';
|
| import 'src/vlq.dart';
|
|
|
| /// Parses a source map directly from a json string.
|
| +///
|
| +/// [mapUrl], which may be either a [String] or a [Uri], indicates the URL of
|
| +/// the source map file itself. If it's passed, any URLs in the source
|
| +/// map will be interpreted as relative to this URL when generating spans.
|
| // TODO(sigmund): evaluate whether other maps should have the json parsed, or
|
| // the string represenation.
|
| // TODO(tjblasi): Ignore the first line of [jsonMap] if the JSON safety string
|
| // `)]}'` begins the string representation of the map.
|
| -Mapping parse(String jsonMap, {Map<String, Map> otherMaps}) =>
|
| - parseJson(JSON.decode(jsonMap), otherMaps: otherMaps);
|
| +Mapping parse(String jsonMap, {Map<String, Map> otherMaps, mapUrl}) =>
|
| + parseJson(JSON.decode(jsonMap), otherMaps: otherMaps, mapUrl: mapUrl);
|
|
|
| /// Parses a source map directly from a json map object.
|
| -Mapping parseJson(Map map, {Map<String, Map> otherMaps}) {
|
| +///
|
| +/// [mapUrl], which may be either a [String] or a [Uri], indicates the URL of
|
| +/// the source map file itself. If it's passed, any URLs in the source
|
| +/// map will be interpreted as relative to this URL when generating spans.
|
| +Mapping parseJson(Map map, {Map<String, Map> otherMaps, mapUrl}) {
|
| if (map['version'] != 3) {
|
| throw new ArgumentError(
|
| 'unexpected source map version: ${map["version"]}. '
|
| @@ -37,9 +45,10 @@ Mapping parseJson(Map map, {Map<String, Map> otherMaps}) {
|
| throw new FormatException('map containing "sections" '
|
| 'cannot contain "mappings", "sources", or "names".');
|
| }
|
| - return new MultiSectionMapping.fromJson(map['sections'], otherMaps);
|
| + return new MultiSectionMapping.fromJson(map['sections'], otherMaps,
|
| + mapUrl: mapUrl);
|
| }
|
| - return new SingleMapping.fromJson(map);
|
| + return new SingleMapping.fromJson(map, mapUrl: mapUrl);
|
| }
|
|
|
|
|
| @@ -68,7 +77,8 @@ class MultiSectionMapping extends Mapping {
|
| final List<Mapping> _maps = <Mapping>[];
|
|
|
| /// Creates a section mapping from json.
|
| - MultiSectionMapping.fromJson(List sections, Map<String, Map> otherMaps) {
|
| + MultiSectionMapping.fromJson(List sections, Map<String, Map> otherMaps,
|
| + {mapUrl}) {
|
| for (var section in sections) {
|
| var offset = section['offset'];
|
| if (offset == null) throw new FormatException('section missing offset');
|
| @@ -93,9 +103,9 @@ class MultiSectionMapping extends Mapping {
|
| 'section contains refers to $url, but no map was '
|
| 'given for it. Make sure a map is passed in "otherMaps"');
|
| }
|
| - _maps.add(parseJson(otherMaps[url], otherMaps: otherMaps));
|
| + _maps.add(parseJson(otherMaps[url], otherMaps: otherMaps, mapUrl: url));
|
| } else if (map != null) {
|
| - _maps.add(parseJson(map, otherMaps: otherMaps));
|
| + _maps.add(parseJson(map, otherMaps: otherMaps, mapUrl: mapUrl));
|
| } else {
|
| throw new FormatException('section missing url or map');
|
| }
|
| @@ -149,10 +159,13 @@ class SingleMapping extends Mapping {
|
| /// Url of the target file.
|
| String targetUrl;
|
|
|
| - /// Source root appended to the start of all entries in [urls].
|
| + /// Source root prepended to all entries in [urls].
|
| String sourceRoot;
|
|
|
| - SingleMapping._(this.targetUrl, this.urls, this.names, this.lines);
|
| + final Uri _mapUrl;
|
| +
|
| + SingleMapping._(this.targetUrl, this.urls, this.names, this.lines)
|
| + : _mapUrl = null;
|
|
|
| factory SingleMapping.fromEntries(
|
| Iterable<builder.Entry> entries, [String fileUrl]) {
|
| @@ -197,12 +210,13 @@ class SingleMapping extends Mapping {
|
| fileUrl, urls.keys.toList(), names.keys.toList(), lines);
|
| }
|
|
|
| - SingleMapping.fromJson(Map map)
|
| + SingleMapping.fromJson(Map map, {mapUrl})
|
| : targetUrl = map['file'],
|
| urls = map['sources'],
|
| names = map['names'],
|
| sourceRoot = map['sourceRoot'],
|
| - lines = <TargetLineEntry>[] {
|
| + lines = <TargetLineEntry>[],
|
| + _mapUrl = mapUrl is String ? Uri.parse(mapUrl) : mapUrl {
|
| int line = 0;
|
| int column = 0;
|
| int srcUrlId = 0;
|
| @@ -373,7 +387,10 @@ class SingleMapping extends Mapping {
|
| }
|
| } else {
|
| var start = new SourceLocation(0,
|
| - sourceUrl: url, line: entry.sourceLine, column: entry.sourceColumn);
|
| + sourceUrl: _mapUrl == null ? url : _mapUrl.resolve(url),
|
| + line: entry.sourceLine,
|
| + column: entry.sourceColumn);
|
| +
|
| // Offset and other context is not available.
|
| if (entry.sourceNameId != null) {
|
| return new SourceMapSpan.identifier(start, names[entry.sourceNameId]);
|
|
|