| Index: packages/dart_style/lib/src/chunk.dart
|
| diff --git a/packages/dart_style/lib/src/chunk.dart b/packages/dart_style/lib/src/chunk.dart
|
| index e92a85b115c506d7d752aedd2cb726c40a21db3a..da6d7bbc011ac9e7d82055ec4d43b76b66c48b52 100644
|
| --- a/packages/dart_style/lib/src/chunk.dart
|
| +++ b/packages/dart_style/lib/src/chunk.dart
|
| @@ -92,9 +92,13 @@ class Chunk extends Selection {
|
| NestingLevel get nesting => _nesting;
|
| NestingLevel _nesting;
|
|
|
| - /// If this chunk marks the beginning of a block, these are the chunks
|
| - /// contained in the block.
|
| - final blockChunks = <Chunk>[];
|
| + /// If this chunk marks the beginning of a block, this contains the child
|
| + /// chunks and other data about that nested block.
|
| + ChunkBlock get block => _block;
|
| + ChunkBlock _block;
|
| +
|
| + /// Whether this chunk has a [block].
|
| + bool get isBlock => _block != null;
|
|
|
| /// Whether it's valid to add more text to this chunk or not.
|
| ///
|
| @@ -110,10 +114,6 @@ class Chunk extends Selection {
|
| Rule get rule => _rule;
|
| Rule _rule;
|
|
|
| - /// Whether this chunk is always followed by a newline or whether the line
|
| - /// splitter may choose to keep the next chunk on the same line.
|
| - bool get isHardSplit => _rule is HardSplitRule;
|
| -
|
| /// Whether or not an extra blank line should be output after this chunk if
|
| /// it's split.
|
| ///
|
| @@ -136,9 +136,9 @@ class Chunk extends Selection {
|
| /// If `true`, then the line after this chunk and its contained block should
|
| /// be flush left.
|
| bool get flushLeftAfter {
|
| - if (blockChunks.isEmpty) return _flushLeft;
|
| + if (!isBlock) return _flushLeft;
|
|
|
| - return blockChunks.last.flushLeftAfter;
|
| + return _block.chunks.last.flushLeftAfter;
|
| }
|
|
|
| /// Whether this chunk should append an extra space if it does not split.
|
| @@ -165,8 +165,10 @@ class Chunk extends Selection {
|
| /// Does not include this chunk's own length, just the length of its child
|
| /// block chunks (recursively).
|
| int get unsplitBlockLength {
|
| + if (_block == null) return 0;
|
| +
|
| var length = 0;
|
| - for (var chunk in blockChunks) {
|
| + for (var chunk in _block.chunks) {
|
| length += chunk.length + chunk.unsplitBlockLength;
|
| }
|
|
|
| @@ -191,15 +193,6 @@ class Chunk extends Selection {
|
| _text += text;
|
| }
|
|
|
| - /// Forces this soft split to become a hard split.
|
| - ///
|
| - /// This is called on the soft splits owned by a rule that decides to harden
|
| - /// when it finds out another hard split occurs within its chunks.
|
| - void harden() {
|
| - _rule = new HardSplitRule();
|
| - spans.clear();
|
| - }
|
| -
|
| /// Finishes off this chunk with the given [rule] and split information.
|
| ///
|
| /// This may be called multiple times on the same split since the splits
|
| @@ -207,10 +200,10 @@ class Chunk extends Selection {
|
| /// preserved whitespace often overlap. When that happens, this has logic to
|
| /// combine that information into a single split.
|
| void applySplit(Rule rule, int indent, NestingLevel nesting,
|
| - {bool flushLeft, bool spaceWhenUnsplit, bool isDouble}) {
|
| + {bool flushLeft, bool isDouble, bool space}) {
|
| if (flushLeft == null) flushLeft = false;
|
| - if (spaceWhenUnsplit == null) spaceWhenUnsplit = false;
|
| - if (isHardSplit || rule is HardSplitRule) {
|
| + if (space == null) space = false;
|
| + if (rule.isHardened) {
|
| // A hard split always wins.
|
| _rule = rule;
|
| } else if (_rule == null) {
|
| @@ -223,12 +216,28 @@ class Chunk extends Selection {
|
| _nesting = nesting;
|
| _indent = indent;
|
|
|
| - _spaceWhenUnsplit = spaceWhenUnsplit;
|
| + _spaceWhenUnsplit = space;
|
|
|
| // Pin down the double state, if given and we haven't already.
|
| if (_isDouble == null) _isDouble = isDouble;
|
| }
|
|
|
| + /// Turns this chunk into one that can contain a block of child chunks.
|
| + void makeBlock(Chunk blockArgument) {
|
| + assert(_block == null);
|
| + _block = new ChunkBlock(blockArgument);
|
| + }
|
| +
|
| + /// Returns `true` if the block body owned by this chunk should be expression
|
| + /// indented given a set of rule values provided by [getValue].
|
| + bool indentBlock(int getValue(Rule rule)) {
|
| + if (_block == null) return false;
|
| + if (_block.argument == null) return false;
|
| +
|
| + return _block.argument.rule
|
| + .isSplit(getValue(_block.argument.rule), _block.argument);
|
| + }
|
| +
|
| // Mark whether this chunk can divide the range of chunks.
|
| void markDivide(canDivide) {
|
| // Should only do this once.
|
| @@ -243,19 +252,18 @@ class Chunk extends Selection {
|
| if (text.isNotEmpty) parts.add(text);
|
|
|
| if (_indent != null) parts.add("indent:$_indent");
|
| - if (spaceWhenUnsplit) parts.add("space");
|
| - if (_isDouble) parts.add("double");
|
| - if (_flushLeft) parts.add("flush");
|
| + if (spaceWhenUnsplit == true) parts.add("space");
|
| + if (_isDouble == true) parts.add("double");
|
| + if (_flushLeft == true) parts.add("flush");
|
|
|
| if (_rule == null) {
|
| parts.add("(no split)");
|
| - } else if (isHardSplit) {
|
| - parts.add("hard");
|
| } else {
|
| parts.add(rule.toString());
|
| + if (rule.isHardened) parts.add("(hard)");
|
|
|
| - if (_rule.outerRules.isNotEmpty) {
|
| - parts.add("-> ${_rule.outerRules.join(' ')}");
|
| + if (_rule.constrainedRules.isNotEmpty) {
|
| + parts.add("-> ${_rule.constrainedRules.join(' ')}");
|
| }
|
| }
|
|
|
| @@ -263,6 +271,22 @@ class Chunk extends Selection {
|
| }
|
| }
|
|
|
| +/// The child chunks owned by a chunk that begins a "block" -- an actual block
|
| +/// statement, function expression, or collection literal.
|
| +class ChunkBlock {
|
| + /// If this block is for a collection literal in an argument list, this will
|
| + /// be the chunk preceding this literal argument.
|
| + ///
|
| + /// That chunk is owned by the argument list and if it splits, this collection
|
| + /// may need extra expression-level indentation.
|
| + final Chunk argument;
|
| +
|
| + /// The child chunks in this block.
|
| + final List<Chunk> chunks = [];
|
| +
|
| + ChunkBlock(this.argument);
|
| +}
|
| +
|
| /// Constants for the cost heuristics used to determine which set of splits is
|
| /// most desirable.
|
| class Cost {
|
| @@ -280,8 +304,11 @@ class Cost {
|
| /// number of nested spans.
|
| static const normal = 1;
|
|
|
| - /// Splitting after a "=" both for assignment and initialization.
|
| - static const assignment = 2;
|
| + /// Splitting after a "=".
|
| + static const assign = 1;
|
| +
|
| + /// Splitting after a "=" when the right-hand side is a collection or cascade.
|
| + static const assignBlock = 2;
|
|
|
| /// Splitting before the first argument when it happens to be a function
|
| /// expression with a block body.
|
| @@ -299,6 +326,9 @@ class Cost {
|
| /// collection contents.
|
| static const splitCollections = 2;
|
|
|
| + /// Splitting on the "." in a named constructor.
|
| + static const constructorName = 3;
|
| +
|
| /// Splitting before a type argument or type parameter.
|
| static const typeArgument = 4;
|
| }
|
|
|