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

Side by Side Diff: pkg/compiler/lib/src/io/code_output.dart

Issue 812233004: Add CodeOutput to prepare for emission without in-memory buffers. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Reinsert return. Created 5 years, 11 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
« no previous file with comments | « pkg/compiler/lib/src/dart2jslib.dart ('k') | pkg/compiler/lib/src/io/source_map_builder.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 library dart2js.code_output;
6
7 import 'dart:async';
8
9 import '../source_file.dart';
10
11 import 'source_map_builder.dart';
12
13 class CodeOutputMarker {
14 final int offsetDelta;
15 final SourceFileLocation sourcePosition;
16
17 CodeOutputMarker(this.offsetDelta, this.sourcePosition);
18 }
19
20 abstract class CodeOutput {
21 List<CodeOutputMarker> markers = new List<CodeOutputMarker>();
22
23 int lastBufferOffset = 0;
24 int mappedRangeCounter = 0;
25
26 int get length;
27
28 void _writeInternal(String text);
29
30 /// Converts [object] to a string and adds it to the buffer. If [object] is a
31 /// [CodeBuffer], adds its markers to [markers].
32 void write(var object) {
33 if (object is CodeBuffer) {
34 addBuffer(object);
35 return;
36 }
37 if (mappedRangeCounter == 0) setSourceLocation(null);
38 _writeInternal(object);
39 }
40
41 void addBuffer(CodeBuffer other) {
42 if (other.markers.length > 0) {
43 CodeOutputMarker firstMarker = other.markers[0];
44 int offsetDelta =
45 length + firstMarker.offsetDelta - lastBufferOffset;
46 markers.add(new CodeOutputMarker(offsetDelta,
47 firstMarker.sourcePosition));
48 for (int i = 1; i < other.markers.length; ++i) {
49 markers.add(other.markers[i]);
50 }
51 lastBufferOffset = length + other.lastBufferOffset;
52 }
53 _writeInternal(other.getText());
54 }
55
56 void beginMappedRange() {
57 ++mappedRangeCounter;
58 }
59
60 void endMappedRange() {
61 assert(mappedRangeCounter > 0);
62 --mappedRangeCounter;
63 }
64
65 void setSourceLocation(SourceFileLocation sourcePosition) {
66 if (sourcePosition == null) {
67 if (markers.length > 0 && markers.last.sourcePosition == null) return;
68 }
69 int offsetDelta = length - lastBufferOffset;
70 markers.add(new CodeOutputMarker(offsetDelta, sourcePosition));
71 lastBufferOffset = length;
72 }
73
74 void forEachSourceLocation(void f(int targetOffset, var sourcePosition)) {
75 int targetOffset = 0;
76 markers.forEach((marker) {
77 targetOffset += marker.offsetDelta;
78 f(targetOffset, marker.sourcePosition);
79 });
80 }
81 }
82
83 /// [CodeOutput] using a [StringBuffer] as backend.
84 class CodeBuffer extends CodeOutput implements StringBuffer {
85 StringBuffer buffer = new StringBuffer();
86
87 @override
88 void _writeInternal(String text) {
89 buffer.write(text);
90 }
91
92 @override
93 int get length => buffer.length;
94
95 @override
96 bool get isEmpty => buffer.isEmpty;
97
98 @override
99 bool get isNotEmpty => buffer.isNotEmpty;
100
101 @override
102 void writeAll(Iterable<Object> objects, [String separator = ""]) {
103 Iterator iterator = objects.iterator;
104 if (!iterator.moveNext()) return;
105 if (separator.isEmpty) {
106 do {
107 write(iterator.current);
108 } while (iterator.moveNext());
109 } else {
110 write(iterator.current);
111 while (iterator.moveNext()) {
112 write(separator);
113 write(iterator.current);
114 }
115 }
116 }
117
118 @override
119 void writeln([var object = ""]) {
120 write(object);
121 write("\n");
122 }
123
124 @override
125 void writeCharCode(int charCode) {
126 buffer.writeCharCode(charCode);
127 }
128
129 @override
130 void clear() {
131 buffer = new StringBuffer();
132 markers.clear();
133 lastBufferOffset = 0;
134 }
135
136 String toString() {
137 throw "Don't use CodeBuffer.toString() since it drops sourcemap data.";
138 }
139
140 String getText() {
141 return buffer.toString();
142 }
143 }
144
145 /// [CodeOutput] using a [CompilationOutput] as backend.
146 class StreamCodeOutput extends CodeOutput {
147 int length = 0;
148 final EventSink<String> output;
149
150 StreamCodeOutput(this.output);
151
152 @override
153 void _writeInternal(String text) {
154 output.add(text);
155 length += text.length;
156 }
157
158 void close() {
159 output.close();
160 }
161 }
162
163 /// [StreamCodeSink] that collects line information.
164 class LineColumnCodeOutput extends StreamCodeOutput
165 implements LineColumnProvider {
166 int lastLineStart = 0;
167 List<int> lineStarts = <int>[0];
168
169 LineColumnCodeOutput(EventSink<String> output) : super(output);
170
171 @override
172 void _writeInternal(String text) {
173 int offset = lastLineStart;
174 int index = 0;
175 while (index < text.length) {
176 // Unix uses '\n' and Windows uses '\r\n', so this algorithm works for
177 // both platforms.
178 index = text.indexOf('\n', index) + 1;
179 if (index <= 0) break;
180 lastLineStart = offset + index;
181 lineStarts.add(lastLineStart);
182 }
183 super._writeInternal(text);
184 }
185
186 @override
187 int getLine(int offset) {
188 List<int> starts = lineStarts;
189 if (offset < 0|| starts.last <= offset) {
190 throw 'bad position #$offset in buffer with length ${length}.';
191 }
192 int first = 0;
193 int count = starts.length;
194 while (count > 1) {
195 int step = count ~/ 2;
196 int middle = first + step;
197 int lineStart = starts[middle];
198 if (offset < lineStart) {
199 count = step;
200 } else {
201 first = middle;
202 count -= step;
203 }
204 }
205 return first;
206 }
207
208 @override
209 int getColumn(int line, int offset) {
210 return offset - lineStarts[line];
211 }
212
213 @override
214 void close() {
215 lineStarts.add(length);
216 super.close();
217 }
218 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/dart2jslib.dart ('k') | pkg/compiler/lib/src/io/source_map_builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698