Chromium Code Reviews| Index: lib/parser.dart |
| diff --git a/lib/parser.dart b/lib/parser.dart |
| index 492e6cf65030792b5062594ace3b748553f2305b..ca872fad325802e5eb8826b10c1fdcfea0f6ca83 100644 |
| --- a/lib/parser.dart |
| +++ b/lib/parser.dart |
| @@ -8,7 +8,6 @@ library source_maps.parser; |
| import 'dart:collection'; |
| import 'dart:convert'; |
| -import 'package:path/path.dart' as path; |
| import 'package:source_span/source_span.dart'; |
| import 'builder.dart' as builder; |
| @@ -205,13 +204,50 @@ class MappingBundle extends Mapping { |
| if (uri == null) { |
| throw new ArgumentError.notNull('uri'); |
| } |
| - if (_mappings.containsKey(uri)) { |
| - return _mappings[uri].spanFor(line, column, files: files, uri: uri); |
| - } |
| - // Fall back to looking up the source map on just the basename. |
| - var name = path.basename(uri.toString()); |
| - if (_mappings.containsKey(name)) { |
| - return _mappings[name].spanFor(line, column, files: files, uri: name); |
| + |
| + // Find the longest suffix of the uri that matches the sourcemap |
| + // where the suffix starts after a path segment boundary. |
| + // We consider ":", "/", and "\" as path segment boundaries so that |
| + // "package:" uris, windows paths, and linux paths can all be handled |
| + // properly with minimal special casing. Having a few false positive |
| + // path segment boundaries is not a significant issue as we prefer the |
| + // longest matching prefix. |
| + // Using package:path `path.split` to find path segment boundaries would |
| + // not generate all of the path segment boundaries we want for package: |
| + // urls as "package:package_name" would be one path segment when we want |
| + // "package" and "package_name" to be sepearate path segments. |
| + |
| + bool onBoundary = true; |
| + var separatorCodeUnits = [ |
| + '/'.codeUnitAt(0), |
| + '\\'.codeUnitAt(0), |
|
Siggi Cherem (dart-lang)
2016/12/14 19:10:34
we discussed this offline: let's get rid of the ha
Jacob
2016/12/14 19:17:00
Done.
|
| + ':'.codeUnitAt(0) |
| + ]; |
| + for (var i = 0; i < uri.length; ++i) { |
| + if (onBoundary) { |
| + var candidate = uri.substring(i); |
| + if (_mappings.containsKey(candidate)) { |
| + return _mappings[candidate] |
| + .spanFor(line, column, files: files, uri: candidate); |
| + } |
| + // The following two cases are needed to handle cases where the uri |
| + // may use different path separator conventions that the source map |
| + // bundle as is seasonable if we are using the source map bundle on |
| + // the server while the files being considered are on the client. |
| + |
| + var webCandidate = candidate.replaceAll('\\', '/'); |
| + if (_mappings.containsKey(webCandidate)) { |
| + return _mappings[webCandidate] |
| + .spanFor(line, column, files: files, uri: webCandidate); |
| + } |
| + |
| + var windowsCandidate = candidate.replaceAll('/', '\\'); |
| + if (_mappings.containsKey(windowsCandidate)) { |
| + return _mappings[windowsCandidate] |
| + .spanFor(line, column, files: files, uri: windowsCandidate); |
| + } |
| + } |
| + onBoundary = separatorCodeUnits.contains(uri.codeUnitAt(i)); |
| } |
| // Note: when there is no source map for an uri, this behaves like an |