From 508409b6f4cbcd746adeafbfbd13c9cbbcffe64c Mon Sep 17 00:00:00 2001 From: Robert Nystrom Date: Thu, 16 Nov 2023 14:33:41 -0800 Subject: [PATCH] Remove _blockCandidates and store block element type on ListElement. --- lib/src/front_end/delimited_list_builder.dart | 33 +++++++++---------- lib/src/piece/list.dart | 30 ++++++++++++++--- 2 files changed, 41 insertions(+), 22 deletions(-) diff --git a/lib/src/front_end/delimited_list_builder.dart b/lib/src/front_end/delimited_list_builder.dart index 149a65ab..ca3a6fc7 100644 --- a/lib/src/front_end/delimited_list_builder.dart +++ b/lib/src/front_end/delimited_list_builder.dart @@ -36,11 +36,6 @@ class DelimitedListBuilder { final ListStyle _style; - /// The nodes that have been visited by this builder. - /// - /// Used to find the block element from them, if desired. - final List _blockCandidates = []; - /// The list of comments following the most recently written element before /// any comma following the element. CommentSequence _commentsBeforeComma = CommentSequence.empty; @@ -131,8 +126,8 @@ class DelimitedListBuilder { /// [addCommentsBefore()] for the first token in the [piece]. /// /// Assumes there is no comma after this piece. - void add(Piece piece) { - _elements.add(ListElement(piece)); + void add(Piece piece, [BlockFormat format = BlockFormat.none]) { + _elements.add(ListElement(piece, format)); _commentsBeforeComma = CommentSequence.empty; } @@ -148,17 +143,21 @@ class DelimitedListBuilder { // Handle comments between the preceding element and this one. addCommentsBefore(element.firstNonCommentToken); + // See if it's an expression that supports block formatting. + var format = switch (element) { + FunctionExpression() when element.canBlockSplit => BlockFormat.function, + Expression() when element.canBlockSplit => BlockFormat.block, + _ => BlockFormat.none, + }; + // Traverse the element itself. _visitor.visit(element); - add(_visitor.pieces.split()); + add(_visitor.pieces.split(), format); var nextToken = element.endToken.next!; if (nextToken.lexeme == ',') { _commentsBeforeComma = _visitor.takeCommentsBefore(nextToken); } - - // If this element might be block formatted, remember it. - if (_style.allowBlockElement) _blockCandidates.add(element); } /// Inserts an inner left delimiter between two elements. @@ -396,14 +395,14 @@ class DelimitedListBuilder { var functions = []; var others = []; - for (var i = 0; i < _blockCandidates.length; i++) { - var node = _blockCandidates[i]; - if (node is Expression && node.canBlockSplit) { - if (node is FunctionExpression) { + for (var i = 0; i < _elements.length; i++) { + switch (_elements[i].blockFormat) { + case BlockFormat.function: functions.add(i); - } else { + case BlockFormat.block: others.add(i); - } + case BlockFormat.none: + break; // Not a block element. } } diff --git a/lib/src/piece/list.dart b/lib/src/piece/list.dart index 5713eb15..0455318c 100644 --- a/lib/src/piece/list.dart +++ b/lib/src/piece/list.dart @@ -187,6 +187,9 @@ class ListPiece extends Piece { final class ListElement { final Piece? _element; + /// What kind of block formatting can be applied to this element. + final BlockFormat blockFormat; + /// If this piece has an opening delimiter after the comma, this is its /// lexeme, otherwise an empty string. /// @@ -203,11 +206,14 @@ final class ListElement { final Piece? _comment; - ListElement(Piece element, [Piece? comment]) : this._(element, '', comment); + ListElement(Piece element, BlockFormat format, [Piece? comment]) + : this._(element, format, '', comment); - ListElement.comment(Piece comment) : this._(null, '', comment); + ListElement.comment(Piece comment) + : this._(null, BlockFormat.none, '', comment); - ListElement._(this._element, this._delimiter, [this._comment]); + ListElement._(this._element, this.blockFormat, this._delimiter, + [this._comment]); /// Writes this element to [writer]. /// @@ -239,11 +245,11 @@ final class ListElement { /// Returns a new [ListElement] containing this one's element and [comment]. ListElement withComment(Piece comment) { assert(_comment == null); // Shouldn't already have one. - return ListElement._(_element, _delimiter, comment); + return ListElement._(_element, blockFormat, _delimiter, comment); } ListElement withDelimiter(String delimiter) { - return ListElement._(_element, delimiter, _comment); + return ListElement._(_element, blockFormat, delimiter, _comment); } } @@ -264,6 +270,20 @@ enum Commas { none, } +/// What kind of block formatting style can be applied to the element. +enum BlockFormat { + /// The element is a function expression, which takes priority over other + /// kinds of block formatted elements. + function, + + /// The element is a collection literal or some other kind expression that + /// can be block formatted. + block, + + /// The element can't be block formatted. + none, +} + /// The various ways a "list" can appear syntactically and be formatted. /// /// [ListPiece] is used for most places in code where a series of elements can