Index: pkg/source_maps/lib/printer.dart |
diff --git a/pkg/source_maps/lib/printer.dart b/pkg/source_maps/lib/printer.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..333aadcd429c4e951c0aef2c78a2f47db287e442 |
--- /dev/null |
+++ b/pkg/source_maps/lib/printer.dart |
@@ -0,0 +1,89 @@ |
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+/// Contains a code printer that generates code by recording the source maps. |
+library source_maps.printer; |
+ |
+import 'dart:utf' show stringToCodepoints; |
+import 'builder.dart'; |
+import 'span.dart'; |
+ |
+const int _LF = 10; |
+const int _CR = 13; |
+ |
+/// A printer that keeps track of offset locations and records source maps |
+/// locations. |
+class Printer { |
+ final String filename; |
+ final StringBuffer _buff = new StringBuffer(); |
+ final SourceMapBuilder _maps = new SourceMapBuilder(); |
+ String get text => _buff.toString(); |
+ String get map => _maps.toJson(filename); |
+ |
+ /// Current source location mapping. |
+ Location _loc; |
+ |
+ /// Current line in the buffer; |
+ int _line = 0; |
+ |
+ /// Current column in the buffer. |
+ int _column = 0; |
+ |
+ Printer(this.filename); |
+ |
+ /// Add [str] contents to the output, tracking new lines to track correct |
+ /// positions for span locations. When [projectMarks] is true, this method |
+ /// adds a source map location on each new line, projecting that every new |
+ /// line in the target file (printed here) corresponds to a new line in the |
+ /// source file. |
+ void add(String str, {projectMarks: false}) { |
+ var chars = stringToCodepoints(str); |
+ var length = chars.length; |
+ for (int i = 0; i < length; i++) { |
+ var c = chars[i]; |
+ if (c == _LF || (c == _CR && (i + 1 == length || chars[i + 1] != _LF))) { |
+ // Return not followed by line-feed is treated as a new line. |
+ _line++; |
+ _column = 0; |
+ if (projectMarks && _loc != null) { |
+ if (_loc is FixedLocation) { |
+ mark(new FixedLocation(0, _loc.sourceUrl, _loc.line + 1, 0)); |
+ } else if (_loc is FileLocation) { |
+ var file = (_loc as FileLocation).file; |
+ mark(new FileLocation(file, file.getOffset(_loc.line + 1, 0))); |
+ } |
+ } |
+ } else { |
+ _column++; |
+ } |
+ } |
+ _buff.write(str); |
+ } |
+ |
+ |
+ /// Append a [total] number of spaces in the target file. Typically used for |
+ /// formatting indentation. |
+ void addSpaces(int total) { |
+ for (int i = 0; i < total; i++) _buff.write(' '); |
+ _column += total; |
+ } |
+ |
+ /// Marks that the current point in the target file corresponds to the [mark] |
+ /// in the source file, which can be either a [Location] or a [Span]. When the |
+ /// mark is an identifier's Span, this also records the name of the identifier |
+ /// in the source map information. |
+ void mark(mark) { |
+ var loc; |
+ var identifier = null; |
+ if (mark is Location) { |
+ loc = mark; |
+ } else if (mark is Span) { |
+ loc = mark.start; |
+ if (mark.isIdentifier) identifier = mark.text; |
+ } |
+ _maps.addLocation(loc, |
+ new FixedLocation(_buff.length, null, _line, _column), identifier); |
+ _loc = loc; |
+ } |
+} |