Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up README and TODO comments. #1592

Merged
merged 2 commits into from
Nov 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 55 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
The dart_style package defines an automatic, opinionated formatter for Dart
code. It replaces the whitespace in your program with what it deems to be the
best formatting for it. Resulting code should follow the [Dart style guide][]
but, moreso, should look nice to most human readers, most of the time.
The dart_style package defines an opinionated automated formatter for Dart code.
It replaces the whitespace in your program with what it deems to be the
best formatting for it. It also makes minor changes around non-semantic
punctuation like trailing commas and brackets in parameter lists.

The resulting code should follow the [Dart style guide][] and look nice to most
human readers, most of the time.

[dart style guide]: https://dart.dev/guides/language/effective-dart/style

Expand All @@ -14,80 +17,89 @@ The formatter turns code like this:

```dart
// BEFORE formatting
if (tag=='style'||tag=='script'&&(type==null||type == TYPE_JS
||type==TYPE_DART)||
tag=='link'&&(rel=='stylesheet'||rel=='import')) {}
process = await Process.start(path.join(p.pubCacheBinPath,Platform.isWindows
?'${command.first}.bat':command.first,),[...command.sublist(1),'web:0',
// Allow for binding to a random available port.
],workingDirectory:workingDir,environment:{'PUB_CACHE':p.pubCachePath,'PATH':
path.dirname(Platform.resolvedExecutable)+(Platform.isWindows?';':':')+
Platform.environment['PATH']!,},);
```

into:

```dart
// AFTER formatting
if (tag == 'style' ||
tag == 'script' &&
(type == null || type == TYPE_JS || type == TYPE_DART) ||
tag == 'link' && (rel == 'stylesheet' || rel == 'import')) {}
process = await Process.start(
path.join(
p.pubCacheBinPath,
Platform.isWindows ? '${command.first}.bat' : command.first,
),
[
...command.sublist(1), 'web:0',
// Allow for binding to a random available port.
],
workingDirectory: workingDir,
environment: {
'PUB_CACHE': p.pubCachePath,
'PATH':
path.dirname(Platform.resolvedExecutable) +
(Platform.isWindows ? ';' : ':') +
Platform.environment['PATH']!,
},
);
```

The formatter will never break your code—you can safely invoke it
automatically from build and presubmit scripts.

## Using the formatter
## Formatting files

The formatter is part of the unified [`dart`][] developer tool included in the
Dart SDK, so most users get it directly from there. That has the latest version
of the formatter that was available when the SDK was released.
Dart SDK, so most users run it directly from there using `dart format`.

[`dart`]: https://dart.dev/tools/dart-tool

IDEs and editors that support Dart usually provide easy ways to run the
formatter. For example, in WebStorm you can right-click a .dart file and then
choose **Reformat with Dart Style**.
formatter. For example, in Visual Studio Code, formatting Dart code will use
the dart_style formatter by default. Most users have it set to reformat every
time they save a file.

Here's a simple example of using the formatter on the command line:

$ dart format test.dart

This command formats the `test.dart` file and writes the result to the
file.
```sh
$ dart format my_file.dart
```

`dart format` takes a list of paths, which can point to directories or files. If
the path is a directory, it processes every `.dart` file in that directory or
any of its subdirectories.
This command formats the `my_file.dart` file and writes the result back to the
same file.

By default, it formats each file and write the formatting changes to the files.
If you pass `--output show`, it prints the formatted code to stdout.
The `dart format` command takes a list of paths, which can point to directories
or files. If the path is a directory, it processes every `.dart` file in that
directory and all of its subdirectories.

You may pass a `-l` option to control the width of the page that it wraps lines
to fit within, but you're strongly encouraged to keep the default line length of
80 columns.
By default, `dart format` formats each file and writes the result back to the
same files. If you pass `--output show`, it prints the formatted code to stdout
and doesn't modify the files.

### Validating files
## Validating formatting

If you want to use the formatter in something like a [presubmit script][] or
[commit hook][], you can pass flags to omit writing formatting changes to disk
and to update the exit code to indicate success/failure:

$ dart format --output=none --set-exit-if-changed .
```sh
$ dart format --output=none --set-exit-if-changed .
```

[presubmit script]: https://www.chromium.org/developers/how-tos/depottools/presubmit-scripts
[commit hook]: https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks

## Running other versions of the formatter CLI command

If you need to run a different version of the formatter, you can
[globally activate][] the package from the dart_style package on
pub.dev:

[globally activate]: https://dart.dev/tools/pub/cmd/pub-global

$ pub global activate dart_style
$ pub global run dart_style:format ...
## Using the formatter as a library

## Using the dart_style API
The `dart_style package exposes a simple [library API][] for formatting code.
Basic usage looks like this:

The package also exposes a single dart_style library containing a programmatic
API for formatting code. Simple usage looks like this:
[library api]: https://pub.dev/documentation/dart_style/latest/

```dart
import 'package:dart_style/dart_style.dart';
Expand Down
7 changes: 6 additions & 1 deletion lib/src/dart_formatter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ import 'string_compare.dart' as string_compare;
/// // dart format width=123
final RegExp _widthCommentPattern = RegExp(r'^// dart format width=(\d+)$');

