| // 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; |
| } |
| |
| CodeBuffer add(var object) { |
| write(object); |
| return this; |
| } |
| /** |
| * Converts [object] to a string and adds it to the buffer. If [object] is a |
| * [CodeBuffer], adds its markers to [markers]. |
| */ |
| CodeBuffer write(var object) { |
| if (object is CodeBuffer) { |
| return addBuffer(object); |
| } |
| if (mappedRangeCounter == 0) setSourceLocation(null); |
| buffer.write(object); |
| return this; |
| } |
| |
| CodeBuffer writeAll(Iterable<Object> objects) { |
| for (var object in objects) { |
| write(object); |
| } |
| return this; |
| } |
| |
| CodeBuffer writeln(var object) { |
| return write(object).write("\n"); |
| } |
| |
| 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.write(other.getText()); |
| return this; |
| } |
| |
| CodeBuffer addAll(Iterable<Object> iterable) => writeAll(iterable); |
| |
| CodeBuffer addCharCode(int charCode) => writeCharCode(charCode); |
| |
| CodeBuffer writeCharCode(int charCode) { |
| return write(new String.fromCharCodes([charCode])); |
| } |
| |
| CodeBuffer clear() { |
| buffer = new StringBuffer(); |
| 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); |
| } |