Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(393)

Side by Side Diff: pkg/source_maps/lib/printer.dart

Issue 22396004: Make observable transform a barback transform. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: addressing john's comments Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 a code printer that generates code by recording the source maps. 5 /// Contains a code printer that generates code by recording the source maps.
6 library source_maps.printer; 6 library source_maps.printer;
7 7
8 import 'dart:utf' show stringToCodepoints; 8 import 'dart:utf' show stringToCodepoints;
9 import 'builder.dart'; 9 import 'builder.dart';
10 import 'span.dart'; 10 import 'span.dart';
11 11
12 const int _LF = 10; 12 const int _LF = 10;
13 const int _CR = 13; 13 const int _CR = 13;
14 14
15 /// A printer that keeps track of offset locations and records source maps 15 /// A simple printer that keeps track of offset locations and records source
16 /// locations. 16 /// maps locations.
17 class Printer { 17 class Printer {
18 final String filename; 18 final String filename;
19 final StringBuffer _buff = new StringBuffer(); 19 final StringBuffer _buff = new StringBuffer();
20 final SourceMapBuilder _maps = new SourceMapBuilder(); 20 final SourceMapBuilder _maps = new SourceMapBuilder();
21 String get text => _buff.toString(); 21 String get text => _buff.toString();
22 String get map => _maps.toJson(filename); 22 String get map => _maps.toJson(filename);
23 23
24 /// Current source location mapping. 24 /// Current source location mapping.
25 Location _loc; 25 Location _loc;
26 26
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 loc = mark; 80 loc = mark;
81 } else if (mark is Span) { 81 } else if (mark is Span) {
82 loc = mark.start; 82 loc = mark.start;
83 if (mark.isIdentifier) identifier = mark.text; 83 if (mark.isIdentifier) identifier = mark.text;
84 } 84 }
85 _maps.addLocation(loc, 85 _maps.addLocation(loc,
86 new FixedLocation(_buff.length, null, _line, _column), identifier); 86 new FixedLocation(_buff.length, null, _line, _column), identifier);
87 _loc = loc; 87 _loc = loc;
88 } 88 }
89 } 89 }
90
91 /// A more advanced printer that keeps track of offset locations to record
Siggi Cherem (dart-lang) 2013/08/09 22:09:09 this code is very similar to the original main dif
92 /// source maps, but additionally allows nesting of different kind of items,
93 /// including [NestedPrinter]s, and it let's you automatically indent text.
94 ///
95 /// This class is especially useful when doing code generation, where different
96 /// peices of the code are generated independently on separate printers, and are
97 /// finally put together in the end.
98 class NestedPrinter implements NestedItem {
99
100 /// Items recoded by this printer, which can be [String] literals,
101 /// [NestedItem]s, and source map information like [Location] and [Span].
102 List _items = [];
103
104 /// Internal buffer to merge consecutive strings added to this printer.
105 StringBuffer _buff;
106
107 /// Current indentation, which can be updated from outside this class.
108 int indent;
109
110 /// Item used to indicate that the following item is copied from the original
111 /// source code, and hence we should preserve source-maps on every new line.
112 static final _ORIGINAL = new Object();
113
114 NestedPrinter([this.indent = 0]);
115
116 /// Adds [object] to this printer. [object] can be a [String],
117 /// [NestedPrinter], or anything implementing [NestedItem]. If [object] is a
118 /// [String], the value is appended directly, without doing any formatting
119 /// changes. If you wish to add a line of code with automatic indentation, use
120 /// [addLine] instead. [NestedPrinter]s and [NestedItem]s are not processed
121 /// until [build] gets called later on. We ensure that [build] emits every
122 /// object in the order that they were added to this printer.
123 ///
124 /// The [location] and [span] parameters indicate the corresponding source map
125 /// location of [object] in the original input. Only one, [location] or
126 /// [span], should be provided at a time.
127 ///
128 /// Indicate [isOriginal] when [object] is copied directly from the user code.
129 /// Setting [isOriginal] will make this printer propagate source map locations
130 /// on every line-break.
131 void add(object, {Location location, Span span, bool isOriginal: false}) {
132 if (object is! String || location != null || span != null || isOriginal) {
133 _flush();
134 assert(location == null || span == null);
135 if (location != null) _items.add(location);
136 if (span != null) _items.add(span);
137 if (isOriginal) _items.add(_ORIGINAL);
138 }
139
140 if (object is String) {
141 _appendString(object);
142 } else {
143 _items.add(object);
144 }
145 }
146
147 /// Append `2 * indent` spaces to this printer.
148 void insertIndent() => _indent(indent);
149
150 /// Add a [line], autoindenting to the current value of [indent]. Note,
151 /// indentation is not inferred from the contents added to this printer. If a
152 /// line starts or ends an indentation block, you need to also update [indent]
153 /// accordingly. Also, indentation is not adapted for nested printers. If
154 /// you add a [NestedPrinter] to this printer, its indentation is set
155 /// separately and will not include any the indentation set here.
156 ///
157 /// The [location] and [span] parameters indicate the corresponding source map
158 /// location of [object] in the original input. Only one, [location] or
159 /// [span], should be provided at a time.
160 void addLine(String line, {Location location, Span span}) {
161 if (location != null || span != null) {
162 _flush();
163 assert(location == null || span == null);
164 if (location != null) _items.add(location);
165 if (span != null) _items.add(span);
166 }
167 if (line == null) return;
168 if (line != '') {
169 // We don't indent empty lines.
170 _indent(indent);
171 _appendString(line);
172 }
173 _appendString('\n');
174 }
175
176 /// Appends a string merging it with any previous strings, if possible.
177 void _appendString(String s) {
178 if (_buff == null) _buff = new StringBuffer();
179 _buff.write(s);
180 }
181
182 /// Adds all of the current [_buff] contents as a string item.
183 void _flush() {
184 if (_buff != null) {
185 _items.add(_buff.toString());
186 _buff = null;
187 }
188 }
189
190 void _indent(int indent) {
191 for (int i = 0; i < indent; i++) _appendString(' ');
192 }
193
194 /// Returns a string representation of all the contents appended to this
195 /// printer, including source map location tokens.
196 String toString() {
197 _flush();
198 return (new StringBuffer()..writeAll(_items)).toString();
199 }
200
201 /// [Printer] used during the last call to [build], if any.
202 Printer printer;
203
204 /// Returns the text produced after calling [build].
205 String get text => printer.text;
206
207 /// Returns the source-map information produced after calling [build].
208 String get map => printer.map;
209
210 /// Builds the output of this printer and source map information. After
211 /// calling this function, you can use [text] and [map] to retrieve the
212 /// geenrated code and source map information, respectively.
213 void build(String filename) {
214 writeTo(printer = new Printer(filename));
215 }
216
217 /// Implements the [NestedItem] interface.
218 void writeTo(Printer printer) {
219 _flush();
220 bool propagate = false;
221 for (var item in _items) {
222 if (item is NestedItem) {
223 item.writeTo(printer);
224 } else if (item is String) {
225 printer.add(item, projectMarks: propagate);
226 propagate = false;
227 } else if (item is Location || item is Span) {
228 printer.mark(item);
229 } else if (item == _ORIGINAL) {
230 // we insert booleans when we are about to quote text that was copied
231 // from the original source. In such case, we will propagate marks on
232 // every new-line.
233 propagate = true;
234 } else {
235 throw new UnsupportedError('Unknown item type: $item');
236 }
237 }
238 }
239 }
240
241 /// An item added to a [NestedPrinter].
242 abstract class NestedItem {
243 /// Write the contents of this item into [printer].
244 void writeTo(Printer printer);
245 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698