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

Unified Diff: dart_style/lib/src/line_writer.dart

Issue 1400473008: Roll Observatory packages and add a roll script (Closed) Base URL: git@github.com:dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years, 2 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 | « dart_style/lib/src/line_splitting/solve_state_queue.dart ('k') | dart_style/lib/src/nesting_builder.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: dart_style/lib/src/line_writer.dart
diff --git a/dart_style/lib/src/line_writer.dart b/dart_style/lib/src/line_writer.dart
deleted file mode 100644
index 055892ea0b251639921cc77b7391411a96a5e421..0000000000000000000000000000000000000000
--- a/dart_style/lib/src/line_writer.dart
+++ /dev/null
@@ -1,277 +0,0 @@
-// Copyright (c) 2014, 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.
-
-library dart_style.src.line_writer;
-
-import 'chunk.dart';
-import 'dart_formatter.dart';
-import 'debug.dart' as debug;
-import 'line_splitting/line_splitter.dart';
-import 'whitespace.dart';
-
-/// Given a series of chunks, splits them into lines and writes the result to
-/// a buffer.
-class LineWriter {
- final _buffer = new StringBuffer();
-
- final List<Chunk> _chunks;
-
- final String _lineEnding;
-
- /// The number of characters allowed in a single line.
- final int pageWidth;
-
- /// The number of characters of additional indentation to apply to each line.
- ///
- /// This is used when formatting blocks to get the output into the right
- /// column based on where the block appears.
- final int _blockIndentation;
-
- /// The cache of blocks that have already been formatted.
- final Map<_BlockKey, FormatResult> _blockCache;
-
- /// The offset in [_buffer] where the selection starts in the formatted code.
- ///
- /// This will be `null` if there is no selection or the writer hasn't reached
- /// the beginning of the selection yet.
- int _selectionStart;
-
- /// The offset in [_buffer] where the selection ends in the formatted code.
- ///
- /// This will be `null` if there is no selection or the writer hasn't reached
- /// the end of the selection yet.
- int _selectionEnd;
-
- /// The number of characters that have been written to the output.
- int get length => _buffer.length;
-
- LineWriter(DartFormatter formatter, this._chunks)
- : _lineEnding = formatter.lineEnding,
- pageWidth = formatter.pageWidth,
- _blockIndentation = 0,
- _blockCache = {};
-
- /// Creates a line writer for a block.
- LineWriter._(this._chunks, this._lineEnding, this.pageWidth,
- this._blockIndentation, this._blockCache) {
- // There is always a newline after the opening delimiter.
- _buffer.write(_lineEnding);
- }
-
- /// Gets the results of formatting the child block of [chunk] at with
- /// starting [column].
- ///
- /// If that block has already been formatted, reuses the results.
- ///
- /// The column is the column for the delimiters. The contents of the block
- /// are always implicitly one level deeper than that.
- ///
- /// main() {
- /// function(() {
- /// block;
- /// });
- /// }
- ///
- /// When we format the anonymous lambda, [column] will be 2, not 4.
- FormatResult formatBlock(Chunk chunk, int column) {
- var key = new _BlockKey(chunk, column);
-
- // Use the cached one if we have it.
- var cached = _blockCache[key];
- if (cached != null) return cached;
-
- var writer = new LineWriter._(
- chunk.blockChunks, _lineEnding, pageWidth, column, _blockCache);
-
- // TODO(rnystrom): Passing in an initial indent here is hacky. The
- // LineWriter ensures all but the first chunk have a block indent, and this
- // handles the first chunk. Do something cleaner.
- var result = writer.writeLines(Indent.block, flushLeft: chunk.flushLeft);
- return _blockCache[key] = result;
- }
-
- /// Takes all of the chunks and divides them into sublists and line splits
- /// each list.
- ///
- /// Since this is linear and line splitting is worse it's good to feed the
- /// line splitter smaller lists of chunks when possible.
- FormatResult writeLines(int firstLineIndent,
- {bool isCompilationUnit: false, bool flushLeft: false}) {
- // Now that we know what hard splits there will be, break the chunks into
- // independently splittable lines.
- var newlines = 0;
- var indent = firstLineIndent;
- var totalCost = 0;
- var start = 0;
-
- for (var i = 0; i < _chunks.length; i++) {
- var chunk = _chunks[i];
- if (!chunk.canDivide) continue;
-
- totalCost +=
- _completeLine(newlines, indent, start, i + 1, flushLeft: flushLeft);
-
- // Get ready for the next line.
- newlines = chunk.isDouble ? 2 : 1;
- indent = chunk.indent;
- flushLeft = chunk.flushLeft;
- start = i + 1;
- }
-
- if (start < _chunks.length) {
- totalCost += _completeLine(newlines, indent, start, _chunks.length,
- flushLeft: flushLeft);
- }
-
- // Be a good citizen, end with a newline.
- if (isCompilationUnit) _buffer.write(_lineEnding);
-
- return new FormatResult(
- _buffer.toString(), totalCost, _selectionStart, _selectionEnd);
- }
-
- /// Takes the first [length] of the chunks with leading [indent], removes
- /// them, and runs the [LineSplitter] on them.
- int _completeLine(int newlines, int indent, int start, int end,
- {bool flushLeft}) {
- // Write the newlines required by the previous line.
- for (var j = 0; j < newlines; j++) {
- _buffer.write(_lineEnding);
- }
-
- var chunks = _chunks.sublist(start, end);
-
- if (debug.traceLineWriter) {
- debug.log(debug.green("\nWriting:"));
- debug.dumpChunks(start, chunks);
- debug.log();
- }
-
- // Run the line splitter.
- var splitter = new LineSplitter(this, chunks, _blockIndentation, indent,
- flushLeft: flushLeft);
- var splits = splitter.apply();
-
- // Write the indentation of the first line.
- if (!flushLeft) {
- _buffer.write(" " * (indent + _blockIndentation));
- }
-
- // Write each chunk with the appropriate splits between them.
- for (var i = 0; i < chunks.length; i++) {
- var chunk = chunks[i];
- _writeChunk(chunk);
-
- if (chunk.blockChunks.isNotEmpty) {
- if (!splits.shouldSplitAt(i)) {
- // This block didn't split (which implies none of the child blocks
- // of that block split either, recursively), so write them all inline.
- _writeChunksUnsplit(chunk.blockChunks);
- } else {
- // Include the formatted block contents.
- var block = formatBlock(chunk, splits.getColumn(i));
-
- // If this block contains one of the selection markers, tell the
- // writer where it ended up in the final output.
- if (block.selectionStart != null) {
- _selectionStart = length + block.selectionStart;
- }
-
- if (block.selectionEnd != null) {
- _selectionEnd = length + block.selectionEnd;
- }
-
- _buffer.write(block.text);
- }
- }
-
- if (i == chunks.length - 1) {
- // Don't write trailing whitespace after the last chunk.
- } else if (splits.shouldSplitAt(i)) {
- _buffer.write(_lineEnding);
- if (chunk.isDouble) _buffer.write(_lineEnding);
-
- _buffer.write(" " * (splits.getColumn(i)));
- } else {
- if (chunk.spaceWhenUnsplit) _buffer.write(" ");
- }
- }
-
- return splits.cost;
- }
-
- /// Writes [chunks] (and any child chunks of them, recursively) without any
- /// splitting.
- void _writeChunksUnsplit(List<Chunk> chunks) {
- for (var chunk in chunks) {
- _writeChunk(chunk);
-
- if (chunk.spaceWhenUnsplit) _buffer.write(" ");
-
- // Recurse into the block.
- _writeChunksUnsplit(chunk.blockChunks);
- }
- }
-
- /// Writes [chunk] to the output and updates the selection if the chunk
- /// contains a selection marker.
- void _writeChunk(Chunk chunk) {
- if (chunk.selectionStart != null) {
- _selectionStart = length + chunk.selectionStart;
- }
-
- if (chunk.selectionEnd != null) {
- _selectionEnd = length + chunk.selectionEnd;
- }
-
- _buffer.write(chunk.text);
- }
-}
-
-/// Key type for the formatted block cache.
-///
-/// To cache formatted blocks, we just need to know which block it is (the
-/// index of its parent chunk) and how far it was indented when we formatted it
-/// (the starting column).
-class _BlockKey {
- /// The index of the chunk in the surrounding chunk list that contains this
- /// block.
- final Chunk chunk;
-
- /// The absolute zero-based column number where the block starts.
- final int column;
-
- _BlockKey(this.chunk, this.column);
-
- bool operator ==(other) {
- if (other is! _BlockKey) return false;
- return chunk == other.chunk && column == other.column;
- }
-
- int get hashCode => chunk.hashCode ^ column.hashCode;
-}
-
-/// The result of formatting a series of chunks.
-class FormatResult {
- /// The resulting formatted text, including newlines and leading whitespace
- /// to reach the proper column.
- final String text;
-
- /// The numeric cost of the chosen solution.
- final int cost;
-
- /// Where in the resulting buffer the selection starting point should appear
- /// if it was contained within this split list of chunks.
- ///
- /// Otherwise, this is `null`.
- final int selectionStart;
-
- /// Where in the resulting buffer the selection end point should appear if it
- /// was contained within this split list of chunks.
- ///
- /// Otherwise, this is `null`.
- final int selectionEnd;
-
- FormatResult(this.text, this.cost, this.selectionStart, this.selectionEnd);
-}
« no previous file with comments | « dart_style/lib/src/line_splitting/solve_state_queue.dart ('k') | dart_style/lib/src/nesting_builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698