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

Unified Diff: pkg/analyzer/lib/src/services/writer.dart

Issue 132383002: Line-breaking plumbing and bits and pieces. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 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/analyzer/lib/src/services/formatter_impl.dart ('k') | pkg/analyzer/test/services/formatter_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/services/writer.dart
===================================================================
--- pkg/analyzer/lib/src/services/writer.dart (revision 31664)
+++ pkg/analyzer/lib/src/services/writer.dart (working copy)
@@ -7,13 +7,13 @@
class Line {
- final int lineLength;
final tokens = <LineToken>[];
final bool useTabs;
final int spacesPerIndent;
+ final LinePrinter printer;
- Line({indent: 0, this.lineLength: 80, this.useTabs: false,
- this.spacesPerIndent: 2}) {
+ Line({indent: 0, this.useTabs: false, this.spacesPerIndent: 2,
+ this.printer: const SimpleLinePrinter()}) {
if (indent > 0) {
_indent(indent);
}
@@ -23,9 +23,9 @@
addSpaces(1);
}
- void addSpaces(int n) {
+ void addSpaces(int n, {breakWeight: DEFAULT_SPACE_WEIGHT}) {
if (n > 0) {
- tokens.add(new SpaceToken(n));
+ tokens.add(new SpaceToken(n, breakWeight: breakWeight));
}
}
@@ -39,29 +39,161 @@
tokens.add(useTabs ? new TabToken(n) : new SpaceToken(n * spacesPerIndent));
}
- String toString() {
+ String toString() => printer.printLine(this);
+
+}
+
+
+/// Base class for line printers
+abstract class LinePrinter {
+
+ const LinePrinter();
+
+ /// Convert this [line] to a [String] representation.
+ String printLine(Line line);
+}
+
+
+/// A simple line breaking [LinePrinter]
+class SimpleLineBreaker extends LinePrinter {
+
+ final chunks = <Chunk>[];
+ final int maxLength;
+
+ SimpleLineBreaker(this.maxLength);
+
+ String printLine(Line line) {
+ //TODO(pquitslund): implement
+ }
+
+ List<Chunk> breakLine(Line line) {
Brian Wilkerson 2014/01/09 19:29:24 Try as I might, I don't understand how this method
pquitslund 2014/01/09 23:04:12 Ah yes. 'tent' was short-hand for 'tentative'. A
+ var chunks = <Chunk>[];
+ var current = new Chunk(maxLength: maxLength);
+ var tent = new Chunk(maxLength: maxLength);
+
+ line.tokens.forEach((tok) {
+
+ if (goodStart(tok, tent)) {
+ if (current.fits(tent)) {
+ current.add(tent);
+ } else {
+ if (current.length > 0) {
+ chunks.add(current);
+ }
+ current = tent;
+ }
+ tent = new Chunk(start: tok, maxLength: maxLength - current.length);
+ } else {
+ if (tent.fits(tok)) {
+ tent.add(tok);
+ } else {
+ current.add(tent);
+ if (current.length > 0) {
+ chunks.add(current);
+ current = new Chunk(maxLength: maxLength);
+ }
+ tent = new Chunk(maxLength: maxLength);
+ tent.add(tok);
+ }
+ }
+
+ });
+
+ current.add(tent);
+ if (current.length > 0) {
+ chunks.add(current);
+ }
+ return chunks;
+ }
+
+ bool goodStart(LineToken tok, Chunk tent) =>
+ tok is SpaceToken && tok.breakWeight >= tent.start.breakWeight;
+
+}
+
+
+/// Special token indicating a line start
+final LINE_START = new SpaceToken(0);
+
+const DEFAULT_SPACE_WEIGHT = -1;
+
+/// Simple non-breaking printer
+class SimpleLinePrinter extends LinePrinter {
+
+ const SimpleLinePrinter();
+
+ String printLine(Line line) {
var buffer = new StringBuffer();
- tokens.forEach((tok) => buffer.write(tok.toString()));
+ line.tokens.forEach((tok) => buffer.write(tok.toString()));
return buffer.toString();
}
}
-class LineToken {
+/// Describes a piece of text in a [Line].
+abstract class LineText {
+ int get length;
+ void addTo(Chunk chunk);
+}
+
+/// A working piece of text used in calculating line breaks
+class Chunk implements LineText {
+
+ final buffer = new StringBuffer();
+
+ int maxLength;
+ SpaceToken start;
+
+ Chunk({this.start, this.maxLength}) {
+ if (start == null) {
+ start = LINE_START;
+ }
+ }
+
+ bool fits(LineText text) => length + text.length < maxLength;
+
+ int get length => start.value.length + buffer.length;
+
+ void add(LineText text) {
+ text.addTo(this);
+ }
+
+ String toString() => buffer.toString().trim();
+
+ void addTo(Chunk chunk) {
+ chunk.buffer.write(start.value);
+ chunk.buffer.write(buffer.toString());
+ }
+}
+
+
+class LineToken implements LineText {
+
final String value;
LineToken(this.value);
String toString() => value;
+
+ int get length => value.length;
+
+ void addTo(Chunk chunk) {
+ chunk.buffer.write(value);
+ }
}
+
class SpaceToken extends LineToken {
- SpaceToken(int n) : super(getSpaces(n));
+ final int breakWeight;
+
+ SpaceToken(int n, {this.breakWeight: DEFAULT_SPACE_WEIGHT}) :
+ super(getSpaces(n));
}
+
class TabToken extends LineToken {
TabToken(int n) : super(getTabs(n));
@@ -74,28 +206,30 @@
}
-
class SourceWriter {
- final StringBuffer buffer = new StringBuffer();
+ final buffer = new StringBuffer();
Brian Wilkerson 2014/01/09 19:29:24 Not sure why you deleted the type. Because this is
pquitslund 2014/01/09 23:04:12 That was overzealous on my part. Added back.
Line currentLine;
final String lineSeparator;
int indentCount = 0;
-
+
+ LinePrinter linePrinter;
LineToken _lastToken;
-
- SourceWriter({this.indentCount: 0, this.lineSeparator: NEW_LINE}) {
- currentLine = new Line(indent: indentCount);
+
+ SourceWriter({this.indentCount: 0, this.lineSeparator: NEW_LINE,
+ int maxLineLength: 80}) {
+ linePrinter = new SimpleLinePrinter();
+ currentLine = new Line(indent: indentCount, printer: linePrinter);
}
LineToken get lastToken => _lastToken;
-
+
_addToken(LineToken token) {
_lastToken = token;
currentLine.addToken(token);
}
-
+
void indent() {
++indentCount;
}
@@ -106,7 +240,7 @@
}
_addToken(new NewlineToken(this.lineSeparator));
buffer.write(currentLine.toString());
- currentLine = new Line(indent: indentCount);
+ currentLine = new Line(indent: indentCount, printer: linePrinter);
}
void newlines(int num) {
@@ -118,24 +252,24 @@
void print(x) {
_addToken(new LineToken(x));
}
-
+
void println(String s) {
print(s);
newline();
}
-
+
void space() {
spaces(1);
}
- void spaces(n) {
- currentLine.addSpaces(n);
+ void spaces(n, {breakWeight: null}) {
+ currentLine.addSpaces(n, breakWeight: breakWeight);
}
-
+
void unindent() {
--indentCount;
}
-
+
String toString() {
var source = new StringBuffer(buffer.toString());
if (!currentLine.isWhitespace()) {
« no previous file with comments | « pkg/analyzer/lib/src/services/formatter_impl.dart ('k') | pkg/analyzer/test/services/formatter_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698