Skip to content

Commit 38eedb3

Browse files
committed
Merge branch 'main' into comment-after-metadata
2 parents bee1256 + 154537e commit 38eedb3

File tree

16 files changed

+237
-211
lines changed

16 files changed

+237
-211
lines changed

CHANGELOG.md

Lines changed: 99 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,87 @@
11
## 3.0.0-wip
22

3+
This is a large change. Under the hood, the formatter was almost completely
4+
rewritten, with the codebase now containing both the old and new
5+
implementations. The old formatter exists to support the older "short" style
6+
and the new code implements [the new "tall" style][tall].
7+
8+
[tall]: https://github.com/dart-lang/dart_style/issues/1253
9+
10+
The formatter uses the language version of the formatted code to determine
11+
which style you get. If the language version is 3.6 or lower, the code is
12+
formatted with the old style. If 3.7 or later, you get the new tall style. You
13+
typically control the language version by [setting a min SDK constraint in your
14+
package's pubspec][versioning].
15+
16+
[versioning]: https://dart.dev/guides/language/evolution
17+
18+
In addition to the new formatting style, a number of other API and CLI changes
19+
are included, some of them breaking:
20+
21+
* **Support project-wide page width configuration.** By long request, you can
22+
now configure your preferred formatting page width on a project-wide basis.
23+
When formatting files, the formatter will look in the file's directory and
24+
any surrounding directories for an `analysis_options.yaml` file. If it finds
25+
one, it looks for the following YAML:
26+
27+
```yaml
28+
formatter:
29+
page_width: 123
30+
```
31+
32+
If it finds a `formatter` key containing a map with a `page_width` key whose
33+
value is an integer, then that is the page width that the file is formatted
34+
using. Since the formatter will walk the surrounding directories until it
35+
finds an `analysis_options.yaml` file, this can be used to globally set the
36+
page width for an entire directory, package, or even collection of packages.
37+
38+
* **Support overriding the page width for a single file.** In code formatted
39+
using the new tall style, you can use a special marker comment to control the
40+
page width that it's formatted using:
41+
42+
```dart
43+
// dart format width=30
44+
main() {
45+
someExpression +
46+
thatSplitsAt30;
47+
}
48+
```
49+
50+
This comment must appear before any code in the file and must match that
51+
format exactly. The width set by the comment overrides the width set by any
52+
surrounding `analysis_options.yaml` file.
53+
54+
This feature is mainly for code generators that generate and immediately
55+
format code but don't know about any surrounding `analysis_options.yaml`
56+
that might be configuring the page width. By inserting this comment in the
57+
generated code before formatting, it ensures that the code generator's
58+
behavior matches the behavior of `dart format`.
59+
60+
End users should mostly use `analysis_options.yaml` for configuring their
61+
preferred page width (or do nothing and use the default page width of 80).
62+
63+
* **Support opting out a region of code from formatting.** In code formatted
64+
using the new tall style, you can use a pair of special marker comments to
65+
opt a region of code out of automated formatting:
66+
67+
```dart
68+
main() {
69+
this.isFormatted();
70+
// dart format off
71+
no + formatting
72+
+
73+
here;
74+
// dart format on
75+
formatting.isBackOnHere();
76+
}
77+
```
78+
79+
The comments must be exactly `// dart format off` and `// dart format on`.
80+
A file may have multiple regions, but they can't overlap or nest.
81+
82+
This can be useful for highly structured data where custom layout can help
83+
a reader understand the data, like large lists of numbers.
84+
385
* **Remove support for fixes and `--fix`.** The tools that come with the Dart
486
SDK provide two ways to apply automated changes to code: `dart format --fix`
587
and `dart fix`. The former is older and used to be faster. But it can only
@@ -16,31 +98,29 @@
1698

1799
* **Make the language version parameter to `DartFormatter()` mandatory.** This
18100
way, the formatter always knows what language version the input is intended
19-
to be treated as. Note that a `// @dart=` language version comment if present
20-
overrides the specified language version. You can think of the version passed
21-
to the `DartFormatter()` constructor as a "default" language version which
22-
the file's contents may then override.
101+
to be treated as. Note that a `// @dart=` language version comment, if
102+
present, overrides the specified language version. You can think of the
103+
version passed to the `DartFormatter()` constructor as a "default" language
104+
version which the file's contents may then override.
23105

24106
If you don't particularly care about the version of what you're formatting,
25107
you can pass in `DartFormatter.latestLanguageVersion` to unconditionally get
26108
the latest language version that the formatter supports. Note that doing so
27-
means you will also implicitly opt into the new tall style when that style
28-
becomes available.
109+
means you will also implicitly opt into the new tall style.
29110

30111
This change only affects the library API. When using the formatter from the
31112
command line, you can use `--language-version=` to specify a language version
32113
or pass `--language-version=latest` to use the latest supported version. If
33-
omitted, the formatter will look up the surrounding directories for a package
114+
omitted, the formatter will look in the surrounding directories for a package
34115
config file and infer the language version for the package from that, similar
35116
to how other Dart tools behave like `dart analyze` and `dart run`.
36117

37118
* **Remove the old formatter executables and CLI options.** Before the
38119
`dart format` command was added to the core Dart SDK, users accessed the
39120
formatter by running a separate `dartfmt` executable that was included with
40121
the Dart SDK. That executable had a different CLI interface. For example, you
41-
had to pass `-w` to get it to overwrite files and if you passed no arguments
42-
at all, it silently sat there waiting for input on stdin. When we added
43-
`dart format`, we took that opportunity to revamp the CLI options.
122+
had to pass `-w` to get it to overwrite files. When we added `dart format`,
123+
we took that opportunity to revamp the CLI options.
44124

45125
However, the dart_style package still exposed an executable with the old CLI.
46126
If you ran `dart pub global activate dart_style`, this would give you a
@@ -64,25 +144,25 @@
64144
`--language-version=`, or use `--language-version=latest` to parse the input
65145
using the latest language version supported by the formatter.
66146

67-
If `--stdin-name` and `--language-version` are both omitted, then parses
68-
stdin using the latest supported language version.
69-
70-
* **Apply class modifiers to API classes.** The dart_style package exposes only
71-
a few classes in its public API: `DartFormatter`, `SourceCode`,
72-
`FormatterException`, and `UnexpectedOutputException`. None were ever
73-
intended to be extended or implemented. They are now all marked `final` to
74-
make that intention explicit.
147+
If `--stdin-name` and `--language-version` are both omitted, then the
148+
formatter parses stdin using the latest supported language version.
75149

76150
* **Rename the `--line-length` option to `--page-width`.** This is consistent
77151
with the public API, internal implementation, and docs, which all use "page
78152
width" to refer to the limit that the formatter tries to fit code into.
79153

80154
The `--line-length` name is still supported for backwards compatibility, but
81155
may be removed at some point in the future. You're encouraged to move to
82-
`--page-width`. Use of this option (however its named) is rare, and will
156+
`--page-width`. Use of this option (however it's named) is rare, and will
83157
likely be even rarer now that project-wide configuration is supported, so
84158
this shouldn't affect many users.
85159

160+
* **Apply class modifiers to API classes.** The dart_style package exposes only
161+
a few classes in its public API: `DartFormatter`, `SourceCode`,
162+
`FormatterException`, and `UnexpectedOutputException`. None were ever
163+
intended to be extended or implemented. They are now all marked `final` to
164+
make that intention explicit.
165+
86166
## 2.3.7
87167

88168
* Allow passing a language version to `DartFomatter()`. Formatted code will be

benchmark/directory.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import 'dart:io';
77
import 'package:args/args.dart';
88
import 'package:collection/collection.dart';
99
import 'package:dart_style/dart_style.dart';
10-
import 'package:dart_style/src/constants.dart';
1110
import 'package:dart_style/src/profile.dart';
1211
import 'package:dart_style/src/testing/benchmark.dart';
1312

@@ -64,8 +63,9 @@ void main(List<String> arguments) async {
6463
void _runFormatter(String source) {
6564
try {
6665
var formatter = DartFormatter(
67-
languageVersion: DartFormatter.latestLanguageVersion,
68-
experimentFlags: [if (!_isShort) tallStyleExperimentFlag]);
66+
languageVersion: _isShort
67+
? DartFormatter.latestShortStyleLanguageVersion
68+
: DartFormatter.latestLanguageVersion);
6969

7070
var result = formatter.format(source);
7171

benchmark/run.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import 'package:analyzer/dart/analysis/results.dart';
1010
import 'package:analyzer/dart/analysis/utilities.dart';
1111
import 'package:args/args.dart';
1212
import 'package:dart_style/dart_style.dart';
13-
import 'package:dart_style/src/constants.dart';
1413
import 'package:dart_style/src/debug.dart' as debug;
1514
import 'package:dart_style/src/front_end/ast_node_visitor.dart';
1615
import 'package:dart_style/src/profile.dart';
@@ -131,10 +130,11 @@ List<double> _runTrials(String verb, Benchmark benchmark, int trials) {
131130
throwIfDiagnostics: false);
132131

133132
var formatter = DartFormatter(
134-
languageVersion: DartFormatter.latestLanguageVersion,
133+
languageVersion: _isShort
134+
? DartFormatter.latestShortStyleLanguageVersion
135+
: DartFormatter.latestLanguageVersion,
135136
pageWidth: benchmark.pageWidth,
136-
lineEnding: '\n',
137-
experimentFlags: [if (!_isShort) tallStyleExperimentFlag]);
137+
lineEnding: '\n');
138138

139139
var measuredTimes = <double>[];
140140
for (var i = 1; i <= trials; i++) {

example/format.dart

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'package:dart_style/dart_style.dart';
6-
import 'package:dart_style/src/constants.dart';
76
import 'package:dart_style/src/debug.dart' as debug;
87
import 'package:dart_style/src/testing/test_file.dart';
98

@@ -40,9 +39,10 @@ void _runFormatter(String source, int pageWidth,
4039
{required bool tall, required bool isCompilationUnit}) {
4140
try {
4241
var formatter = DartFormatter(
43-
languageVersion: DartFormatter.latestLanguageVersion,
44-
pageWidth: pageWidth,
45-
experimentFlags: [if (tall) tallStyleExperimentFlag]);
42+
languageVersion: tall
43+
? DartFormatter.latestLanguageVersion
44+
: DartFormatter.latestShortStyleLanguageVersion,
45+
pageWidth: pageWidth);
4646

4747
String result;
4848
if (isCompilationUnit) {
@@ -75,10 +75,7 @@ Future<void> _runTest(String path, int line,
7575
var formatter = DartFormatter(
7676
languageVersion: formatTest.languageVersion,
7777
pageWidth: testFile.pageWidth,
78-
indent: formatTest.leadingIndent,
79-
experimentFlags: tall
80-
? const ['inline-class', tallStyleExperimentFlag]
81-
: const ['inline-class']);
78+
indent: formatTest.leadingIndent);
8279

8380
var actual = formatter.formatSource(formatTest.input);
8481

lib/src/cli/format_command.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,7 @@ final class FormatCommand extends Command<int> {
6969
help: 'Language version of formatted code.\n'
7070
'Use "latest" to parse as the latest supported version.\n'
7171
'Omit to look for a surrounding package config.',
72-
// TODO(rnystrom): Show this when the tall-style experiment ships.
73-
hide: true);
72+
hide: !verbose);
7473

7574
argParser.addFlag('set-exit-if-changed',
7675
negatable: false,

lib/src/config_cache.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ final class ConfigCache {
6262
// Otherwise, walk the file system and look for it.
6363
var config =
6464
await _findPackageConfig(file, displayPath, forLanguageVersion: true);
65+
6566
if (config?.packageOf(file.absolute.uri)?.languageVersion
6667
case var languageVersion?) {
6768
// Store the version as pub_semver's [Version] type because that's

lib/src/constants.dart

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,6 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5-
/// The in-progress "tall" formatting style is enabled by passing an experiment
6-
/// flag with this name.
7-
///
8-
/// Note that this isn't a real Dart SDK experiment: Only the formatter supports
9-
/// it. We use the [experimentFlags] API to pass this in so that support for it
10-
/// can be removed in a later version without it being a breaking change to the
11-
/// dart_style library API.
12-
const tallStyleExperimentFlag = 'tall-style';
13-
145
/// Constants for the cost heuristics used to determine which set of splits is
156
/// most desirable.
167
final class Cost {

lib/src/dart_formatter.dart

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import 'package:analyzer/src/dart/scanner/scanner.dart';
1414
import 'package:analyzer/src/string_source.dart';
1515
import 'package:pub_semver/pub_semver.dart';
1616

17-
import 'constants.dart';
1817
import 'exceptions.dart';
1918
import 'front_end/ast_node_visitor.dart';
2019
import 'short/source_visitor.dart';
@@ -30,7 +29,14 @@ final RegExp _widthCommentPattern = RegExp(r'^// dart format width=(\d+)$');
3029
final class DartFormatter {
3130
/// The latest Dart language version that can be parsed and formatted by this
3231
/// version of the formatter.
33-
static final latestLanguageVersion = Version(3, 3, 0);
32+
static final latestLanguageVersion = Version(3, 7, 0);
33+
34+
/// The latest Dart language version that will be formatted using the older
35+
/// "short" style.
36+
///
37+
/// Any Dart code at a language version later than this will be formatted
38+
/// using the new "tall" style.
39+
static final latestShortStyleLanguageVersion = Version(3, 6, 0);
3440

3541
/// The page width that the formatter tries to fit code inside if no other
3642
/// width is specified.
@@ -125,11 +131,8 @@ final class DartFormatter {
125131
);
126132
}
127133

128-
// Don't pass the formatter's own experiment flag to the parser.
129-
var experiments = experimentFlags.toList();
130-
experiments.remove(tallStyleExperimentFlag);
131134
var featureSet = FeatureSet.fromEnableFlags2(
132-
sdkLanguageVersion: languageVersion, flags: experiments);
135+
sdkLanguageVersion: languageVersion, flags: experimentFlags);
133136

134137
// Parse it.
135138
var parseResult = parseString(
@@ -185,8 +188,9 @@ final class DartFormatter {
185188
// Format it.
186189
var lineInfo = parseResult.lineInfo;
187190

191+
// Use language version to determine what formatting style to apply.
188192
SourceCode output;
189-
if (experimentFlags.contains(tallStyleExperimentFlag)) {
193+
if (languageVersion > latestShortStyleLanguageVersion) {
190194
// Look for a page width comment before the code.
191195
int? pageWidthFromComment;
192196
for (Token? comment = node.beginToken.precedingComments;
@@ -203,6 +207,7 @@ final class DartFormatter {
203207
var visitor = AstNodeVisitor(this, lineInfo, unitSourceCode);
204208
output = visitor.run(unitSourceCode, node, pageWidthFromComment);
205209
} else {
210+
// Use the old style.
206211
var visitor = SourceVisitor(this, lineInfo, unitSourceCode);
207212
output = visitor.run(node);
208213
}

0 commit comments

Comments
 (0)