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 |