| 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:convert'; | 8 import 'dart:convert'; |
| 9 | 9 |
| 10 import 'span.dart'; | 10 import 'span.dart'; |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 // following order: | 178 // following order: |
| 179 // 0: the starting column in the current line of the generated file | 179 // 0: the starting column in the current line of the generated file |
| 180 // 1: the id of the original source file | 180 // 1: the id of the original source file |
| 181 // 2: the starting line in the original source | 181 // 2: the starting line in the original source |
| 182 // 3: the starting column in the original source | 182 // 3: the starting column in the original source |
| 183 // 4: the id of the original symbol name | 183 // 4: the id of the original symbol name |
| 184 // The values are relative to the previous encountered values. | 184 // The values are relative to the previous encountered values. |
| 185 if (tokenizer.nextKind.isNewSegment) throw _segmentError(0, line); | 185 if (tokenizer.nextKind.isNewSegment) throw _segmentError(0, line); |
| 186 column += tokenizer._consumeValue(); | 186 column += tokenizer._consumeValue(); |
| 187 if (!tokenizer.nextKind.isValue) { | 187 if (!tokenizer.nextKind.isValue) { |
| 188 entries.add(new TargetEntry(column, srcUrlId, srcLine, srcColumn)); | 188 entries.add(new TargetEntry(column)); |
| 189 } else { | 189 } else { |
| 190 srcUrlId += tokenizer._consumeValue(); | 190 srcUrlId += tokenizer._consumeValue(); |
| 191 if (srcUrlId >= urls.length) { | 191 if (srcUrlId >= urls.length) { |
| 192 throw new StateError( | 192 throw new StateError( |
| 193 'Invalid source url id. $targetUrl, $line, $srcUrlId'); | 193 'Invalid source url id. $targetUrl, $line, $srcUrlId'); |
| 194 } | 194 } |
| 195 if (!tokenizer.nextKind.isValue) throw _segmentError(2, line); | 195 if (!tokenizer.nextKind.isValue) throw _segmentError(2, line); |
| 196 srcLine += tokenizer._consumeValue(); | 196 srcLine += tokenizer._consumeValue(); |
| 197 if (!tokenizer.nextKind.isValue) throw _segmentError(3, line); | 197 if (!tokenizer.nextKind.isValue) throw _segmentError(3, line); |
| 198 srcColumn += tokenizer._consumeValue(); | 198 srcColumn += tokenizer._consumeValue(); |
| 199 if (!tokenizer.nextKind.isValue) { | 199 if (!tokenizer.nextKind.isValue) { |
| 200 entries.add(new TargetEntry(column, srcUrlId, srcLine, srcColumn)); | 200 entries.add(new TargetEntry(column, srcUrlId, srcLine, srcColumn)); |
| 201 } else { | 201 } else { |
| 202 srcNameId += tokenizer._consumeValue(); | 202 srcNameId += tokenizer._consumeValue(); |
| 203 if (srcNameId >= names.length) { | 203 if (srcNameId >= names.length) { |
| 204 throw new StateError( | 204 throw new StateError( |
| 205 'Invalid name id: $targetUrl, $line, $srcNameId'); | 205 'Invalid name id: $targetUrl, $line, $srcNameId'); |
| 206 } | 206 } |
| 207 entries.add( | 207 entries.add(new TargetEntry(column, srcUrlId, srcLine, srcColumn, |
| 208 new TargetEntry(column, srcUrlId, srcLine, srcColumn, srcNameId)); | 208 srcNameId)); |
| 209 } | 209 } |
| 210 } | 210 } |
| 211 if (tokenizer.nextKind.isNewSegment) tokenizer._consumeNewSegment(); | 211 if (tokenizer.nextKind.isNewSegment) tokenizer._consumeNewSegment(); |
| 212 } | 212 } |
| 213 if (!entries.isEmpty) { | 213 if (!entries.isEmpty) { |
| 214 lines.add(new TargetLineEntry(line, entries)); | 214 lines.add(new TargetLineEntry(line, entries)); |
| 215 } | 215 } |
| 216 } | 216 } |
| 217 | 217 |
| 218 _segmentError(int seen, int line) => new StateError( | 218 _segmentError(int seen, int line) => new StateError( |
| (...skipping 16 matching lines...) Expand all Loading... |
| 235 TargetEntry _findColumn(int line, int column, TargetLineEntry lineEntry) { | 235 TargetEntry _findColumn(int line, int column, TargetLineEntry lineEntry) { |
| 236 if (lineEntry == null || lineEntry.entries.length == 0) return null; | 236 if (lineEntry == null || lineEntry.entries.length == 0) return null; |
| 237 if (lineEntry.line != line) return lineEntry.entries.last; | 237 if (lineEntry.line != line) return lineEntry.entries.last; |
| 238 var entries = lineEntry.entries; | 238 var entries = lineEntry.entries; |
| 239 int index = binarySearch(entries, (e) => e.column > column); | 239 int index = binarySearch(entries, (e) => e.column > column); |
| 240 return (index <= 0) ? null : entries[index - 1]; | 240 return (index <= 0) ? null : entries[index - 1]; |
| 241 } | 241 } |
| 242 | 242 |
| 243 Span spanFor(int line, int column, {Map<String, SourceFile> files}) { | 243 Span spanFor(int line, int column, {Map<String, SourceFile> files}) { |
| 244 var entry = _findColumn(line, column, _findLine(line)); | 244 var entry = _findColumn(line, column, _findLine(line)); |
| 245 if (entry == null) return null; | 245 if (entry == null || entry.sourceUrlId == null) return null; |
| 246 var url = urls[entry.sourceUrlId]; | 246 var url = urls[entry.sourceUrlId]; |
| 247 if (files != null && files[url] != null) { | 247 if (files != null && files[url] != null) { |
| 248 var file = files[url]; | 248 var file = files[url]; |
| 249 var start = file.getOffset(entry.sourceLine, entry.sourceColumn); | 249 var start = file.getOffset(entry.sourceLine, entry.sourceColumn); |
| 250 if (entry.sourceNameId != null) { | 250 if (entry.sourceNameId != null) { |
| 251 var text = names[entry.sourceNameId]; | 251 var text = names[entry.sourceNameId]; |
| 252 return new FileSpan(files[url], start, start + text.length, true); | 252 return new FileSpan(files[url], start, start + text.length, true); |
| 253 } else { | 253 } else { |
| 254 return new FileSpan(files[url], start); | 254 return new FileSpan(files[url], start); |
| 255 } | 255 } |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 } | 315 } |
| 316 | 316 |
| 317 /// A target segment entry read from a source map | 317 /// A target segment entry read from a source map |
| 318 class TargetEntry { | 318 class TargetEntry { |
| 319 final int column; | 319 final int column; |
| 320 final int sourceUrlId; | 320 final int sourceUrlId; |
| 321 final int sourceLine; | 321 final int sourceLine; |
| 322 final int sourceColumn; | 322 final int sourceColumn; |
| 323 final int sourceNameId; | 323 final int sourceNameId; |
| 324 | 324 |
| 325 TargetEntry(this.column, this.sourceUrlId, this.sourceLine, | 325 TargetEntry(this.column, [this.sourceUrlId, this.sourceLine, |
| 326 this.sourceColumn, [this.sourceNameId]); | 326 this.sourceColumn, this.sourceNameId]); |
| 327 | 327 |
| 328 String toString() => '$runtimeType: ' | 328 String toString() => '$runtimeType: ' |
| 329 '($column, $sourceUrlId, $sourceLine, $sourceColumn, $sourceNameId)'; | 329 '($column, $sourceUrlId, $sourceLine, $sourceColumn, $sourceNameId)'; |
| 330 } | 330 } |
| 331 | 331 |
| 332 /** A character iterator over a string that can peek one character ahead. */ | 332 /** A character iterator over a string that can peek one character ahead. */ |
| 333 class _MappingTokenizer implements Iterator<String> { | 333 class _MappingTokenizer implements Iterator<String> { |
| 334 final String _internal; | 334 final String _internal; |
| 335 final int _length; | 335 final int _length; |
| 336 int index = -1; | 336 int index = -1; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 static const _TokenKind EOF = const _TokenKind(isEof: true); | 381 static const _TokenKind EOF = const _TokenKind(isEof: true); |
| 382 static const _TokenKind VALUE = const _TokenKind(); | 382 static const _TokenKind VALUE = const _TokenKind(); |
| 383 final bool isNewLine; | 383 final bool isNewLine; |
| 384 final bool isNewSegment; | 384 final bool isNewSegment; |
| 385 final bool isEof; | 385 final bool isEof; |
| 386 bool get isValue => !isNewLine && !isNewSegment && !isEof; | 386 bool get isValue => !isNewLine && !isNewSegment && !isEof; |
| 387 | 387 |
| 388 const _TokenKind( | 388 const _TokenKind( |
| 389 {this.isNewLine: false, this.isNewSegment: false, this.isEof: false}); | 389 {this.isNewLine: false, this.isNewSegment: false, this.isEof: false}); |
| 390 } | 390 } |
| OLD | NEW |