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 |