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

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: 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 abstract class CodeOutput {
14 List<CodeOutputMarker> markers = new List<CodeOutputMarker>();
15
16 int lastBufferOffset = 0;
17 int mappedRangeCounter = 0;
18
19 int get length;
20
21 void writeInternal(String text);
floitsch 2014/12/29 18:36:35 private?
Johnni Winther 2014/12/30 11:05:18 Done.
22
23 /// Converts [object] to a string and adds it to the buffer. If [object] is a
24 /// [CodeBuffer], adds its markers to [markers].
25 void write(var object) {
26 if (object is CodeBuffer) {
27 return addBuffer(object);
floitsch 2014/12/29 18:36:35 Don't return from a void function. (even if the ta
Johnni Winther 2014/12/30 11:05:18 Done.
28 }
29 if (mappedRangeCounter == 0) setSourceLocation(null);
30 writeInternal(object);
31 }
32
33 void addBuffer(CodeBuffer other) {
34 if (other.markers.length > 0) {
35 CodeOutputMarker firstMarker = other.markers[0];
36 int offsetDelta =
37 length + firstMarker.offsetDelta - lastBufferOffset;
38 markers.add(new CodeOutputMarker(offsetDelta,
39 firstMarker.sourcePosition));
40 for (int i = 1; i < other.markers.length; ++i) {
41 markers.add(other.markers[i]);
42 }
43 lastBufferOffset = length + other.lastBufferOffset;
44 }
45 writeInternal(other.getText());
46 }
47
48 void beginMappedRange() {
49 ++mappedRangeCounter;
50 }
51
52 void endMappedRange() {
53 assert(mappedRangeCounter > 0);
54 --mappedRangeCounter;
55 }
56
57 void setSourceLocation(SourceFileLocation sourcePosition) {
58 if (sourcePosition == null) {
59 if (markers.length > 0 && markers.last.sourcePosition == null) return;
60 }
61 int offsetDelta = length - lastBufferOffset;
62 markers.add(new CodeOutputMarker(offsetDelta, sourcePosition));
63 lastBufferOffset = length;
64 }
65
66 void forEachSourceLocation(void f(int targetOffset, var sourcePosition)) {
67 int targetOffset = 0;
68 markers.forEach((marker) {
69 targetOffset += marker.offsetDelta;
70 f(targetOffset, marker.sourcePosition);
71 });
72 }
73 }
74
75 /// [CodeOutput] using a [StringBuffer] as backend.
76 class CodeBuffer extends CodeOutput implements StringBuffer {
77 StringBuffer buffer = new StringBuffer();
78
79 void writeInternal(String text) {
80 buffer.write(text);
81 }
82
83 int get length => buffer.length;
84
85 bool get isEmpty => buffer.isEmpty;
86
87 bool get isNotEmpty => buffer.isNotEmpty;
88
89 void writeAll(Iterable<Object> objects, [String separator = ""]) {
90 Iterator iterator = objects.iterator;
91 if (!iterator.moveNext()) return;
92 if (separator.isEmpty) {
93 do {
94 write(iterator.current);
95 } while (iterator.moveNext());
96 } else {
97 write(iterator.current);
98 while (iterator.moveNext()) {
99 write(separator);
100 write(iterator.current);
101 }
102 }
103 }
104
105 void writeln([var object = ""]) {
106 write(object);
107 write("\n");
108 }
109
110 void writeCharCode(int charCode) {
111 buffer.writeCharCode(charCode);
112 }
113
114 void clear() {
115 buffer = new StringBuffer();
116 markers.clear();
117 lastBufferOffset = 0;
118 }
119
120 String toString() {
121 throw "Don't use CodeBuffer.toString() since it drops sourcemap data.";
122 }
123
124 String getText() {
125 return buffer.toString();
126 }
127 }
128
129 /// [CodeOutput] using a [CompilationOutput] as backend.
130 class StreamCodeOutput extends CodeOutput {
131 int length = 0;
132 final EventSink<String> output;
133
134 StreamCodeOutput(this.output);
135
136 void writeInternal(String text) {
137 output.add(text);
138 length += text.length;
139 }
140
141 void close() {
142 output.close();
143 }
144 }
145
146 /// [StreamCodeSink] that collects line information.
147 class LineColumnCodeOutput extends StreamCodeOutput
148 implements LineColumnProvider {
149 int lastLineStart = 0;
150 List<int> lineStarts = <int>[0];
151
152 LineColumnCodeOutput(EventSink<String> output) : super(output);
153
154 @override
155 void writeInternal(String text) {
156 int offset = lastLineStart;
157 int index = 0;
158 while (index < text.length) {
159 // Unix uses '\n' and Windows uses '\r\n', so this algorithm works for
160 // both platforms.
161 index = text.indexOf('\n', index) + 1;
162 if (index <= 0) break;
163 lastLineStart = offset + index;
164 lineStarts.add(lastLineStart);
165 }
166 super.writeInternal(text);
167 }
168
169 int getLine(int offset) {
170 List<int> starts = lineStarts;
171 if (offset < 0|| starts.last <= offset) {
172 throw 'bad position #$offset in buffer with length ${length}.';
173 }
174 int first = 0;
175 int count = starts.length;
176 while (count > 1) {
177 int step = count ~/ 2;
178 int middle = first + step;
179 int lineStart = starts[middle];
180 if (offset < lineStart) {
181 count = step;
182 } else {
183 first = middle;
184 count -= step;
185 }
186 }
187 return first;
188 }
189
190 int getColumn(int line, int offset) {
191 return offset - lineStarts[line];
192 }
193
194 @override
195 void close() {
196 lineStarts.add(length);
197 super.close();
198 }
199 }
200
201 class CodeOutputMarker {
floitsch 2014/12/29 18:36:35 Move up?
Johnni Winther 2014/12/30 11:05:18 Done.
202 final int offsetDelta;
203 final SourceFileLocation sourcePosition;
204
205 CodeOutputMarker(this.offsetDelta, this.sourcePosition);
206 }
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