OLD | NEW |
(Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 /// Contains a code printer that generates code by recording the source maps. |
| 6 library source_maps.printer; |
| 7 |
| 8 import 'dart:utf' show stringToCodepoints; |
| 9 import 'builder.dart'; |
| 10 import 'span.dart'; |
| 11 |
| 12 const int _LF = 10; |
| 13 const int _CR = 13; |
| 14 |
| 15 /// A printer that keeps track of offset locations and records source maps |
| 16 /// locations. |
| 17 class Printer { |
| 18 final String filename; |
| 19 final StringBuffer _buff = new StringBuffer(); |
| 20 final SourceMapBuilder _maps = new SourceMapBuilder(); |
| 21 String get text => _buff.toString(); |
| 22 String get map => _maps.toJson(filename); |
| 23 |
| 24 /// Current source location mapping. |
| 25 Location _loc; |
| 26 |
| 27 /// Current line in the buffer; |
| 28 int _line = 0; |
| 29 |
| 30 /// Current column in the buffer. |
| 31 int _column = 0; |
| 32 |
| 33 Printer(this.filename); |
| 34 |
| 35 /// Add [str] contents to the output, tracking new lines to track correct |
| 36 /// positions for span locations. When [projectMarks] is true, this method |
| 37 /// adds a source map location on each new line, projecting that every new |
| 38 /// line in the target file (printed here) corresponds to a new line in the |
| 39 /// source file. |
| 40 void add(String str, {projectMarks: false}) { |
| 41 var chars = stringToCodepoints(str); |
| 42 var length = chars.length; |
| 43 for (int i = 0; i < length; i++) { |
| 44 var c = chars[i]; |
| 45 if (c == _LF || (c == _CR && (i + 1 == length || chars[i + 1] != _LF))) { |
| 46 // Return not followed by line-feed is treated as a new line. |
| 47 _line++; |
| 48 _column = 0; |
| 49 if (projectMarks && _loc != null) { |
| 50 if (_loc is FixedLocation) { |
| 51 mark(new FixedLocation(0, _loc.sourceUrl, _loc.line + 1, 0)); |
| 52 } else if (_loc is FileLocation) { |
| 53 var file = (_loc as FileLocation).file; |
| 54 mark(new FileLocation(file, file.getOffset(_loc.line + 1, 0))); |
| 55 } |
| 56 } |
| 57 } else { |
| 58 _column++; |
| 59 } |
| 60 } |
| 61 _buff.write(str); |
| 62 } |
| 63 |
| 64 |
| 65 /// Append a [total] number of spaces in the target file. Typically used for |
| 66 /// formatting indentation. |
| 67 void addSpaces(int total) { |
| 68 for (int i = 0; i < total; i++) _buff.write(' '); |
| 69 _column += total; |
| 70 } |
| 71 |
| 72 /// Marks that the current point in the target file corresponds to the [mark] |
| 73 /// in the source file, which can be either a [Location] or a [Span]. When the |
| 74 /// mark is an identifier's Span, this also records the name of the identifier |
| 75 /// in the source map information. |
| 76 void mark(mark) { |
| 77 var loc; |
| 78 var identifier = null; |
| 79 if (mark is Location) { |
| 80 loc = mark; |
| 81 } else if (mark is Span) { |
| 82 loc = mark.start; |
| 83 if (mark.isIdentifier) identifier = mark.text; |
| 84 } |
| 85 _maps.addLocation(loc, |
| 86 new FixedLocation(_buff.length, null, _line, _column), identifier); |
| 87 _loc = loc; |
| 88 } |
| 89 } |
OLD | NEW |