Index: lib/src/line_writer.dart |
diff --git a/lib/src/line_writer.dart b/lib/src/line_writer.dart |
index 0477e2f9966fd9baedd14840c0f3a0fd67bdc4aa..3169aaab36761b73af752edc129261c338e3d2be 100644 |
--- a/lib/src/line_writer.dart |
+++ b/lib/src/line_writer.dart |
@@ -74,7 +74,7 @@ class LineWriter { |
/// The nested stack of spans that are currently being written. |
final _openSpans = <Span>[]; |
- /// All of the spans that have been created, open and closed. |
+ /// All of the spans that have been created and closed. |
final _spans = <Span>[]; |
/// The current indentation and nesting levels. |
@@ -371,6 +371,10 @@ class LineWriter { |
/// Ends the innermost span. |
void endSpan() { |
var span = _openSpans.removeLast(); |
+ |
+ // If the span was discarded while it was still open, just forget about it. |
+ if (span == null) return; |
+ |
span.close(_currentChunkIndex); |
// A span that just covers a single chunk can't be split anyway. |
@@ -381,8 +385,9 @@ class LineWriter { |
/// Starts a new [Multisplit]. |
/// |
/// Returns the [SplitParam] for the multisplit. |
- SplitParam startMultisplit({bool separable}) { |
- var multisplit = new Multisplit(_currentChunkIndex, separable: separable); |
+ SplitParam startMultisplit({bool separable, int cost}) { |
+ var multisplit = new Multisplit(_currentChunkIndex, |
+ separable: separable, cost: cost); |
_multisplits.add(multisplit); |
return multisplit.param; |
@@ -423,7 +428,7 @@ class LineWriter { |
/// In particular, it's easy for the visitor to know that collections with a |
/// large number of items must split. Doing that early avoids crashing the |
/// splitter when it tries to recurse on huge collection literals. |
- void preemptMultisplits() => _splitMultisplits(); |
+ void preemptMultisplits() => _handleHardSplit(); |
/// Increases the level of expression nesting. |
/// |
@@ -622,7 +627,7 @@ class LineWriter { |
_chunks.last.applySplit(indent, nesting, param, |
isDouble: isDouble, spaceWhenUnsplit: spaceWhenUnsplit); |
- if (_chunks.last.isHardSplit) _splitMultisplits(); |
+ if (_chunks.last.isHardSplit) _handleHardSplit(); |
} |
/// Writes [text] to either the current chunk or a new one if the current |
@@ -677,11 +682,6 @@ class LineWriter { |
void _completeLine(int length) { |
assert(_chunks.isNotEmpty); |
- if (debugFormatter) { |
- dumpChunks(_chunks.take(length).toList()); |
- print(_spans.join("\n")); |
- } |
- |
// Write the newlines required by the previous line. |
for (var i = 0; i < _bufferedNewlines; i++) { |
_buffer.write(_formatter.lineEnding); |
@@ -697,6 +697,11 @@ class LineWriter { |
spans = spans.where((span) => span.start <= length).toList(); |
} |
+ if (debugFormatter) { |
+ dumpChunks(chunks); |
+ print(spans.join("\n")); |
+ } |
+ |
var splitter = new LineSplitter(_formatter.lineEnding, _formatter.pageWidth, |
chunks, spans, _beginningIndent); |
var selection = splitter.apply(_buffer); |
@@ -705,13 +710,21 @@ class LineWriter { |
if (selection[1] != null) _selectionLength = selection[1] - _selectionStart; |
} |
- /// Handles multisplits when a hard line occurs. |
+ /// Handles open multisplits and spans when a hard line occurs. |
/// |
/// Any active separable multisplits will get split in two at this point. |
/// Other multisplits are forced into the "hard" state. All of their previous |
/// splits are turned into explicit hard splits and any new splits for that |
/// multisplit become hard splits too. |
- void _splitMultisplits() { |
+ /// |
+ /// All open spans get discarded since they will never be satisfied. |
+ void _handleHardSplit() { |
+ // Discard all open spans. We don't remove them from the stack so that we |
+ // can still correctly count later calls to endSpan(). |
+ for (var i = 0; i < _openSpans.length; i++) { |
+ _openSpans[i] = null; |
+ } |
+ |
if (_multisplits.isEmpty) return; |
var splitParams = new Set(); |