/// Dart source code formatter.
/// A Dart source code formatter.
///
/// This is a lightweight class that mostly bundles formatting options so that
/// you don't have to pass a long argument list to [format()] and
/// [formatStatement()]. You can efficiently create a new instance of this for
/// every format invocation.
final class DartFormatter {
/// The latest Dart language version that can be parsed and formatted by this
/// version of the formatter.
Expand Down
4 changes: 2 additions & 2 deletions lib/src/front_end/piece_factory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ mixin PieceFactory {
// ]) {
// body;
// }
// TODO(tall): Passing `canBlockSplitLeft: true` allows output like:
// TODO(rnystrom): Passing `canBlockSplitLeft: true` allows output like:
//
// // 1
// for (variable in longExpression +
Expand Down Expand Up @@ -900,7 +900,7 @@ mixin PieceFactory {

/// Writes a [Piece] for an index expression.
void writeIndexExpression(IndexExpression index) {
// TODO(tall): Consider whether we should allow splitting between
// TODO(rnystrom): Consider whether we should allow splitting between
// successive index expressions, like:
//
// jsonData['some long key']
Expand Down
15 changes: 5 additions & 10 deletions lib/src/front_end/piece_writer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,11 @@ final class PieceWriter {

if (spaceBefore) space();

// TODO(perf): If [_currentCode] is `null` but [_pendingSpace] is `true`,
// it should be possible to create a new code piece and write the leading
// space to it instead of having a leading SpacePiece. Unfortunately, that
// sometimes leads to duplicate spaces in the output, so it might take some
// tweaking to get working.
// TODO(rnystrom): If [_currentCode] is `null` but [_pendingSpace] is
// `true`, it should be possible to create a new code piece and write the
// leading space to it instead of having a leading SpacePiece.
// Unfortunately, that sometimes leads to duplicate spaces in the output,
// so it might take some tweaking to get working.

if (token.precedingComments != null) {
// Don't append to the previous token if there is a comment after it.
Expand Down Expand Up @@ -269,11 +269,6 @@ final class PieceWriter {
}
}

// TODO(tall): Much of the comment handling code in CommentWriter got moved
// into here, so there isn't great separation of concerns anymore. Can we
// organize this code better? Or just combine CommentWriter with this class
// completely?

/// Creates a new [Piece] for [comment] and returns it.
Piece commentPiece(SourceComment comment,
[Whitespace trailingWhitespace = Whitespace.none]) {
Expand Down
20 changes: 0 additions & 20 deletions lib/src/piece/chain.dart
Original file line number Diff line number Diff line change
Expand Up @@ -53,26 +53,6 @@ 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);

// TODO(tall): Currently, we only allow a single call in the chain to be
// block-formatted, and it must be the last or next-to-last. That covers
// the majority of common use cases (>90% of Flutter call chains), but there
// are some cases (<1%) where it might be good to support multiple block
// calls in a chain, like:
//
// future.then((_) {
// doStuff();
// }).then((_) {
// moreStuff();
// }).catchError((error) {
// print('Oh no!');
// });
//
// Decide if we want to support this and, if so, which calls are allowed to
// be block formatted. A reasonable approach would be to say that multiple
// block calls are allowed when the chain is (possibly zero) leading
// properties followed by only splittable calls and all splittable calls get
// block formatted.

/// Split the call chain at each method call, but leave the leading properties
/// on the same line as the target.
static const State _splitAfterProperties = State(2);
Expand Down
2 changes: 1 addition & 1 deletion lib/src/piece/control_flow.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ final class ControlFlowPiece extends Piece {
writer.splitIf(state == State.split);
}

// TODO(perf): Investigate whether it's worth using `separate:` here.
// TODO(rnystrom): Investigate whether it's worth using `separate:` here.
writer.format(section.statement);

// Reset the indentation for the subsequent `else` or `} else` line.
Expand Down
2 changes: 0 additions & 2 deletions lib/src/piece/piece.dart
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,6 @@ abstract base class Piece {
///
/// This is usually just the state's cost, but some pieces may want to tweak
/// the cost in certain circumstances.
// TODO(tall): Given that we have this API now, consider whether it makes
// sense to remove the cost field from State entirely.
int stateCost(State state) => state.cost;

/// Forces this piece to always use [state].
Expand Down
1 change: 0 additions & 1 deletion lib/src/piece/variable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ final class VariablePiece extends Piece {
// Split between variables.
if (i > 0) writer.splitIf(state != State.unsplit);

// TODO(perf): Investigate whether it's worth using `separate:` here.
writer.format(_variables[i]);
}

Expand Down
12 changes: 6 additions & 6 deletions lib/src/string_compare.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
// 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.

// TODO(tall): Now that the formatter may add and remove trailing commas and
// reposition comments relative to `,`, `[`, `]`, `{`, and `}`, this function
// is getting less and less precise. (For example, a bug in the formatter that
// dropped all `[` tokens on the floor would still pass.) Consider a more
// sophisticated approach for determining that the formatter preserved all of
// the original code.
// TODO(rnystrom): Now that the formatter may add and remove trailing commas
// and reposition comments relative to `,`, `[`, `]`, `{`, and `}`, this
// function is getting less and less precise. (For example, a bug in the
// formatter that dropped all `[` tokens on the floor would still pass.)
// Consider a more sophisticated approach for determining that the formatter
// preserved all of the original code.

/// Returns `true` if [c] represents a whitespace code unit allowed in Dart
/// source code.
Expand Down