From a5ec37d3563f9c77e932f5f32f67496ab841a5f5 Mon Sep 17 00:00:00 2001 From: Bob Nystrom Date: Fri, 4 Oct 2024 14:03:19 -0700 Subject: [PATCH] Apply class modifiers to all the classes. (#1575) Now that we've bumped the major version and can make breaking changes, I went ahead and locked down all of the classes. It mostly matters for the public ones, but I went ahead and applied it to the internal ones too just to see if it makes things easier to maintain. --- CHANGELOG.md | 6 ++++++ lib/src/back_end/code.dart | 2 +- lib/src/back_end/code_writer.dart | 4 ++-- lib/src/back_end/solution.dart | 2 +- lib/src/back_end/solution_cache.dart | 2 +- lib/src/back_end/solver.dart | 2 +- lib/src/cli/format_command.dart | 2 +- lib/src/cli/formatter_options.dart | 2 +- lib/src/cli/summary.dart | 6 +++--- lib/src/constants.dart | 4 ++-- lib/src/dart_formatter.dart | 2 +- lib/src/debug.dart | 2 +- lib/src/exceptions.dart | 4 ++-- lib/src/front_end/ast_node_visitor.dart | 2 +- lib/src/front_end/chain_builder.dart | 2 +- lib/src/front_end/comment_writer.dart | 6 +++--- lib/src/front_end/delimited_list_builder.dart | 2 +- lib/src/front_end/piece_writer.dart | 2 +- lib/src/front_end/sequence_builder.dart | 2 +- lib/src/language_version_cache.dart | 2 +- lib/src/piece/adjacent.dart | 2 +- lib/src/piece/assign.dart | 2 +- lib/src/piece/case.dart | 2 +- lib/src/piece/chain.dart | 4 ++-- lib/src/piece/clause.dart | 2 +- lib/src/piece/constructor.dart | 2 +- lib/src/piece/control_flow.dart | 4 ++-- lib/src/piece/for.dart | 4 ++-- lib/src/piece/if_case.dart | 2 +- lib/src/piece/infix.dart | 2 +- lib/src/piece/leading_comment.dart | 2 +- lib/src/piece/list.dart | 4 ++-- lib/src/piece/piece.dart | 4 ++-- lib/src/piece/sequence.dart | 6 +++--- lib/src/piece/text.dart | 10 +++++----- lib/src/piece/type.dart | 2 +- lib/src/piece/variable.dart | 2 +- lib/src/profile.dart | 2 +- lib/src/short/argument_list_visitor.dart | 4 ++-- lib/src/short/call_chain_visitor.dart | 10 +++++----- lib/src/short/chunk.dart | 8 ++++---- lib/src/short/chunk_builder.dart | 2 +- lib/src/short/fast_hash.dart | 2 +- lib/src/short/line_splitting/line_splitter.dart | 2 +- lib/src/short/line_splitting/rule_set.dart | 4 ++-- lib/src/short/line_splitting/solve_state.dart | 2 +- lib/src/short/line_splitting/solve_state_queue.dart | 2 +- lib/src/short/line_writer.dart | 6 +++--- lib/src/short/nesting_builder.dart | 2 +- lib/src/short/nesting_level.dart | 2 +- lib/src/short/rule/argument.dart | 6 +++--- lib/src/short/rule/combinator.dart | 2 +- lib/src/short/rule/rule.dart | 6 +++--- lib/src/short/rule/type_argument.dart | 2 +- lib/src/short/selection.dart | 2 +- lib/src/short/source_comment.dart | 2 +- lib/src/short/source_visitor.dart | 4 ++-- lib/src/source_code.dart | 2 +- lib/src/testing/benchmark.dart | 2 +- lib/src/testing/test_file.dart | 4 ++-- 60 files changed, 100 insertions(+), 94 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7ef3ae4..0d56e46a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,12 @@ If `--stdin-name` and `--language-version` are both omitted, then parses stdin using the latest supported language version. +* **Apply class modifiers to API classes.** The dart_style package exposes only + a few classes in its public API: `DartFormatter`, `SourceCode`, + `FormatterException`, and `UnexpectedOutputException`. None were ever + intended to be extended or implemented. They are now all marked `final` to + make that intention explicit. + ## 2.3.7 * Allow passing a language version to `DartFomatter()`. Formatted code will be diff --git a/lib/src/back_end/code.dart b/lib/src/back_end/code.dart index 52416a1d..addd1831 100644 --- a/lib/src/back_end/code.dart +++ b/lib/src/back_end/code.dart @@ -177,7 +177,7 @@ enum _Marker { start, end } /// Traverses a [Code] tree and produces the final string of output code and /// the selection markers, if any. -class _StringBuilder { +final class _StringBuilder { /// Pre-calculated whitespace strings for various common levels of /// indentation. /// diff --git a/lib/src/back_end/code_writer.dart b/lib/src/back_end/code_writer.dart index c266dc17..c30e1054 100644 --- a/lib/src/back_end/code_writer.dart +++ b/lib/src/back_end/code_writer.dart @@ -20,7 +20,7 @@ import 'solution_cache.dart'; /// an instance of this class. It has methods that the piece can call to add /// output text to the resulting code, recursively format child pieces, insert /// whitespace, etc. -class CodeWriter { +final class CodeWriter { final int _pageWidth; /// Previously cached formatted subtrees. @@ -415,7 +415,7 @@ enum Whitespace { } /// A level of indentation in the indentation stack. -class _Indent { +final class _Indent { /// The total number of spaces of indentation. final int indent; diff --git a/lib/src/back_end/solution.dart b/lib/src/back_end/solution.dart index a084ffaa..cacf0967 100644 --- a/lib/src/back_end/solution.dart +++ b/lib/src/back_end/solution.dart @@ -17,7 +17,7 @@ import 'solution_cache.dart'; /// of the pieces in the tree so they can format themselves. That in turn /// yields a total number of overflow characters, cost, and formatted output, /// which are all stored here. -class Solution implements Comparable { +final class Solution implements Comparable { /// The states that pieces have been bound to. /// /// Note that order that keys are inserted into this map is significant. When diff --git a/lib/src/back_end/solution_cache.dart b/lib/src/back_end/solution_cache.dart index b2b51844..a76f9b0c 100644 --- a/lib/src/back_end/solution_cache.dart +++ b/lib/src/back_end/solution_cache.dart @@ -22,7 +22,7 @@ import 'solver.dart'; /// the same child Piece and wanting to format it separately with the same /// indentation. When that happens, sharing this cache allows us to reuse that /// cached subtree Solution. -class SolutionCache { +final class SolutionCache { final _cache = <_Key, Solution>{}; /// Returns a previously cached solution for formatting [root] with leading diff --git a/lib/src/back_end/solver.dart b/lib/src/back_end/solver.dart index 323f32c9..ce2a344c 100644 --- a/lib/src/back_end/solver.dart +++ b/lib/src/back_end/solver.dart @@ -42,7 +42,7 @@ const _maxAttempts = 10000; /// use it across different Solutions. This enables us to both divide and /// conquer the Piece tree and solve portions separately, while also /// reusing work across different solutions. -class Solver { +final class Solver { final SolutionCache _cache; final int _pageWidth; diff --git a/lib/src/cli/format_command.dart b/lib/src/cli/format_command.dart index 5618261f..67e7e629 100644 --- a/lib/src/cli/format_command.dart +++ b/lib/src/cli/format_command.dart @@ -14,7 +14,7 @@ import 'output.dart'; import 'show.dart'; import 'summary.dart'; -class FormatCommand extends Command { +final class FormatCommand extends Command { @override String get name => 'format'; diff --git a/lib/src/cli/formatter_options.dart b/lib/src/cli/formatter_options.dart index d20e4238..c7dbd3fe 100644 --- a/lib/src/cli/formatter_options.dart +++ b/lib/src/cli/formatter_options.dart @@ -15,7 +15,7 @@ import 'summary.dart'; const dartStyleVersion = '2.3.7'; /// Global options that affect how the formatter produces and uses its outputs. -class FormatterOptions { +final class FormatterOptions { /// The language version formatted code should be parsed at or `null` if not /// specified. final Version? languageVersion; diff --git a/lib/src/cli/summary.dart b/lib/src/cli/summary.dart index 87085d54..fe366740 100644 --- a/lib/src/cli/summary.dart +++ b/lib/src/cli/summary.dart @@ -8,7 +8,7 @@ import '../source_code.dart'; import 'formatter_options.dart'; /// The kind of summary shown after all formatting is complete. -class Summary { +final class Summary { static const Summary none = Summary._(); /// Creates a Summary that tracks how many files were formatted and the total @@ -41,7 +41,7 @@ class Summary { } /// Tracks how many files were formatted and the total time. -class _LineSummary extends Summary { +final class _LineSummary extends Summary { final DateTime _start = DateTime.now(); /// The number of processed files. @@ -81,7 +81,7 @@ class _LineSummary extends Summary { } /// Reports how long it took for format each file. -class _ProfileSummary implements Summary { +final class _ProfileSummary implements Summary { /// The files that have been started but have not completed yet. /// /// Maps a file label to the time that it started being formatted. diff --git a/lib/src/constants.dart b/lib/src/constants.dart index a830adc8..59e20859 100644 --- a/lib/src/constants.dart +++ b/lib/src/constants.dart @@ -13,7 +13,7 @@ const tallStyleExperimentFlag = 'tall-style'; /// Constants for the cost heuristics used to determine which set of splits is /// most desirable. -class Cost { +final class Cost { /// The cost of splitting after the `=>` in a lambda or arrow-bodied member. /// /// We make this zero because there is already a span around the entire body @@ -64,7 +64,7 @@ class Cost { } /// Constants for the number of spaces for various kinds of indentation. -class Indent { +final class Indent { /// Reset back to no indentation. static const none = 0; diff --git a/lib/src/dart_formatter.dart b/lib/src/dart_formatter.dart index 9394448d..9c5a6818 100644 --- a/lib/src/dart_formatter.dart +++ b/lib/src/dart_formatter.dart @@ -22,7 +22,7 @@ import 'source_code.dart'; import 'string_compare.dart' as string_compare; /// Dart source code formatter. -class DartFormatter { +final class DartFormatter { /// The latest Dart language version that can be parsed and formatted by this /// version of the formatter. static final latestLanguageVersion = Version(3, 3, 0); diff --git a/lib/src/debug.dart b/lib/src/debug.dart index e27f2d4a..5d3999a8 100644 --- a/lib/src/debug.dart +++ b/lib/src/debug.dart @@ -277,7 +277,7 @@ String pieceTree(Piece piece) { } /// A stringified representation of a tree of pieces for debug output. -class _PieceDebugTree { +final class _PieceDebugTree { final String label; final List<_PieceDebugTree> children = []; diff --git a/lib/src/exceptions.dart b/lib/src/exceptions.dart index 93809e4e..58213080 100644 --- a/lib/src/exceptions.dart +++ b/lib/src/exceptions.dart @@ -7,7 +7,7 @@ import 'package:source_span/source_span.dart'; /// Thrown when one or more errors occurs while parsing the code to be /// formatted. -class FormatterException implements Exception { +final class FormatterException implements Exception { /// The [AnalysisError]s that occurred. final List errors; @@ -53,7 +53,7 @@ class FormatterException implements Exception { /// Exception thrown when the internal sanity check that only whitespace /// changes are made fails. -class UnexpectedOutputException implements Exception { +final class UnexpectedOutputException implements Exception { /// The source being formatted. final String _input; diff --git a/lib/src/front_end/ast_node_visitor.dart b/lib/src/front_end/ast_node_visitor.dart index 904122b7..87b4d169 100644 --- a/lib/src/front_end/ast_node_visitor.dart +++ b/lib/src/front_end/ast_node_visitor.dart @@ -34,7 +34,7 @@ import 'sequence_builder.dart'; /// To avoid this class becoming a monolith, functionality is divided into a /// couple of mixins, one for each area of functionality. This class then /// contains only shared state and the visitor methods for the AST. -class AstNodeVisitor extends ThrowingAstVisitor with PieceFactory { +final class AstNodeVisitor extends ThrowingAstVisitor with PieceFactory { @override final PieceWriter pieces; diff --git a/lib/src/front_end/chain_builder.dart b/lib/src/front_end/chain_builder.dart index bf36b5d1..4cb114f5 100644 --- a/lib/src/front_end/chain_builder.dart +++ b/lib/src/front_end/chain_builder.dart @@ -41,7 +41,7 @@ import 'piece_factory.dart'; /// /// This lets us create a single [ChainPiece] for the entire series of dotted /// operations, so that we can control splitting them or not as a unit. -class ChainBuilder { +final class ChainBuilder { final PieceFactory _visitor; /// The outermost expression being converted to a chain. diff --git a/lib/src/front_end/comment_writer.dart b/lib/src/front_end/comment_writer.dart index 3e1926eb..542666ac 100644 --- a/lib/src/front_end/comment_writer.dart +++ b/lib/src/front_end/comment_writer.dart @@ -41,7 +41,7 @@ import '../comment_type.dart'; /// construct. These get directly embedded in the [TextPiece] of the code being /// written. When that [TextPiece] is output later, it will include the comments /// as well. -class CommentWriter { +final class CommentWriter { final LineInfo _lineInfo; /// The tokens whose preceding comments have already been taken by calls to @@ -147,7 +147,7 @@ class CommentWriter { /// A comment in the source, with a bit of information about the surrounding /// whitespace. -class SourceComment { +final class SourceComment { /// The text of the comment, including `//`, `/*`, and `*/`. final String text; @@ -210,7 +210,7 @@ class SourceComment { /// * 2 newlines between `/* c2 */` and `/* c3 */` /// * Comment `/* c3 */` /// * 3 newlines between `/* c3 */` and `b` -class CommentSequence extends ListBase { +final class CommentSequence extends ListBase { static const CommentSequence empty = CommentSequence._([0], []); /// The number of newlines between a pair of comments or the preceding or diff --git a/lib/src/front_end/delimited_list_builder.dart b/lib/src/front_end/delimited_list_builder.dart index a81f8ae5..a4bf9da0 100644 --- a/lib/src/front_end/delimited_list_builder.dart +++ b/lib/src/front_end/delimited_list_builder.dart @@ -18,7 +18,7 @@ import 'piece_factory.dart'; /// delimiter token. Then call [add()] for each [AstNode] that is inside the /// delimiters. The [rightBracket()] with the closing delimiter and finally /// [build()] to get the resulting [ListPiece]. -class DelimitedListBuilder { +final class DelimitedListBuilder { final PieceFactory _visitor; /// The opening bracket before the elements, if any. diff --git a/lib/src/front_end/piece_writer.dart b/lib/src/front_end/piece_writer.dart index e2e1f0bf..624c6f72 100644 --- a/lib/src/front_end/piece_writer.dart +++ b/lib/src/front_end/piece_writer.dart @@ -24,7 +24,7 @@ import 'sequence_builder.dart'; /// /// Handles updating selection markers and attaching comments to the tokens /// before and after the comments. -class PieceWriter { +final class PieceWriter { final DartFormatter _formatter; final SourceCode _source; diff --git a/lib/src/front_end/sequence_builder.dart b/lib/src/front_end/sequence_builder.dart index ce51a298..0edbb925 100644 --- a/lib/src/front_end/sequence_builder.dart +++ b/lib/src/front_end/sequence_builder.dart @@ -22,7 +22,7 @@ import 'piece_factory.dart'; /// separate statements inside the sequence. This lets us gracefully handle /// indenting them and supporting blank lines around them the same way we handle /// other statements or members in a sequence. -class SequenceBuilder { +final class SequenceBuilder { final PieceFactory _visitor; /// The opening bracket before the elements, if any. diff --git a/lib/src/language_version_cache.dart b/lib/src/language_version_cache.dart index 14e04d50..97df4619 100644 --- a/lib/src/language_version_cache.dart +++ b/lib/src/language_version_cache.dart @@ -23,7 +23,7 @@ import 'profile.dart'; /// looking for package configs for each file as it did formatting if we don't /// cache. Caching makes it ~10x faster to find the language version for each /// file.) -class LanguageVersionCache { +final class LanguageVersionCache { /// The previously cached default language version for all files immediately /// within a given directory. /// diff --git a/lib/src/piece/adjacent.dart b/lib/src/piece/adjacent.dart index 9d6c97ba..80316f32 100644 --- a/lib/src/piece/adjacent.dart +++ b/lib/src/piece/adjacent.dart @@ -5,7 +5,7 @@ import '../back_end/code_writer.dart'; import 'piece.dart'; /// A simple piece that just writes its child pieces one after the other. -class AdjacentPiece extends Piece { +final class AdjacentPiece extends Piece { final List pieces; AdjacentPiece(this.pieces); diff --git a/lib/src/piece/assign.dart b/lib/src/piece/assign.dart index d861721c..39f58c83 100644 --- a/lib/src/piece/assign.dart +++ b/lib/src/piece/assign.dart @@ -67,7 +67,7 @@ import 'piece.dart'; /// var [unsplitBlock] = /// longOperand + /// anotherOperand; -class AssignPiece extends Piece { +final class AssignPiece extends Piece { /// Force the block left-hand side to split and allow the right-hand side to /// split. static const State _blockSplitLeft = State(1); diff --git a/lib/src/piece/case.dart b/lib/src/piece/case.dart index de42ef3c..b17a0ab7 100644 --- a/lib/src/piece/case.dart +++ b/lib/src/piece/case.dart @@ -7,7 +7,7 @@ import '../constants.dart'; import 'piece.dart'; /// Piece for a case pattern, guard, and body in a switch expression. -class CaseExpressionPiece extends Piece { +final class CaseExpressionPiece extends Piece { /// Split after the `=>` before the body. static const State _beforeBody = State(1); diff --git a/lib/src/piece/chain.dart b/lib/src/piece/chain.dart index b7a2d387..29a4afc9 100644 --- a/lib/src/piece/chain.dart +++ b/lib/src/piece/chain.dart @@ -49,7 +49,7 @@ import 'piece.dart'; /// argument, /// argument, /// ); -class ChainPiece extends Piece { +final class ChainPiece extends Piece { /// Allow newlines in the last (or next-to-last) call but nowhere else. static const State _blockFormatTrailingCall = State(1, cost: 0); @@ -248,7 +248,7 @@ class ChainPiece extends Piece { /// A method or getter call in a call chain, along with any postfix operations /// applies to it. -class ChainCall { +final class ChainCall { /// Piece for the call. Piece _call; diff --git a/lib/src/piece/clause.dart b/lib/src/piece/clause.dart index 0e77ddb0..003441b0 100644 --- a/lib/src/piece/clause.dart +++ b/lib/src/piece/clause.dart @@ -61,7 +61,7 @@ import 'piece.dart'; /// /// This ensures that when any wrapping occurs, the keywords are always at the /// beginning of the line. -class ClausePiece extends Piece { +final class ClausePiece extends Piece { /// State where we split between the clauses but not before the first one. static const State _betweenClauses = State(1); diff --git a/lib/src/piece/constructor.dart b/lib/src/piece/constructor.dart index ed6a0707..5f496e94 100644 --- a/lib/src/piece/constructor.dart +++ b/lib/src/piece/constructor.dart @@ -48,7 +48,7 @@ import 'piece.dart'; /// ]) : firstInitializer = 1, /// second = 2; /// // ^ Five spaces of indentation. -class ConstructorPiece extends Piece { +final class ConstructorPiece extends Piece { static const _splitBeforeInitializers = State(1, cost: 1); static const _splitBetweenInitializers = State(2, cost: 2); diff --git a/lib/src/piece/control_flow.dart b/lib/src/piece/control_flow.dart index 831b4205..eab78c7a 100644 --- a/lib/src/piece/control_flow.dart +++ b/lib/src/piece/control_flow.dart @@ -7,7 +7,7 @@ import 'piece.dart'; /// A piece for an if statement or element, while statement, or for statement /// without a block body. -class ControlFlowPiece extends Piece { +final class ControlFlowPiece extends Piece { /// Whether this is an if statement versus if collection element. /// /// It's not meaningful for while and for statements/elements. @@ -97,7 +97,7 @@ class ControlFlowPiece extends Piece { /// is the `else if (condition)` and the statement is the subsequent then /// branch. For the final `else` branch, if there is one, the [header] is just /// `else` and the statement is the else branch. -class _Section { +final class _Section { final Piece header; final Piece statement; diff --git a/lib/src/piece/for.dart b/lib/src/piece/for.dart index e5146061..d2193d47 100644 --- a/lib/src/piece/for.dart +++ b/lib/src/piece/for.dart @@ -6,7 +6,7 @@ import '../constants.dart'; import 'piece.dart'; /// A piece for the `for (...)` part of a for statement or element. -class ForPiece extends Piece { +final class ForPiece extends Piece { /// The `for` keyword. final Piece _forKeyword; @@ -73,7 +73,7 @@ class ForPiece extends Piece { /// anotherOperand) { /// ... /// } -class ForInPiece extends Piece { +final class ForInPiece extends Piece { /// The variable or pattern initialized with each loop iteration. final Piece _variable; diff --git a/lib/src/piece/if_case.dart b/lib/src/piece/if_case.dart index 80d8e087..f9557390 100644 --- a/lib/src/piece/if_case.dart +++ b/lib/src/piece/if_case.dart @@ -36,7 +36,7 @@ import 'piece.dart'; /// if (obj /// case pattern /// when cond) ... -class IfCasePiece extends Piece { +final class IfCasePiece extends Piece { /// Split before the `when` guard clause. static const State _beforeWhen = State(1); diff --git a/lib/src/piece/infix.dart b/lib/src/piece/infix.dart index 989cb1d2..e9652cb9 100644 --- a/lib/src/piece/infix.dart +++ b/lib/src/piece/infix.dart @@ -8,7 +8,7 @@ import 'piece.dart'; /// A piece for a series of binary expressions at the same precedence, like: /// /// a + b + c -class InfixPiece extends Piece { +final class InfixPiece extends Piece { /// The series of operands. /// /// Since we don't split on both sides of the operator, the operators will be diff --git a/lib/src/piece/leading_comment.dart b/lib/src/piece/leading_comment.dart index 2025c4f5..c602f814 100644 --- a/lib/src/piece/leading_comment.dart +++ b/lib/src/piece/leading_comment.dart @@ -23,7 +23,7 @@ import 'piece.dart'; /// // comment /// a + /// b; -class LeadingCommentPiece extends Piece { +final class LeadingCommentPiece extends Piece { final List _comments; final Piece _piece; diff --git a/lib/src/piece/list.dart b/lib/src/piece/list.dart index 3eb36ccd..3c9ec287 100644 --- a/lib/src/piece/list.dart +++ b/lib/src/piece/list.dart @@ -38,7 +38,7 @@ import 'piece.dart'; /// /// ListPieces are usually constructed using [createList()] or /// [DelimitedListBuilder]. -class ListPiece extends Piece { +final class ListPiece extends Piece { /// The opening bracket before the elements, if any. final Piece? _before; @@ -435,7 +435,7 @@ enum BlockFormat { /// they vary in whether or not a trailing comma is allowed, whether there /// should be spaces inside the delimiters when the elements aren't split, etc. /// This class captures those options. -class ListStyle { +final class ListStyle { /// How commas should be handled by the list. /// /// Most lists use [Commas.trailing]. Type parameters and type arguments use diff --git a/lib/src/piece/piece.dart b/lib/src/piece/piece.dart index 9a45b85e..693f599a 100644 --- a/lib/src/piece/piece.dart +++ b/lib/src/piece/piece.dart @@ -14,7 +14,7 @@ typedef Constrain = void Function(Piece other, State constrainedState); /// roughly follows the AST but includes comments and is optimized for /// formatting and line splitting. The final output is then determined by /// deciding which pieces split and how. -abstract class Piece { +abstract base class Piece { /// The ordered list of all possible ways this piece could split. /// /// Piece subclasses should override this if they support being split in @@ -199,7 +199,7 @@ abstract class Piece { /// /// Each state identifies one way that a piece can be split into multiple lines. /// Each piece determines how its states are interpreted. -class State implements Comparable { +final class State implements Comparable { static const unsplit = State(0, cost: 0); /// The maximally split state a piece can be in. diff --git a/lib/src/piece/sequence.dart b/lib/src/piece/sequence.dart index 2df49113..e976517d 100644 --- a/lib/src/piece/sequence.dart +++ b/lib/src/piece/sequence.dart @@ -10,7 +10,7 @@ import 'piece.dart'; /// body or at the top level of a program. /// /// Constructed using a [SequenceBuilder]. -class SequencePiece extends Piece { +final class SequencePiece extends Piece { /// The series of members or statements. final List _elements; @@ -56,7 +56,7 @@ class SequencePiece extends Piece { /// Unlike [ListPiece], always splits between the elements. /// /// Constructed using a [SequenceBuilder]. -class BlockPiece extends Piece { +final class BlockPiece extends Piece { /// The opening delimiter. final Piece _leftBracket; @@ -97,7 +97,7 @@ class BlockPiece extends Piece { /// An element inside a [SequencePiece]. /// /// Tracks the underlying [Piece] along with surrounding whitespace. -class SequenceElementPiece extends Piece { +final class SequenceElementPiece extends Piece { /// The number of spaces of indentation on the line before this element, /// relative to the surrounding [Piece]. final int _indent; diff --git a/lib/src/piece/text.dart b/lib/src/piece/text.dart index b5c159f4..630b1944 100644 --- a/lib/src/piece/text.dart +++ b/lib/src/piece/text.dart @@ -105,7 +105,7 @@ sealed class TextPiece extends Piece { /// [TextPiece] for non-comment source code that may have comments attached to /// it. -class CodePiece extends TextPiece { +final class CodePiece extends TextPiece { /// Pieces for any comments that appear immediately before this code. final List _leadingComments; @@ -147,7 +147,7 @@ class CodePiece extends TextPiece { } /// A [TextPiece] for a source code comment and the whitespace after it, if any. -class CommentPiece extends TextPiece { +final class CommentPiece extends TextPiece { /// Whitespace at the end of the comment. final Whitespace _trailingWhitespace; @@ -170,7 +170,7 @@ class CommentPiece extends TextPiece { /// A piece for the special `// dart format off` and `// dart format on` /// comments that are used to opt a region of code out of being formatted. -class EnableFormattingCommentPiece extends CommentPiece { +final class EnableFormattingCommentPiece extends CommentPiece { /// Whether this comment disables formatting (`format off`) or re-enables it /// (`format on`). final bool _enabled; @@ -195,7 +195,7 @@ class EnableFormattingCommentPiece extends CommentPiece { } /// A piece that writes a single space. -class SpacePiece extends Piece { +final class SpacePiece extends Piece { @override void forEachChild(void Function(Piece piece) callback) {} @@ -212,7 +212,7 @@ class SpacePiece extends Piece { } /// A piece that writes a single newline. -class NewlinePiece extends Piece { +final class NewlinePiece extends Piece { @override void forEachChild(void Function(Piece piece) callback) {} diff --git a/lib/src/piece/type.dart b/lib/src/piece/type.dart index 38251a54..ef0dab12 100644 --- a/lib/src/piece/type.dart +++ b/lib/src/piece/type.dart @@ -7,7 +7,7 @@ import 'piece.dart'; /// Piece for a type declaration with a body containing members. /// /// Used for class, enum, and extension declarations. -class TypePiece extends Piece { +final class TypePiece extends Piece { /// The leading keywords and modifiers, type name, type parameters, and any /// other `extends`, `with`, etc. clauses. final Piece _header; diff --git a/lib/src/piece/variable.dart b/lib/src/piece/variable.dart index 97dfe29b..ef137e02 100644 --- a/lib/src/piece/variable.dart +++ b/lib/src/piece/variable.dart @@ -29,7 +29,7 @@ import 'piece.dart'; /// VeryLongTypeName /// longVariableName = initializer, /// anotherVariable = anotherInitializer; -class VariablePiece extends Piece { +final class VariablePiece extends Piece { /// Split between each variable in a multiple variable declaration. static const State _betweenVariables = State(1); diff --git a/lib/src/profile.dart b/lib/src/profile.dart index 6628ba19..b783cdef 100644 --- a/lib/src/profile.dart +++ b/lib/src/profile.dart @@ -10,7 +10,7 @@ import 'dart:math'; /// Using a general-purpose sampling profiler is difficult with the formatter /// because so much of its code is recursive. Manual instrumentation can provide /// more concise, meaningful data. -class Profile { +final class Profile { /// Whether profiling is enabled. /// /// Enabling profiling has a noticeable effect on overall performance. When diff --git a/lib/src/short/argument_list_visitor.dart b/lib/src/short/argument_list_visitor.dart index 491f2eef..f5aead7b 100644 --- a/lib/src/short/argument_list_visitor.dart +++ b/lib/src/short/argument_list_visitor.dart @@ -16,7 +16,7 @@ import 'source_visitor.dart'; /// Helper class for [SourceVisitor] that handles visiting and writing an /// [ArgumentList], including all of the special code needed to handle /// block-formatted arguments. -class ArgumentListVisitor { +final class ArgumentListVisitor { final SourceVisitor _visitor; /// The "(" before the argument list. @@ -291,7 +291,7 @@ class ArgumentListVisitor { /// when an argument list has block functions in the middle, the arguments /// before and after the functions are treated as separate independent lists. /// In that case, there will be two of these. -class ArgumentSublist { +final class ArgumentSublist { /// The full argument list from the AST. final List _allArguments; diff --git a/lib/src/short/call_chain_visitor.dart b/lib/src/short/call_chain_visitor.dart index 0abf0b59..bb96a8b5 100644 --- a/lib/src/short/call_chain_visitor.dart +++ b/lib/src/short/call_chain_visitor.dart @@ -35,7 +35,7 @@ import 'source_visitor.dart'; /// accesses. Then each of those may have one or more postfix selectors /// attached: indexers, null-assertions, or invocations. This mirrors how they /// are formatted. -class CallChainVisitor { +final class CallChainVisitor { final SourceVisitor _visitor; /// The initial target of the call chain. @@ -408,7 +408,7 @@ class CallChainVisitor { /// .method(arg)[index] /// .another()! /// .third(); -abstract class _Selector { +sealed class _Selector { /// The series of index and/or null-assertion postfix selectors that follow /// and are attached to this one. /// @@ -454,7 +454,7 @@ abstract class _Selector { void writeSelector(CallChainVisitor visitor); } -class _MethodSelector extends _Selector { +final class _MethodSelector extends _Selector { final MethodInvocation _node; _MethodSelector(this._node); @@ -481,7 +481,7 @@ class _MethodSelector extends _Selector { } } -class _PrefixedSelector extends _Selector { +final class _PrefixedSelector extends _Selector { final PrefixedIdentifier _node; _PrefixedSelector(this._node); @@ -493,7 +493,7 @@ class _PrefixedSelector extends _Selector { } } -class _PropertySelector extends _Selector { +final class _PropertySelector extends _Selector { final PropertyAccess _node; _PropertySelector(this._node); diff --git a/lib/src/short/chunk.dart b/lib/src/short/chunk.dart index 9987572e..c37ed110 100644 --- a/lib/src/short/chunk.dart +++ b/lib/src/short/chunk.dart @@ -30,7 +30,7 @@ import 'selection.dart'; /// /// A split controls the leading spacing of the line before the chunk's text, /// both block-based [indent] and expression-wrapping-based [nesting]. -class Chunk extends Selection { +final class Chunk extends Selection { /// The literal text output for the chunk. @override String get text => _text; @@ -195,7 +195,7 @@ class Chunk extends Selection { /// | |- Chunk "element," /// | '- (text) "];" /// '- (text) "}" -class BlockChunk extends Chunk { +final class BlockChunk extends Chunk { /// If this block is for a collection literal in an argument list, this will /// be the chunk preceding this literal argument. /// @@ -241,7 +241,7 @@ class BlockChunk extends Chunk { /// The in-progress state for a [Span] that has been started but has not yet /// been completed. -class OpenSpan { +final class OpenSpan { /// Index of the first chunk contained in this span. final int start; @@ -268,7 +268,7 @@ class OpenSpan { /// Spans can be marked during processing in an algorithm but should be left /// unmarked when the algorithm finishes to make marking work in subsequent /// calls. -class Span extends FastHash with Markable { +final class Span with FastHash, Markable { /// The cost applied when the span is split across multiple lines or `null` /// if the span is for a multisplit. final int cost; diff --git a/lib/src/short/chunk_builder.dart b/lib/src/short/chunk_builder.dart index a9620c6d..eecb9d37 100644 --- a/lib/src/short/chunk_builder.dart +++ b/lib/src/short/chunk_builder.dart @@ -24,7 +24,7 @@ final _trailingIdentifierChar = RegExp(r'[a-zA-Z0-9_]$'); /// Keeps track of leading indentation, expression nesting, and all of the hairy /// code required to seamlessly integrate existing comments into the pure /// output produced by [SourceVisitor]. -class ChunkBuilder { +final class ChunkBuilder { final DartFormatter _formatter; /// The builder for the code surrounding the block that this writer is for, or diff --git a/lib/src/short/fast_hash.dart b/lib/src/short/fast_hash.dart index 30ebf68d..9244e787 100644 --- a/lib/src/short/fast_hash.dart +++ b/lib/src/short/fast_hash.dart @@ -4,7 +4,7 @@ /// A mixin for classes with identity equality that need to be frequently /// hashed. -abstract class FastHash { +mixin FastHash { static int _nextId = 0; /// A semi-unique numeric identifier for the object. diff --git a/lib/src/short/line_splitting/line_splitter.dart b/lib/src/short/line_splitting/line_splitter.dart index 63e46023..25d58d41 100644 --- a/lib/src/short/line_splitting/line_splitter.dart +++ b/lib/src/short/line_splitting/line_splitter.dart @@ -93,7 +93,7 @@ const _maxAttempts = 5000; /// require a lot of exploring to find an optimal solution. To make that fast, /// this code is carefully profiled and optimized. If you modify this, make /// sure to test against the benchmark to ensure you don't regress performance. -class LineSplitter { +final class LineSplitter { final LineWriter writer; /// The list of chunks being split. diff --git a/lib/src/short/line_splitting/rule_set.dart b/lib/src/short/line_splitting/rule_set.dart index 0f6ef8e5..b2ffade7 100644 --- a/lib/src/short/line_splitting/rule_set.dart +++ b/lib/src/short/line_splitting/rule_set.dart @@ -12,7 +12,7 @@ import '../rule/rule.dart'; /// /// Internally, this then just stores the values in a sparse list whose indices /// are the indices of the rules. -class RuleSet { +final class RuleSet { List _values; RuleSet(int numRules) : this._(List.filled(numRules, null)); @@ -126,7 +126,7 @@ class RuleSet { /// Internally, this uses a list where each element corresponds to the column /// of the chunk at that index in the chunk list, or `-1` if that chunk did not /// split. This had about a 10% perf improvement over using a [Set] of splits. -class SplitSet { +final class SplitSet { final List _columns; /// The cost of the solution that led to these splits. diff --git a/lib/src/short/line_splitting/solve_state.dart b/lib/src/short/line_splitting/solve_state.dart index 6fdda7f9..95aab4c1 100644 --- a/lib/src/short/line_splitting/solve_state.dart +++ b/lib/src/short/line_splitting/solve_state.dart @@ -22,7 +22,7 @@ import 'rule_set.dart'; /// From a given solve state, we can explore the search tree to more refined /// solve states by producing new ones that add more bound rules to the current /// state. -class SolveState { +final class SolveState { final LineSplitter _splitter; final RuleSet _ruleValues; diff --git a/lib/src/short/line_splitting/solve_state_queue.dart b/lib/src/short/line_splitting/solve_state_queue.dart index 7605037e..ce423463 100644 --- a/lib/src/short/line_splitting/solve_state_queue.dart +++ b/lib/src/short/line_splitting/solve_state_queue.dart @@ -14,7 +14,7 @@ import 'solve_state.dart'; /// States are stored internally in a heap ordered by cost, the number of /// overflow characters. When a new state is added to the heap, it will be /// discarded, or a previously enqueued one will be discarded, if two overlap. -class SolveStateQueue { +final class SolveStateQueue { /// Initial capacity of a queue when created. /// /// Number can be any positive value. Picking a size that gives a whole diff --git a/lib/src/short/line_writer.dart b/lib/src/short/line_writer.dart index c0f54430..d3f4850c 100644 --- a/lib/src/short/line_writer.dart +++ b/lib/src/short/line_writer.dart @@ -8,7 +8,7 @@ import 'line_splitting/line_splitter.dart'; /// Given a series of chunks, splits them into lines and writes the result to /// a buffer. -class LineWriter { +final class LineWriter { final _buffer = StringBuffer(); final List _chunks; @@ -208,7 +208,7 @@ class LineWriter { /// 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 { +final class _BlockKey { /// The index of the chunk in the surrounding chunk list that contains this /// block. final Chunk chunk; @@ -229,7 +229,7 @@ class _BlockKey { } /// The result of formatting a series of chunks. -class FormatResult { +final class FormatResult { /// The resulting formatted text, including newlines and leading whitespace /// to reach the proper column. final String text; diff --git a/lib/src/short/nesting_builder.dart b/lib/src/short/nesting_builder.dart index 56bc6a1f..1cef90b9 100644 --- a/lib/src/short/nesting_builder.dart +++ b/lib/src/short/nesting_builder.dart @@ -12,7 +12,7 @@ import 'nesting_level.dart'; /// stratified from each other. Expression nesting is always inside block /// indentation, which means it is an error to try to change the block /// indentation while any expression nesting is in effect. -class NestingBuilder { +final class NestingBuilder { /// The block indentation levels. /// /// This is tracked as a stack of numbers, each of which is the total number diff --git a/lib/src/short/nesting_level.dart b/lib/src/short/nesting_level.dart index 65306d5a..0040233f 100644 --- a/lib/src/short/nesting_level.dart +++ b/lib/src/short/nesting_level.dart @@ -24,7 +24,7 @@ import 'marking_scheme.dart'; /// NestingLEvels can be marked during processing in an algorithm but should be /// left unmarked when the algorithm finishes to make marking work in subsequent /// calls. -class NestingLevel extends FastHash with Markable { +final class NestingLevel with FastHash, Markable { /// The nesting level surrounding this one, or `null` if this is represents /// top level code in a block. final NestingLevel? parent; diff --git a/lib/src/short/rule/argument.dart b/lib/src/short/rule/argument.dart index 0aa16485..f082642b 100644 --- a/lib/src/short/rule/argument.dart +++ b/lib/src/short/rule/argument.dart @@ -5,7 +5,7 @@ import '../chunk.dart'; import 'rule.dart'; /// Base class for a rule that handles argument or parameter lists. -abstract class ArgumentRule extends SplitContainingRule { +abstract base class ArgumentRule extends SplitContainingRule { /// The chunks prior to each positional argument. final List _arguments = []; @@ -33,7 +33,7 @@ abstract class ArgumentRule extends SplitContainingRule { /// Finally, if there are collection arguments, there is another value that /// splits before all of the non-collection arguments, but does not split /// before the collections, so that they can split internally. -class PositionalRule extends ArgumentRule { +final class PositionalRule extends ArgumentRule { /// The number of leading collection arguments. /// /// This and [_trailingCollections] cannot both be positive. If every @@ -163,7 +163,7 @@ class PositionalRule extends ArgumentRule { /// * Do not split at all. /// * Split only before first argument. /// * Split before all arguments. -class NamedRule extends ArgumentRule { +final class NamedRule extends ArgumentRule { @override int get numValues => 3; diff --git a/lib/src/short/rule/combinator.dart b/lib/src/short/rule/combinator.dart index c4529471..97330946 100644 --- a/lib/src/short/rule/combinator.dart +++ b/lib/src/short/rule/combinator.dart @@ -42,7 +42,7 @@ import 'rule.dart'; /// /// This ensures that when any wrapping occurs, the keywords are always at /// the beginning of the line. -class CombinatorRule extends Rule { +final class CombinatorRule extends Rule { /// The set of chunks before the combinators. final _combinators = {}; diff --git a/lib/src/short/rule/rule.dart b/lib/src/short/rule/rule.dart index 7214fddb..393d48d7 100644 --- a/lib/src/short/rule/rule.dart +++ b/lib/src/short/rule/rule.dart @@ -9,7 +9,7 @@ import '../fast_hash.dart'; /// A constraint that determines the different ways a related set of chunks may /// be split. -class Rule extends FastHash { +base class Rule with FastHash { /// The rule used for dummy chunks. static final Rule dummy = Rule.hard(); @@ -219,7 +219,7 @@ class Rule extends FastHash { } /// A rule that may contain splits which don't force it to split. -class SplitContainingRule extends Rule { +base class SplitContainingRule extends Rule { /// If true, then inner rules that are written will force this rule to split. /// /// Temporarily disabled while writing collection arguments so that they can @@ -248,7 +248,7 @@ class SplitContainingRule extends Rule { /// /// If the first rule's selected value is within [min], [max] (inclusive), then /// the other rule's value is forced to be [otherValue]. -class _Constraint { +final class _Constraint { /// The minimum of the range of values that rule can have to enable the /// constraint. final int min; diff --git a/lib/src/short/rule/type_argument.dart b/lib/src/short/rule/type_argument.dart index 170757e1..d6e50b7d 100644 --- a/lib/src/short/rule/type_argument.dart +++ b/lib/src/short/rule/type_argument.dart @@ -19,7 +19,7 @@ import 'rule.dart'; /// /// If there is only one type argument, the last two cases collapse and there /// are only two values. -class TypeArgumentRule extends Rule { +final class TypeArgumentRule extends Rule { /// The chunks prior to each positional type argument. final List _arguments = []; diff --git a/lib/src/short/selection.dart b/lib/src/short/selection.dart index 2174e34c..aab851e0 100644 --- a/lib/src/short/selection.dart +++ b/lib/src/short/selection.dart @@ -4,7 +4,7 @@ /// A region of text selected by an optional start and end index, measured in /// UTF-16 code units. -abstract class Selection { +abstract base class Selection { /// The chunk of text. String get text; diff --git a/lib/src/short/source_comment.dart b/lib/src/short/source_comment.dart index b9925129..86dba7b6 100644 --- a/lib/src/short/source_comment.dart +++ b/lib/src/short/source_comment.dart @@ -6,7 +6,7 @@ import 'selection.dart'; /// A comment in the source, with a bit of information about the surrounding /// whitespace. -class SourceComment extends Selection { +final class SourceComment extends Selection { /// The text of the comment, including `//`, `/*`, and `*/`. @override final String text; diff --git a/lib/src/short/source_visitor.dart b/lib/src/short/source_visitor.dart index 4b964af7..42a5039a 100644 --- a/lib/src/short/source_visitor.dart +++ b/lib/src/short/source_visitor.dart @@ -26,7 +26,7 @@ import 'source_comment.dart'; /// Visits every token of the AST and passes all of the relevant bits to a /// [ChunkBuilder]. -class SourceVisitor extends ThrowingAstVisitor { +final class SourceVisitor extends ThrowingAstVisitor { /// The builder for the block that is currently being visited. ChunkBuilder builder; @@ -4298,7 +4298,7 @@ class SourceVisitor extends ThrowingAstVisitor { /// Used to share formatting logic between binary operators, logic operators, /// logic patterns, etc. // TODO: Remove this and just use a record when those are available. -class BinaryNode { +final class BinaryNode { final AstNode left; final Token operator; final AstNode right; diff --git a/lib/src/source_code.dart b/lib/src/source_code.dart index 54049df2..246cab18 100644 --- a/lib/src/source_code.dart +++ b/lib/src/source_code.dart @@ -4,7 +4,7 @@ /// Describes a chunk of source code that is to be formatted or has been /// formatted. -class SourceCode { +final class SourceCode { /// The [uri] where the source code is from. /// /// Used in error messages if the code cannot be parsed. diff --git a/lib/src/testing/benchmark.dart b/lib/src/testing/benchmark.dart index 92f07fb6..d4559435 100644 --- a/lib/src/testing/benchmark.dart +++ b/lib/src/testing/benchmark.dart @@ -6,7 +6,7 @@ import 'dart:io'; import 'package:path/path.dart' as p; -class Benchmark { +final class Benchmark { /// Finds all of the benchmarks in the `benchmark/cases` directory, relative /// to [packageDirectory]. static List findAll(String packageDirectory) { diff --git a/lib/src/testing/test_file.dart b/lib/src/testing/test_file.dart index 01a3eec4..a00a4504 100644 --- a/lib/src/testing/test_file.dart +++ b/lib/src/testing/test_file.dart @@ -34,7 +34,7 @@ Future findTestDirectory() async { } /// A file containing a series of formatting tests. -class TestFile { +final class TestFile { /// Finds all test files in the given directory relative to the package's /// `test/` directory. static Future> listDirectory(String name) async { @@ -174,7 +174,7 @@ class TestFile { } /// A single formatting test inside a [TestFile]. -class FormatTest { +final class FormatTest { /// The unformatted input. final SourceCode input;