| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library dart_style.src.line_writer; | 5 library dart_style.src.line_writer; |
| 6 | 6 |
| 7 import 'chunk.dart'; | 7 import 'chunk.dart'; |
| 8 import 'dart_formatter.dart'; | 8 import 'dart_formatter.dart'; |
| 9 import 'debug.dart' as debug; | 9 import 'debug.dart' as debug; |
| 10 import 'line_splitting/line_splitter.dart'; | 10 import 'line_splitting/line_splitter.dart'; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 /// | 75 /// |
| 76 /// When we format the anonymous lambda, [column] will be 2, not 4. | 76 /// When we format the anonymous lambda, [column] will be 2, not 4. |
| 77 FormatResult formatBlock(Chunk chunk, int column) { | 77 FormatResult formatBlock(Chunk chunk, int column) { |
| 78 var key = new _BlockKey(chunk, column); | 78 var key = new _BlockKey(chunk, column); |
| 79 | 79 |
| 80 // Use the cached one if we have it. | 80 // Use the cached one if we have it. |
| 81 var cached = _blockCache[key]; | 81 var cached = _blockCache[key]; |
| 82 if (cached != null) return cached; | 82 if (cached != null) return cached; |
| 83 | 83 |
| 84 var writer = new LineWriter._( | 84 var writer = new LineWriter._( |
| 85 chunk.blockChunks, _lineEnding, pageWidth, column, _blockCache); | 85 chunk.block.chunks, _lineEnding, pageWidth, column, _blockCache); |
| 86 | 86 |
| 87 // TODO(rnystrom): Passing in an initial indent here is hacky. The | 87 // TODO(rnystrom): Passing in an initial indent here is hacky. The |
| 88 // LineWriter ensures all but the first chunk have a block indent, and this | 88 // LineWriter ensures all but the first chunk have a block indent, and this |
| 89 // handles the first chunk. Do something cleaner. | 89 // handles the first chunk. Do something cleaner. |
| 90 var result = writer.writeLines(Indent.block, flushLeft: chunk.flushLeft); | 90 var result = writer.writeLines(Indent.block, flushLeft: chunk.flushLeft); |
| 91 return _blockCache[key] = result; | 91 return _blockCache[key] = result; |
| 92 } | 92 } |
| 93 | 93 |
| 94 /// Takes all of the chunks and divides them into sublists and line splits | 94 /// Takes all of the chunks and divides them into sublists and line splits |
| 95 /// each list. | 95 /// each list. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 124 flushLeft: flushLeft); | 124 flushLeft: flushLeft); |
| 125 } | 125 } |
| 126 | 126 |
| 127 // Be a good citizen, end with a newline. | 127 // Be a good citizen, end with a newline. |
| 128 if (isCompilationUnit) _buffer.write(_lineEnding); | 128 if (isCompilationUnit) _buffer.write(_lineEnding); |
| 129 | 129 |
| 130 return new FormatResult( | 130 return new FormatResult( |
| 131 _buffer.toString(), totalCost, _selectionStart, _selectionEnd); | 131 _buffer.toString(), totalCost, _selectionStart, _selectionEnd); |
| 132 } | 132 } |
| 133 | 133 |
| 134 /// Takes the first [length] of the chunks with leading [indent], removes | 134 /// Takes the chunks from [start] to [end] with leading [indent], removes |
| 135 /// them, and runs the [LineSplitter] on them. | 135 /// them, and runs the [LineSplitter] on them. |
| 136 int _completeLine(int newlines, int indent, int start, int end, | 136 int _completeLine(int newlines, int indent, int start, int end, |
| 137 {bool flushLeft}) { | 137 {bool flushLeft}) { |
| 138 // Write the newlines required by the previous line. | 138 // Write the newlines required by the previous line. |
| 139 for (var j = 0; j < newlines; j++) { | 139 for (var j = 0; j < newlines; j++) { |
| 140 _buffer.write(_lineEnding); | 140 _buffer.write(_lineEnding); |
| 141 } | 141 } |
| 142 | 142 |
| 143 var chunks = _chunks.sublist(start, end); | 143 var chunks = _chunks.sublist(start, end); |
| 144 | 144 |
| 145 if (debug.traceLineWriter) { | 145 if (debug.traceLineWriter) { |
| 146 debug.log(debug.green("\nWriting:")); | 146 debug.log(debug.green("\nWriting:")); |
| 147 debug.dumpChunks(start, chunks); | 147 debug.dumpChunks(0, chunks); |
| 148 debug.log(); | 148 debug.log(); |
| 149 } | 149 } |
| 150 | 150 |
| 151 // Run the line splitter. | 151 // Run the line splitter. |
| 152 var splitter = new LineSplitter(this, chunks, _blockIndentation, indent, | 152 var splitter = new LineSplitter(this, chunks, _blockIndentation, indent, |
| 153 flushLeft: flushLeft); | 153 flushLeft: flushLeft); |
| 154 var splits = splitter.apply(); | 154 var splits = splitter.apply(); |
| 155 | 155 |
| 156 // Write the indentation of the first line. | 156 // Write the indentation of the first line. |
| 157 if (!flushLeft) { | 157 if (!flushLeft) { |
| 158 _buffer.write(" " * (indent + _blockIndentation)); | 158 _buffer.write(" " * (indent + _blockIndentation)); |
| 159 } | 159 } |
| 160 | 160 |
| 161 // Write each chunk with the appropriate splits between them. | 161 // Write each chunk with the appropriate splits between them. |
| 162 for (var i = 0; i < chunks.length; i++) { | 162 for (var i = 0; i < chunks.length; i++) { |
| 163 var chunk = chunks[i]; | 163 var chunk = chunks[i]; |
| 164 _writeChunk(chunk); | 164 _writeChunk(chunk); |
| 165 | 165 |
| 166 if (chunk.blockChunks.isNotEmpty) { | 166 if (chunk.isBlock) { |
| 167 if (!splits.shouldSplitAt(i)) { | 167 if (!splits.shouldSplitAt(i)) { |
| 168 // This block didn't split (which implies none of the child blocks | 168 // This block didn't split (which implies none of the child blocks |
| 169 // of that block split either, recursively), so write them all inline. | 169 // of that block split either, recursively), so write them all inline. |
| 170 _writeChunksUnsplit(chunk.blockChunks); | 170 _writeChunksUnsplit(chunk); |
| 171 } else { | 171 } else { |
| 172 // Include the formatted block contents. | 172 // Include the formatted block contents. |
| 173 var block = formatBlock(chunk, splits.getColumn(i)); | 173 var block = formatBlock(chunk, splits.getColumn(i)); |
| 174 | 174 |
| 175 // If this block contains one of the selection markers, tell the | 175 // If this block contains one of the selection markers, tell the |
| 176 // writer where it ended up in the final output. | 176 // writer where it ended up in the final output. |
| 177 if (block.selectionStart != null) { | 177 if (block.selectionStart != null) { |
| 178 _selectionStart = length + block.selectionStart; | 178 _selectionStart = length + block.selectionStart; |
| 179 } | 179 } |
| 180 | 180 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 194 | 194 |
| 195 _buffer.write(" " * (splits.getColumn(i))); | 195 _buffer.write(" " * (splits.getColumn(i))); |
| 196 } else { | 196 } else { |
| 197 if (chunk.spaceWhenUnsplit) _buffer.write(" "); | 197 if (chunk.spaceWhenUnsplit) _buffer.write(" "); |
| 198 } | 198 } |
| 199 } | 199 } |
| 200 | 200 |
| 201 return splits.cost; | 201 return splits.cost; |
| 202 } | 202 } |
| 203 | 203 |
| 204 /// Writes [chunks] (and any child chunks of them, recursively) without any | 204 /// Writes the block chunks of [chunk] (and any child chunks of them, |
| 205 /// splitting. | 205 /// recursively) without any splitting. |
| 206 void _writeChunksUnsplit(List<Chunk> chunks) { | 206 void _writeChunksUnsplit(Chunk chunk) { |
| 207 for (var chunk in chunks) { | 207 if (!chunk.isBlock) return; |
| 208 _writeChunk(chunk); | |
| 209 | 208 |
| 210 if (chunk.spaceWhenUnsplit) _buffer.write(" "); | 209 for (var blockChunk in chunk.block.chunks) { |
| 210 _writeChunk(blockChunk); |
| 211 |
| 212 if (blockChunk.spaceWhenUnsplit) _buffer.write(" "); |
| 211 | 213 |
| 212 // Recurse into the block. | 214 // Recurse into the block. |
| 213 _writeChunksUnsplit(chunk.blockChunks); | 215 _writeChunksUnsplit(blockChunk); |
| 214 } | 216 } |
| 215 } | 217 } |
| 216 | 218 |
| 217 /// Writes [chunk] to the output and updates the selection if the chunk | 219 /// Writes [chunk] to the output and updates the selection if the chunk |
| 218 /// contains a selection marker. | 220 /// contains a selection marker. |
| 219 void _writeChunk(Chunk chunk) { | 221 void _writeChunk(Chunk chunk) { |
| 220 if (chunk.selectionStart != null) { | 222 if (chunk.selectionStart != null) { |
| 221 _selectionStart = length + chunk.selectionStart; | 223 _selectionStart = length + chunk.selectionStart; |
| 222 } | 224 } |
| 223 | 225 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 final int selectionStart; | 270 final int selectionStart; |
| 269 | 271 |
| 270 /// Where in the resulting buffer the selection end point should appear if it | 272 /// Where in the resulting buffer the selection end point should appear if it |
| 271 /// was contained within this split list of chunks. | 273 /// was contained within this split list of chunks. |
| 272 /// | 274 /// |
| 273 /// Otherwise, this is `null`. | 275 /// Otherwise, this is `null`. |
| 274 final int selectionEnd; | 276 final int selectionEnd; |
| 275 | 277 |
| 276 FormatResult(this.text, this.cost, this.selectionStart, this.selectionEnd); | 278 FormatResult(this.text, this.cost, this.selectionStart, this.selectionEnd); |
| 277 } | 279 } |
| OLD | NEW |