OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012, 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 part of dart2js; | |
6 | |
7 class CodeBuffer implements StringBuffer { | |
8 | |
9 StringBuffer buffer = new StringBuffer(); | |
10 List<CodeBufferMarker> markers = new List<CodeBufferMarker>(); | |
11 | |
12 int lastBufferOffset = 0; | |
13 int mappedRangeCounter = 0; | |
14 | |
15 CodeBuffer(); | |
16 | |
17 int get length => buffer.length; | |
18 bool get isEmpty => buffer.isEmpty; | |
19 bool get isNotEmpty => buffer.isNotEmpty; | |
20 | |
21 CodeBuffer add(var object) { | |
22 write(object); | |
23 return this; | |
24 } | |
25 /** | |
26 * Converts [object] to a string and adds it to the buffer. If [object] is a | |
27 * [CodeBuffer], adds its markers to [markers]. | |
28 */ | |
29 CodeBuffer write(var object) { | |
30 if (object is CodeBuffer) { | |
31 return addBuffer(object); | |
32 } | |
33 if (mappedRangeCounter == 0) setSourceLocation(null); | |
34 buffer.write(object); | |
35 return this; | |
36 } | |
37 | |
38 CodeBuffer writeAll(Iterable<Object> objects, [String separator = ""]) { | |
39 Iterator iterator = objects.iterator; | |
40 if (!iterator.moveNext()) return this; | |
41 if (separator.isEmpty) { | |
42 do { | |
43 write(iterator.current); | |
44 } while (iterator.moveNext()); | |
45 } else { | |
46 write(iterator.current); | |
47 while (iterator.moveNext()) { | |
48 write(separator); | |
49 write(iterator.current); | |
50 } | |
51 } | |
52 return this; | |
53 } | |
54 | |
55 CodeBuffer writeln([var object = ""]) { | |
56 return write(object).write("\n"); | |
57 } | |
58 | |
59 CodeBuffer addBuffer(CodeBuffer other) { | |
60 if (other.markers.length > 0) { | |
61 CodeBufferMarker firstMarker = other.markers[0]; | |
62 int offsetDelta = | |
63 buffer.length + firstMarker.offsetDelta - lastBufferOffset; | |
64 markers.add(new CodeBufferMarker(offsetDelta, | |
65 firstMarker.sourcePosition)); | |
66 for (int i = 1; i < other.markers.length; ++i) { | |
67 markers.add(other.markers[i]); | |
68 } | |
69 lastBufferOffset = buffer.length + other.lastBufferOffset; | |
70 } | |
71 buffer.write(other.getText()); | |
72 return this; | |
73 } | |
74 | |
75 CodeBuffer addAll(Iterable<Object> iterable) => writeAll(iterable); | |
76 | |
77 CodeBuffer writeCharCode(int charCode) { | |
78 buffer.writeCharCode(charCode); | |
79 return this; | |
80 } | |
81 | |
82 CodeBuffer clear() { | |
83 buffer = new StringBuffer(); | |
84 markers.clear(); | |
85 lastBufferOffset = 0; | |
86 return this; | |
87 } | |
88 | |
89 String toString() { | |
90 throw "Don't use CodeBuffer.toString() since it drops sourcemap data."; | |
91 } | |
92 | |
93 String getText() { | |
94 return buffer.toString(); | |
95 } | |
96 | |
97 void beginMappedRange() { | |
98 ++mappedRangeCounter; | |
99 } | |
100 | |
101 void endMappedRange() { | |
102 assert(mappedRangeCounter > 0); | |
103 --mappedRangeCounter; | |
104 } | |
105 | |
106 void setSourceLocation(var sourcePosition) { | |
107 if (sourcePosition == null) { | |
108 if (markers.length > 0 && markers.last.sourcePosition == null) return; | |
109 } | |
110 int offsetDelta = buffer.length - lastBufferOffset; | |
111 markers.add(new CodeBufferMarker(offsetDelta, sourcePosition)); | |
112 lastBufferOffset = buffer.length; | |
113 } | |
114 | |
115 void forEachSourceLocation(void f(int targetOffset, var sourcePosition)) { | |
116 int targetOffset = 0; | |
117 markers.forEach((marker) { | |
118 targetOffset += marker.offsetDelta; | |
119 f(targetOffset, marker.sourcePosition); | |
120 }); | |
121 } | |
122 } | |
123 | |
124 class CodeBufferMarker { | |
125 final int offsetDelta; | |
126 final sourcePosition; | |
127 | |
128 CodeBufferMarker(this.offsetDelta, this.sourcePosition); | |
129 } | |
OLD | NEW |