Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: lib/parser.dart

Issue 2574593004: Rev package version as the extended source map format is a new feature. (Closed)
Patch Set: Stripped out support for windows paths and instead assume URIs. Added TODO to validate uris in the … Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « CHANGELOG.md ('k') | pubspec.yaml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /// Contains the top-level function to parse source maps version 3. 5 /// Contains the top-level function to parse source maps version 3.
6 library source_maps.parser; 6 library source_maps.parser;
7 7
8 import 'dart:collection'; 8 import 'dart:collection';
9 import 'dart:convert'; 9 import 'dart:convert';
10 10
11 import 'package:path/path.dart' as path;
12 import 'package:source_span/source_span.dart'; 11 import 'package:source_span/source_span.dart';
13 12
14 import 'builder.dart' as builder; 13 import 'builder.dart' as builder;
15 import 'src/source_map_span.dart'; 14 import 'src/source_map_span.dart';
16 import 'src/utils.dart'; 15 import 'src/utils.dart';
17 import 'src/vlq.dart'; 16 import 'src/vlq.dart';
18 17
19 /// Parses a source map directly from a json string. 18 /// Parses a source map directly from a json string.
20 /// 19 ///
21 /// [mapUrl], which may be either a [String] or a [Uri], indicates the URL of 20 /// [mapUrl], which may be either a [String] or a [Uri], indicates the URL of
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 } 177 }
179 } 178 }
180 179
181 class MappingBundle extends Mapping { 180 class MappingBundle extends Mapping {
182 Map<String, SingleMapping> _mappings = {}; 181 Map<String, SingleMapping> _mappings = {};
183 182
184 MappingBundle.fromJson(List json, {String mapUrl}) { 183 MappingBundle.fromJson(List json, {String mapUrl}) {
185 for (var map in json) { 184 for (var map in json) {
186 var mapping = parseJson(map, mapUrl: mapUrl) as SingleMapping; 185 var mapping = parseJson(map, mapUrl: mapUrl) as SingleMapping;
187 var targetUrl = mapping.targetUrl; 186 var targetUrl = mapping.targetUrl;
187 // TODO(jacobr): verify that targetUrl is valid uri instead of a windows
188 // path.
188 _mappings[targetUrl] = mapping; 189 _mappings[targetUrl] = mapping;
189 } 190 }
190 } 191 }
191 192
192 /// Encodes the Mapping mappings as a json map. 193 /// Encodes the Mapping mappings as a json map.
193 List toJson() => _mappings.values.map((v) => v.toJson()).toList(); 194 List toJson() => _mappings.values.map((v) => v.toJson()).toList();
194 195
195 String toString() { 196 String toString() {
196 var buff = new StringBuffer(); 197 var buff = new StringBuffer();
197 for (var map in _mappings.values) { 198 for (var map in _mappings.values) {
198 buff.write(map.toString()); 199 buff.write(map.toString());
199 } 200 }
200 return buff.toString(); 201 return buff.toString();
201 } 202 }
202 203
203 SourceMapSpan spanFor(int line, int column, 204 SourceMapSpan spanFor(int line, int column,
204 {Map<String, SourceFile> files, String uri}) { 205 {Map<String, SourceFile> files, String uri}) {
205 if (uri == null) { 206 if (uri == null) {
206 throw new ArgumentError.notNull('uri'); 207 throw new ArgumentError.notNull('uri');
207 } 208 }
208 if (_mappings.containsKey(uri)) { 209
209 return _mappings[uri].spanFor(line, column, files: files, uri: uri); 210 // Find the longest suffix of the uri that matches the sourcemap
210 } 211 // where the suffix starts after a path segment boundary.
211 // Fall back to looking up the source map on just the basename. 212 // We consider ":" and "/" as path segment boundaries so that
212 var name = path.basename(uri.toString()); 213 // "package:" uris can be handled with minimal special casing. Having a
213 if (_mappings.containsKey(name)) { 214 // few false positive path segment boundaries is not a significant issue
214 return _mappings[name].spanFor(line, column, files: files, uri: name); 215 // as we prefer the longest matching prefix.
216 // Using package:path `path.split` to find path segment boundaries would
217 // not generate all of the path segment boundaries we want for "package:"
218 // urls as "package:package_name" would be one path segment when we want
219 // "package" and "package_name" to be sepearate path segments.
220
221 bool onBoundary = true;
222 var separatorCodeUnits = ['/'.codeUnitAt(0), ':'.codeUnitAt(0)];
223 for (var i = 0; i < uri.length; ++i) {
224 if (onBoundary) {
225 var candidate = uri.substring(i);
226 if (_mappings.containsKey(candidate)) {
227 return _mappings[candidate]
228 .spanFor(line, column, files: files, uri: candidate);
229 }
230 }
231 onBoundary = separatorCodeUnits.contains(uri.codeUnitAt(i));
215 } 232 }
216 233
217 // Note: when there is no source map for an uri, this behaves like an 234 // Note: when there is no source map for an uri, this behaves like an
218 // identity function, returning the requested location as the result. 235 // identity function, returning the requested location as the result.
219 236
220 // Create a mock offset for the output location. We compute it in terms 237 // Create a mock offset for the output location. We compute it in terms
221 // of the input line and column to minimize the chances that two different 238 // of the input line and column to minimize the chances that two different
222 // line and column locations are mapped to the same offset. 239 // line and column locations are mapped to the same offset.
223 var offset = line * 1000000 + column; 240 var offset = line * 1000000 + column;
224 var location = new SourceLocation(offset, 241 var location = new SourceLocation(offset,
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 static const _TokenKind EOF = const _TokenKind(isEof: true); 628 static const _TokenKind EOF = const _TokenKind(isEof: true);
612 static const _TokenKind VALUE = const _TokenKind(); 629 static const _TokenKind VALUE = const _TokenKind();
613 final bool isNewLine; 630 final bool isNewLine;
614 final bool isNewSegment; 631 final bool isNewSegment;
615 final bool isEof; 632 final bool isEof;
616 bool get isValue => !isNewLine && !isNewSegment && !isEof; 633 bool get isValue => !isNewLine && !isNewSegment && !isEof;
617 634
618 const _TokenKind( 635 const _TokenKind(
619 {this.isNewLine: false, this.isNewSegment: false, this.isEof: false}); 636 {this.isNewLine: false, this.isNewSegment: false, this.isEof: false});
620 } 637 }
OLDNEW
« no previous file with comments | « CHANGELOG.md ('k') | pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698