Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 'builder.dart' as builder; | 11 import 'builder.dart' as builder; |
| 12 import 'span.dart'; | 12 import 'span.dart'; |
| 13 import 'src/span_wrapper.dart'; | |
| 13 import 'src/utils.dart'; | 14 import 'src/utils.dart'; |
| 14 import 'src/vlq.dart'; | 15 import 'src/vlq.dart'; |
| 15 | 16 |
| 16 /// Parses a source map directly from a json string. | 17 /// Parses a source map directly from a json string. |
| 17 // TODO(sigmund): evaluate whether other maps should have the json parsed, or | 18 // TODO(sigmund): evaluate whether other maps should have the json parsed, or |
| 18 // the string represenation. | 19 // the string represenation. |
| 19 // TODO(tjblasi): Ignore the first line of [jsonMap] if the JSON safety string | 20 // TODO(tjblasi): Ignore the first line of [jsonMap] if the JSON safety string |
| 20 // `)]}'` begins the string representation of the map. | 21 // `)]}'` begins the string representation of the map. |
| 21 Mapping parse(String jsonMap, {Map<String, Map> otherMaps}) => | 22 Mapping parse(String jsonMap, {Map<String, Map> otherMaps}) => |
| 22 parseJson(JSON.decode(jsonMap), otherMaps: otherMaps); | 23 parseJson(JSON.decode(jsonMap), otherMaps: otherMaps); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 40 'cannot contain "mappings", "sources", or "names".'); | 41 'cannot contain "mappings", "sources", or "names".'); |
| 41 } | 42 } |
| 42 return new MultiSectionMapping.fromJson(map['sections'], otherMaps); | 43 return new MultiSectionMapping.fromJson(map['sections'], otherMaps); |
| 43 } | 44 } |
| 44 return new SingleMapping.fromJson(map); | 45 return new SingleMapping.fromJson(map); |
| 45 } | 46 } |
| 46 | 47 |
| 47 | 48 |
| 48 /// A mapping parsed out of a source map. | 49 /// A mapping parsed out of a source map. |
| 49 abstract class Mapping { | 50 abstract class Mapping { |
| 50 Span spanFor(int line, int column, {Map<String, SourceFile> files}); | 51 /// Returns the span associated with [line] and [column]. |
| 52 /// | |
| 53 /// The values of [files] can be either `source_map` [SourceFile]s or | |
| 54 /// `source_span` `SourceFile`s. Using `source_map` [SourceFile]s is | |
| 55 /// deprecated and will be unsupported in version 0.10.0. | |
| 56 Span spanFor(int line, int column, {Map<String, dynamic> files}); | |
|
Siggi Cherem (dart-lang)
2014/07/18 01:40:53
is the idea that the return type of this function
nweiz
2014/07/23 23:17:18
Yes.
| |
| 51 | 57 |
| 52 Span spanForLocation(Location loc, {Map<String, SourceFile> files}) { | 58 /// Returns the span associated with [location]. |
| 53 return spanFor(loc.line, loc.column, files: files); | 59 /// |
| 60 /// The values of [files] may be either `source_map` [SourceFile]s or | |
| 61 /// `source_span` `SourceFile`s. Using `source_map` [SourceFile]s is | |
| 62 /// deprecated and will be unsupported in version 0.10.0. | |
| 63 Span spanForLocation(location, {Map<String, dynamic> files}) { | |
| 64 location = LocationWrapper.wrap(location); | |
| 65 return spanFor(location.line, location.column, files: files); | |
| 54 } | 66 } |
| 55 } | 67 } |
| 56 | 68 |
| 57 /// A meta-level map containing sections. | 69 /// A meta-level map containing sections. |
| 58 class MultiSectionMapping extends Mapping { | 70 class MultiSectionMapping extends Mapping { |
| 59 /// For each section, the start line offset. | 71 /// For each section, the start line offset. |
| 60 final List<int> _lineStart = <int>[]; | 72 final List<int> _lineStart = <int>[]; |
| 61 | 73 |
| 62 /// For each section, the start column offset. | 74 /// For each section, the start column offset. |
| 63 final List<int> _columnStart = <int>[]; | 75 final List<int> _columnStart = <int>[]; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 105 } | 117 } |
| 106 | 118 |
| 107 int _indexFor(line, column) { | 119 int _indexFor(line, column) { |
| 108 for(int i = 0; i < _lineStart.length; i++) { | 120 for(int i = 0; i < _lineStart.length; i++) { |
| 109 if (line < _lineStart[i]) return i - 1; | 121 if (line < _lineStart[i]) return i - 1; |
| 110 if (line == _lineStart[i] && column < _columnStart[i]) return i - 1; | 122 if (line == _lineStart[i] && column < _columnStart[i]) return i - 1; |
| 111 } | 123 } |
| 112 return _lineStart.length - 1; | 124 return _lineStart.length - 1; |
| 113 } | 125 } |
| 114 | 126 |
| 115 Span spanFor(int line, int column, {Map<String, SourceFile> files}) { | 127 Span spanFor(int line, int column, {Map<String, dynamic> files}) { |
| 116 int index = _indexFor(line, column); | 128 int index = _indexFor(line, column); |
| 117 return _maps[index].spanFor( | 129 return _maps[index].spanFor( |
| 118 line - _lineStart[index], column - _columnStart[index], files: files); | 130 line - _lineStart[index], column - _columnStart[index], files: files); |
| 119 } | 131 } |
| 120 | 132 |
| 121 String toString() { | 133 String toString() { |
| 122 var buff = new StringBuffer("$runtimeType : ["); | 134 var buff = new StringBuffer("$runtimeType : ["); |
| 123 for (int i = 0; i < _lineStart.length; i++) { | 135 for (int i = 0; i < _lineStart.length; i++) { |
| 124 buff..write('(') | 136 buff..write('(') |
| 125 ..write(_lineStart[i]) | 137 ..write(_lineStart[i]) |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 344 /// [lineEntry] corresponds to a line prior to [line], then the result will be | 356 /// [lineEntry] corresponds to a line prior to [line], then the result will be |
| 345 /// the very last entry on that line. | 357 /// the very last entry on that line. |
| 346 TargetEntry _findColumn(int line, int column, TargetLineEntry lineEntry) { | 358 TargetEntry _findColumn(int line, int column, TargetLineEntry lineEntry) { |
| 347 if (lineEntry == null || lineEntry.entries.length == 0) return null; | 359 if (lineEntry == null || lineEntry.entries.length == 0) return null; |
| 348 if (lineEntry.line != line) return lineEntry.entries.last; | 360 if (lineEntry.line != line) return lineEntry.entries.last; |
| 349 var entries = lineEntry.entries; | 361 var entries = lineEntry.entries; |
| 350 int index = binarySearch(entries, (e) => e.column > column); | 362 int index = binarySearch(entries, (e) => e.column > column); |
| 351 return (index <= 0) ? null : entries[index - 1]; | 363 return (index <= 0) ? null : entries[index - 1]; |
| 352 } | 364 } |
| 353 | 365 |
| 354 Span spanFor(int line, int column, {Map<String, SourceFile> files}) { | 366 Span spanFor(int line, int column, {Map<String, dynamic> files}) { |
| 355 var entry = _findColumn(line, column, _findLine(line)); | 367 var entry = _findColumn(line, column, _findLine(line)); |
| 356 if (entry == null || entry.sourceUrlId == null) return null; | 368 if (entry == null || entry.sourceUrlId == null) return null; |
| 357 var url = urls[entry.sourceUrlId]; | 369 var url = urls[entry.sourceUrlId]; |
| 358 if (sourceRoot != null) { | 370 if (sourceRoot != null) { |
| 359 url = '${sourceRoot}${url}'; | 371 url = '${sourceRoot}${url}'; |
| 360 } | 372 } |
| 361 if (files != null && files[url] != null) { | 373 if (files != null && files[url] != null) { |
| 362 var file = files[url]; | 374 var file = SourceFileWrapper.wrap(files[url]); |
| 363 var start = file.getOffset(entry.sourceLine, entry.sourceColumn); | 375 var start = file.getOffset(entry.sourceLine, entry.sourceColumn); |
| 364 if (entry.sourceNameId != null) { | 376 if (entry.sourceNameId != null) { |
| 365 var text = names[entry.sourceNameId]; | 377 var text = names[entry.sourceNameId]; |
| 366 return new FileSpan(files[url], start, start + text.length, true); | 378 return new FileSpan(files[url], start, start + text.length, true); |
| 367 } else { | 379 } else { |
| 368 return new FileSpan(files[url], start); | 380 return new FileSpan(files[url], start); |
| 369 } | 381 } |
| 370 } else { | 382 } else { |
| 371 // Offset and other context is not available. | 383 // Offset and other context is not available. |
| 372 if (entry.sourceNameId != null) { | 384 if (entry.sourceNameId != null) { |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 500 static const _TokenKind EOF = const _TokenKind(isEof: true); | 512 static const _TokenKind EOF = const _TokenKind(isEof: true); |
| 501 static const _TokenKind VALUE = const _TokenKind(); | 513 static const _TokenKind VALUE = const _TokenKind(); |
| 502 final bool isNewLine; | 514 final bool isNewLine; |
| 503 final bool isNewSegment; | 515 final bool isNewSegment; |
| 504 final bool isEof; | 516 final bool isEof; |
| 505 bool get isValue => !isNewLine && !isNewSegment && !isEof; | 517 bool get isValue => !isNewLine && !isNewSegment && !isEof; |
| 506 | 518 |
| 507 const _TokenKind( | 519 const _TokenKind( |
| 508 {this.isNewLine: false, this.isNewSegment: false, this.isEof: false}); | 520 {this.isNewLine: false, this.isNewSegment: false, this.isEof: false}); |
| 509 } | 521 } |
| OLD | NEW |