Skip to content

Commit ca019b0

Browse files
authored
Use "@Dart=" comment when determining which style rules to apply. (#1766)
Use "@Dart=" comment when determining which style rules to apply. The formatter correctly used those comments to switch between the old short and new tall style, but ignored them for language versioned style rule changes after 3.7. Now the language version of the file is consistently respected for all style rules. In the process of fixing this, I made two other clean-ups: * Introduce a FormattingStyle class separate from DartFormatter. The latter had dual use as both the public API used to configure formatting and the internal object passed around by the formatter to access that configuration. That was annoying because it meant I couldn't hang handy utility methods that the implementation wants off that class because it's public. And it meant that I couldn't change what state it stored (like the language version from the "@Dart" comment) without it being a breaking API change. Now there is a separate internal class that wraps the DartFormatter that can contain that logic. By consistently passing that around and not the DartFormatter, it ensures that code can't accidentally forget to use the language version in the "@Dart" comment. * Pick a consistent naming convention for version numbers in identifiers. When we shipped Dart 3.8, a bunch of style rules changed. I needed a way to refer to the older style and couldn't come up with anything better than "3.7". But you can't have a dot in identifier, so I did "37". With Dart 3.10 on the horizon, that doesn't make sense: "310" is confusing and ambiguous. I considered "3_7", but that violates the lint for type names which shouldn't contain "_". Went with "3Dot7" instead which I don't love but seems to work. Fix #1762.
1 parent 3499c1e commit ca019b0

18 files changed

+239
-151
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@
1212
* Don't force a space between `?` and `.` if a null-aware element contains a
1313
dot shorthand.
1414

15+
### Bug fixes
16+
17+
* Respect `@dart=` version comments when determining which >3.7 style to apply.
18+
The formatter correctly used those comments to switch between the old short
19+
and new tall style, but ignored them for language versioned style rule changes
20+
after 3.7. Now the language version of the file is consistently respected for
21+
all style rules (#1762).
22+
1523
## 3.1.2
1624

1725
* Support dot shorthand syntax.

benchmark/run.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import 'package:args/args.dart';
1212
import 'package:dart_style/dart_style.dart';
1313
import 'package:dart_style/src/debug.dart' as debug;
1414
import 'package:dart_style/src/front_end/ast_node_visitor.dart';
15+
import 'package:dart_style/src/front_end/formatting_style.dart';
1516
import 'package:dart_style/src/profile.dart';
1617
import 'package:dart_style/src/short/source_visitor.dart';
1718
import 'package:dart_style/src/testing/benchmark.dart';
@@ -172,7 +173,11 @@ double _runTrial(
172173
var visitor = SourceVisitor(formatter, parseResult.lineInfo, source);
173174
result = visitor.run(parseResult.unit).text;
174175
} else {
175-
var visitor = AstNodeVisitor(formatter, parseResult.lineInfo, source);
176+
var visitor = AstNodeVisitor(
177+
FormattingStyle(formatter),
178+
parseResult.lineInfo,
179+
source,
180+
);
176181
result = visitor.run(source, parseResult.unit).text;
177182
}
178183
}

lib/src/ast_extensions.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ extension AdjacentStringsExtensions on AdjacentStrings {
458458
///
459459
/// To balance these, we omit the indentation when an adjacent string
460460
/// expression is in a context where it's unlikely to be confusing.
461-
bool get indentStringsV37 {
461+
bool get indentStrings3Dot7 {
462462
return switch (parent) {
463463
ArgumentList(:var arguments) => _hasOtherStringArgument(arguments),
464464

lib/src/back_end/code_writer.dart

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ final class CodeWriter {
154154
/// Increases the indentation by [indent] relative to the current amount of
155155
/// indentation.
156156
void pushIndent(Indent indent) {
157-
if (_cache.isVersion37) {
158-
_pushIndentV37(indent);
157+
if (_cache.is3Dot7) {
158+
_pushIndent3Dot7(indent);
159159
} else {
160160
var parent = _indentStack.last;
161161

@@ -191,8 +191,8 @@ final class CodeWriter {
191191
/// This is only used in a couple of corners of if-case and for-in headers
192192
/// where the indentation is unusual.
193193
void pushCollapsibleIndent() {
194-
if (_cache.isVersion37) {
195-
_pushIndentV37(Indent.expression, canCollapse: true);
194+
if (_cache.is3Dot7) {
195+
_pushIndent3Dot7(Indent.expression, canCollapse: true);
196196
} else {
197197
pushIndent(Indent.controlFlowClause);
198198
}
@@ -228,26 +228,26 @@ final class CodeWriter {
228228
/// To deal with this, 3.7 had a notion of "collapsible" indentation. In 3.8
229229
/// and later, there is a different mechanism for merging indentation kinds.
230230
/// This function implements the former.
231-
void _pushIndentV37(Indent indent, {bool canCollapse = false}) {
231+
void _pushIndent3Dot7(Indent indent, {bool canCollapse = false}) {
232232
var parentIndent = _indentStack.last.spaces;
233233
var parentCollapse = _indentStack.last.collapsible;
234234

235235
if (parentCollapse == indent.spaces) {
236236
// We're indenting by the same existing collapsible amount, so collapse
237237
// this new indentation with that existing one.
238-
_indentStack.add(_IndentLevel.v37(parentIndent, 0));
238+
_indentStack.add(_IndentLevel.v3Dot7(parentIndent, 0));
239239
} else if (canCollapse) {
240240
// We should never get multiple levels of nested collapsible indentation.
241241
assert(parentCollapse == 0);
242242

243243
// Increase the indentation and note that it can be collapsed with
244244
// further indentation.
245245
_indentStack.add(
246-
_IndentLevel.v37(parentIndent + indent.spaces, indent.spaces),
246+
_IndentLevel.v3Dot7(parentIndent + indent.spaces, indent.spaces),
247247
);
248248
} else {
249249
// Regular indentation, so just increase the indent.
250-
_indentStack.add(_IndentLevel.v37(parentIndent + indent.spaces, 0));
250+
_indentStack.add(_IndentLevel.v3Dot7(parentIndent + indent.spaces, 0));
251251
}
252252
}
253253

@@ -399,7 +399,7 @@ final class CodeWriter {
399399
);
400400

401401
bool invalid;
402-
if (_cache.isVersion37) {
402+
if (_cache.is3Dot7) {
403403
// If the child must be inline, then invalidate because we know it
404404
// contains some kind of newline.
405405
// TODO(rnystrom): It would be better if this logic wasn't different for
@@ -640,7 +640,7 @@ final class _IndentLevel {
640640
/// Only used for 3.7 style.
641641
final int collapsible;
642642

643-
_IndentLevel.v37(this.spaces, this.collapsible) : type = Indent.none;
643+
_IndentLevel.v3Dot7(this.spaces, this.collapsible) : type = Indent.none;
644644

645645
_IndentLevel(this.type, this.spaces) : collapsible = 0;
646646

lib/src/back_end/solution_cache.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ import 'solver.dart';
2424
/// cached subtree Solution.
2525
final class SolutionCache {
2626
/// Whether this cache and all solutions in it use the 3.7 style solver.
27-
final bool isVersion37;
27+
final bool is3Dot7;
2828

2929
final _cache = <_Key, Solution>{};
3030

31-
SolutionCache({required bool version37}) : isVersion37 = version37;
31+
SolutionCache({required this.is3Dot7});
3232

3333
/// Returns a previously cached solution for formatting [root] with leading
3434
/// [indent] (and [subsequentIndent] for lines after the first) or produces a

lib/src/dart_formatter.dart

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import 'package:pub_semver/pub_semver.dart';
1717

1818
import 'exceptions.dart';
1919
import 'front_end/ast_node_visitor.dart';
20+
import 'front_end/formatting_style.dart';
2021
import 'short/source_visitor.dart';
2122
import 'source_code.dart';
2223
import 'string_compare.dart' as string_compare;
@@ -233,8 +234,16 @@ final class DartFormatter {
233234
}
234235
}
235236

236-
var visitor = AstNodeVisitor(this, lineInfo, unitSourceCode);
237-
output = visitor.run(unitSourceCode, node, pageWidthFromComment);
237+
var visitor = AstNodeVisitor(
238+
FormattingStyle(
239+
this,
240+
languageVersion: sourceLanguageVersion,
241+
pageWidth: pageWidthFromComment,
242+
),
243+
lineInfo,
244+
unitSourceCode,
245+
);
246+
output = visitor.run(unitSourceCode, node);
238247
} else {
239248
// Use the old style.
240249
var visitor = SourceVisitor(this, lineInfo, unitSourceCode);

0 commit comments

Comments
 (0)