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

Unified Diff: pkg/compiler/lib/src/io/code_output.dart

Issue 830703004: Emit to StreamCodeOutput instead of CodeBuffer. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comments 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/lib/src/hash/sha1.dart ('k') | pkg/compiler/lib/src/io/line_column_provider.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/io/code_output.dart
diff --git a/pkg/compiler/lib/src/io/code_output.dart b/pkg/compiler/lib/src/io/code_output.dart
index f7f1c9b0a3aba69b84e6a05b4002a4ef77951faa..bd97af021575b6eaff1e5e8ef9958979be88fd77 100644
--- a/pkg/compiler/lib/src/io/code_output.dart
+++ b/pkg/compiler/lib/src/io/code_output.dart
@@ -6,8 +6,6 @@ library dart2js.code_output;
import 'dart:async';
-import '../source_file.dart';
-
import 'source_map_builder.dart';
class CodeOutputMarker {
@@ -17,27 +15,55 @@ class CodeOutputMarker {
CodeOutputMarker(this.offsetDelta, this.sourcePosition);
}
+abstract class CodeOutputListener {
+ void onText(String text);
+ void onDone(int length);
+}
+
abstract class CodeOutput {
- List<CodeOutputMarker> markers = new List<CodeOutputMarker>();
+ /// Write [text] to this output.
+ ///
+ /// If the output is closed, a [StateError] is thrown.
+ void add(String text);
+
+ /// Adds the content of [buffer] to the output and adds its markers to
+ /// [markers].
+ ///
+ /// If the output is closed, a [StateError] is thrown.
+ void addBuffer(CodeBuffer buffer);
+
+ /// Returns the number of characters currently write to this output.
+ int get length;
+
+ /// Returns `true` if this output has been closed.
+ bool get isClosed;
+
+ /// Closes the output. Further writes will cause a [StateError].
+ void close();
+
+ /// Applies [f] to every marker in this output.
+ void forEachSourceLocation(void f(int targetOffset,
+ SourceFileLocation sourceLocation));
+}
+abstract class AbstractCodeOutput extends CodeOutput {
+ List<CodeOutputMarker> markers = new List<CodeOutputMarker>();
int lastBufferOffset = 0;
int mappedRangeCounter = 0;
+ bool isClosed = false;
- int get length;
-
- void _writeInternal(String text);
+ void _addInternal(String text);
- /// Converts [object] to a string and adds it to the buffer. If [object] is a
- /// [CodeBuffer], adds its markers to [markers].
- void write(var object) {
- if (object is CodeBuffer) {
- addBuffer(object);
- return;
+ @override
+ void add(String text) {
+ if (isClosed) {
+ throw new StateError("Code output is closed. Trying to write '$text'.");
}
if (mappedRangeCounter == 0) setSourceLocation(null);
- _writeInternal(object);
+ _addInternal(text);
}
+ @override
void addBuffer(CodeBuffer other) {
if (other.markers.length > 0) {
CodeOutputMarker firstMarker = other.markers[0];
@@ -50,7 +76,10 @@ abstract class CodeOutput {
}
lastBufferOffset = length + other.lastBufferOffset;
}
- _writeInternal(other.getText());
+ if (!other.isClosed) {
+ other.close();
+ }
+ _addInternal(other.getText());
}
void beginMappedRange() {
@@ -78,141 +107,58 @@ abstract class CodeOutput {
f(targetOffset, marker.sourcePosition);
});
}
+
+ void close() {
+ if (isClosed) {
+ throw new StateError("Code output is already closed.");
+ }
+ isClosed = true;
+ }
}
/// [CodeOutput] using a [StringBuffer] as backend.
-class CodeBuffer extends CodeOutput implements StringBuffer {
+class CodeBuffer extends AbstractCodeOutput {
StringBuffer buffer = new StringBuffer();
@override
- void _writeInternal(String text) {
+ void _addInternal(String text) {
buffer.write(text);
}
@override
int get length => buffer.length;
- @override
- bool get isEmpty => buffer.isEmpty;
-
- @override
- bool get isNotEmpty => buffer.isNotEmpty;
-
- @override
- void writeAll(Iterable<Object> objects, [String separator = ""]) {
- Iterator iterator = objects.iterator;
- if (!iterator.moveNext()) return;
- if (separator.isEmpty) {
- do {
- write(iterator.current);
- } while (iterator.moveNext());
- } else {
- write(iterator.current);
- while (iterator.moveNext()) {
- write(separator);
- write(iterator.current);
- }
- }
- }
-
- @override
- void writeln([var object = ""]) {
- write(object);
- write("\n");
- }
-
- @override
- void writeCharCode(int charCode) {
- buffer.writeCharCode(charCode);
- }
-
- @override
- void clear() {
- buffer = new StringBuffer();
- markers.clear();
- lastBufferOffset = 0;
+ String getText() {
+ return buffer.toString();
}
String toString() {
throw "Don't use CodeBuffer.toString() since it drops sourcemap data.";
}
-
- String getText() {
- return buffer.toString();
- }
}
/// [CodeOutput] using a [CompilationOutput] as backend.
-class StreamCodeOutput extends CodeOutput {
+class StreamCodeOutput extends AbstractCodeOutput {
int length = 0;
final EventSink<String> output;
+ final List<CodeOutputListener> _listeners;
- StreamCodeOutput(this.output);
+ StreamCodeOutput(this.output, [this._listeners]);
@override
- void _writeInternal(String text) {
+ void _addInternal(String text) {
output.add(text);
length += text.length;
- }
-
- void close() {
- output.close();
- }
-}
-
-/// [StreamCodeSink] that collects line information.
-class LineColumnCodeOutput extends StreamCodeOutput
- implements LineColumnProvider {
- int lastLineStart = 0;
- List<int> lineStarts = <int>[0];
-
- LineColumnCodeOutput(EventSink<String> output) : super(output);
-
- @override
- void _writeInternal(String text) {
- int offset = lastLineStart;
- int index = 0;
- while (index < text.length) {
- // Unix uses '\n' and Windows uses '\r\n', so this algorithm works for
- // both platforms.
- index = text.indexOf('\n', index) + 1;
- if (index <= 0) break;
- lastLineStart = offset + index;
- lineStarts.add(lastLineStart);
+ if (_listeners != null) {
+ _listeners.forEach((listener) => listener.onText(text));
}
- super._writeInternal(text);
}
- @override
- int getLine(int offset) {
- List<int> starts = lineStarts;
- if (offset < 0|| starts.last <= offset) {
- throw 'bad position #$offset in buffer with length ${length}.';
- }
- int first = 0;
- int count = starts.length;
- while (count > 1) {
- int step = count ~/ 2;
- int middle = first + step;
- int lineStart = starts[middle];
- if (offset < lineStart) {
- count = step;
- } else {
- first = middle;
- count -= step;
- }
- }
- return first;
- }
-
- @override
- int getColumn(int line, int offset) {
- return offset - lineStarts[line];
- }
-
- @override
void close() {
- lineStarts.add(length);
+ output.close();
super.close();
+ if (_listeners != null) {
+ _listeners.forEach((listener) => listener.onDone(length));
+ }
}
}
« no previous file with comments | « pkg/compiler/lib/src/hash/sha1.dart ('k') | pkg/compiler/lib/src/io/line_column_provider.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698