blob: c3465e8783cec69dd3ac6deea2eea9a8d98de952 [file] [log] [blame]
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
part of dart2js;
class CodeBuffer implements StringBuffer {
StringBuffer buffer;
List<CodeBufferMarker> markers;
int lastBufferOffset = 0;
int mappedRangeCounter = 0;
CodeBuffer()
: buffer = new StringBuffer(),
markers = new List<CodeBufferMarker>();
int get length => buffer.length;
bool get isEmpty {
return buffer.isEmpty;
}
/**
* Converts [object] to a string and adds it to the buffer. If [object] is a
* [CodeBuffer], adds its markers to [markers].
*/
CodeBuffer add(var object) {
if (object is CodeBuffer) {
return addBuffer(object);
}
if (mappedRangeCounter == 0) setSourceLocation(null);
buffer.add(object.toString());
return this;
}
CodeBuffer addBuffer(CodeBuffer other) {
if (other.markers.length > 0) {
CodeBufferMarker firstMarker = other.markers[0];
int offsetDelta =
buffer.length + firstMarker.offsetDelta - lastBufferOffset;
markers.add(new CodeBufferMarker(offsetDelta,
firstMarker.sourcePosition));
for (int i = 1; i < other.markers.length; ++i) {
markers.add(other.markers[i]);
}
lastBufferOffset = buffer.length + other.lastBufferOffset;
}
buffer.add(other.getText());
}
CodeBuffer addAll(Iterable<Object> iterable) {
for (Object obj in iterable) {
add(obj);
}
return this;
}
CodeBuffer addCharCode(int charCode) {
return add(new String.fromCharCodes([charCode]));
}
CodeBuffer clear() {
buffer.clear();
markers.clear();
lastBufferOffset = 0;
return this;
}
String toString() {
throw "Don't use CodeBuffer.toString() since it drops sourcemap data.";
}
String getText() {
return buffer.toString();
}
void beginMappedRange() {
++mappedRangeCounter;
}
void endMappedRange() {
assert(mappedRangeCounter > 0);
--mappedRangeCounter;
}
void setSourceLocation(var sourcePosition) {
int offsetDelta = buffer.length - lastBufferOffset;
markers.add(new CodeBufferMarker(offsetDelta, sourcePosition));
lastBufferOffset = buffer.length;
}
void forEachSourceLocation(void f(int targetOffset, var sourcePosition)) {
int targetOffset = 0;
markers.forEach((marker) {
targetOffset += marker.offsetDelta;
f(targetOffset, marker.sourcePosition);
});
}
}
class CodeBufferMarker {
final int offsetDelta;
final sourcePosition;
CodeBufferMarker(this.offsetDelta, this.sourcePosition);
}