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 |