-
Notifications
You must be signed in to change notification settings - Fork 120
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
Make the formatter aware of the language version of what it's formatting #1402
Comments
I'm working on this now. One key question is how the formatter should behave when it can't determine the language version of what it's formatting. Cases where that can occur:
Currently, the formatter's behavior is to always format the code as the latest version. When the tall style ships, defaulting to the latest version means it will also default to the tall style. That might be disruptive to users because the same way they used to format code could spontaneously change the style under them. Eventually, this won't be a problem. The ecosystem will move to the new style and they won't see any churn if the formatter defaults to a language version that gives them that style. But I don't know if that's the right behavior when we first launch the new style. OptionsI can think of a few options: Default to the latest language versionThis is what I currently proposed. As the formatter does today, if it doesn't know what language version you want, you get the very latest version that it supports. That means that as soon as we ship the tall style, whenever the formatter doesn't know your language version you will also get the tall style. Require a language versionBecause some folks on the team are rightly worried about unexpected format changes with the above option, they have suggested that the formatter should simply not support formatting code at all when it doesn't clearly know the desired language version. That would mean:
This avoids any user confusion or surprise about what output they get. But it may be that it simply replaces it with user pain. "Format using the latest version" has worked fine 99.99% of the time for the past decade and likely will again once we're through the style migration, so not allowing that at all feels unpleasant. Default to the latest short style versionThere is a middle path which I hadn't considered until now. Let's say we ship the new tall style in Dart 3.7. That means any code whose language version is 3.7 or higher will get the new style. We could say that if you run the formatter and it doesn't know the language version you want, it defaults to 3.6. That means any previously formatted short style code will continue to be formatted using the short style. No formatting disruption. On the other hand it means that if you try to use any new syntax which may appear in Dart 3.7 or later, the formatter will fail because it can't parse the code. Eventually, I intend to sunset and remove support for the short style entirely, even when formatting older language versions. When that happens, we would change this to behavior to again default to the actual latest version supported by the formatter and not the latest short style version. Thoughts, @dart-lang/language-team (or anyone else)? |
I'm pretty sure we already have a "default language version" defined somewhere, which is the language version we use if the Wouldn't it be more consistent to use this as the default for formatting too? |
Yes, I agree this is absolutely correct behavior for the
This is the change I was advocating for. It could be nullable still (which means latest version), or it could force the user to pass in the latest language version explicitly for code which doesn't have an explicit version. But it should be explicit, because all existing usages should be passing in a language version when they have one available. I would suggest releasing this first as an optional parameter, so that packages can migrate to it. Then make it required, with a breaking change. That way the dependency constraint can continue to be |
In this release, would it always apply the short style if you omit the parameter? |
There is no right answer here... but I would probably do the long style. You could set a minimum SDK for the release, which will guarantee only users which might have a package on the latest version would get this behavior, and users on old SDKs will not get weird formatting. But it is really a toss up what you choose, you have no signal to differentiate. |
Fwiw, I would expect the vast majority of people hitting this will be the ones using build_runner, and specifically users of code generators built on the source_gen package, which does formatting by default. Just fixing that one package will probably handle most of the cases. |
I'd be happy either way for
|
OK, I have the DartFormatter class taking a currently optional parameter for the language version. If passed, it uses that language version for parsing. If omitted, it defaults to the latest supported version. In a future commit, I'll bump the major version of dart_style and make that parameter mandatory. The Dart CLI will search the file system for a surrounding package config and use that to infer the language version of the file. You can also pass The hack to try to parse at the latest version and fall back to a pre-patterns version if that fails is still in there. But it only kicks in if the language version is omitted. Once the version is mandatory in DartFormatter, I can remove it. The remaining task is to coordinate with analyzer and other folks using the dart_style library API to get them to start passing in a language version. But first I'll need to publish a new version of dart_style with language version support and roll it into the Dart SDK. |
Fwiw I do think this should be landed prior to the new formatter being shipped in a stable release, if possible. This is just because I have an assumption that nobody outside the people on this thread will know about or use this new parameter until it is required. That does however cover |
We could do this for passing code into |
I think it's harmless to publish a patch release of dart_style with support for the optional language version parameter. It behaves essentially the same way dart_style currently behaves, but it does give users the ability to pass in a version if they want and start migrating to get their code ready for that parameter being mandatory.
Maybe, but I'm always surprised to discover how many users are out there using our stuff in unexpected ways. |
I think using CWD might be surprising, but I'm not sure. My current plan is to just make it mandatory so that users are explicit about what they want. In practice, I don't think stdin support is very widely used. I think maybe the Vim integration relies on it?
Yeah, explicit is clearer. The |
I agree publishing the patch release is harmless (actually, purely has positive value). I also think that publishing the breaking change has positive value though. It will signal to people that there is something to be done. As a package maintainer with many transitive deps, why would you look at the changelog for a patch release in one of those deps? There is no motivation for doing so... I just don't see how anybody would reasonably know they need to update here. And they do need to update, if they don't weirdness will happen. That weirdness will mostly occur once the new version of the formatter ships in a stable SDK, and people start opting into the new style. So, that is why I say the breaking change should be published prior to the formatter shipping in a stable SDK, so that package authors become aware of this change (by seeing the new major version, which requires action on their part to allow). |
Yeah, I do intend to publish dart_style with a major version bump before the Dart SDK ships on stable. |
The vim plugin does use stdin, and it has no understanding of language versions. I prefer formatting through stdin so we don't have to force a file write before formatting. Can we add some argument to make this easier? What do you think about something like Edit: I think we added |
Having |
I moved the task of coordinating with the analyzer and other teams to pass language versions to the formatter up into the main implementation issue (#1403), so this is done. |
We're in [the process of](dart-lang/dart_style#1403) moving dart_style to [a new formatting style](dart-lang/dart_style#1253). That involves making the formatter [aware of the language version of what it's formatting](dart-lang/dart_style#1402). That in turn means that the library API now lets you pass in a language version. In dart_style 2.3.7 [you can pass in a language version but the parameter is optional](https://pub.dev/documentation/dart_style/latest/dart_style/DartFormatter/DartFormatter.html). In the forthcoming 3.0.0 release, that parameter will become mandatory. This updates every call to `DartFormatter()` to pass in the latest language version. If there's a more specific version that should be used, let me know and I'll update the PR. Thanks!
* Update dart_style to pass in a language version to DartFormatter. We're in [the process of](dart-lang/dart_style#1403) moving dart_style to [a new formatting style](dart-lang/dart_style#1253). That involves making the formatter [aware of the language version of what it's formatting](dart-lang/dart_style#1402). That in turn means that the library API now lets you pass in a language version. In dart_style 2.3.7 [you can pass in a language version but the parameter is optional](https://pub.dev/documentation/dart_style/latest/dart_style/DartFormatter/DartFormatter.html). In the forthcoming 3.0.0 release, that parameter will become mandatory. This updates every call to `DartFormatter()` to pass in the latest language version. * Update CHANGELOG and analysis_options.yaml. * Require Dart SDK 3.5.0.
We're in [the process of](dart-lang/dart_style#1403) moving dart_style to [a new formatting style](dart-lang/dart_style#1253). That involves making the formatter [aware of the language version of what it's formatting](dart-lang/dart_style#1402). That in turn means that the library API now lets you pass in a language version. In dart_style 2.3.7 [you can pass in a language version but the parameter is optional](https://pub.dev/documentation/dart_style/latest/dart_style/DartFormatter/DartFormatter.html). In the forthcoming 3.0.0 release, that parameter will become mandatory. This updates the call to `DartFormatter()` to pass in the latest language version. If there's a more specific version that should be used, let me know and I'll update the PR.
We're in [the process of](dart-lang/dart_style#1403) moving dart_style to [a new formatting style](dart-lang/dart_style#1253). That involves making the formatter [aware of the language version of what it's formatting](dart-lang/dart_style#1402). That in turn means that the library API now lets you pass in a language version. In dart_style 2.3.7 [you can pass in a language version but the parameter is optional](https://pub.dev/documentation/dart_style/latest/dart_style/DartFormatter/DartFormatter.html). In the forthcoming 3.0.0 release, that parameter will become mandatory. This updates the two calls to `DartFormatter()` in intl_translation/bin to pass in a language version. It attempts to look for a surrounding package_config.json file and uses the language version from that (which is what other Dart tools do). If that files, it just defaults to using the latest language version that the formatter supports.
We're in [the process of](dart-lang/dart_style#1403) moving dart_style to [a new formatting style](dart-lang/dart_style#1253). That involves making the formatter [aware of the language version of what it's formatting](dart-lang/dart_style#1402). That in turn means that the library API now lets you pass in a language version. In dart_style 2.3.7 [you can pass in a language version but the parameter is optional](https://pub.dev/documentation/dart_style/latest/dart_style/DartFormatter/DartFormatter.html). In the forthcoming 3.0.0 release, that parameter will become mandatory. This updates the call to `DartFormatter()` to pass in the latest language version. If there's a more specific version that should be used, let me know and I'll update the PR.
…rt-archive/code_builder#466) * Update dart_style to pass in a language version to DartFormatter. We're in [the process of](dart-lang/dart_style#1403) moving dart_style to [a new formatting style](dart-lang/dart_style#1253). That involves making the formatter [aware of the language version of what it's formatting](dart-lang/dart_style#1402). That in turn means that the library API now lets you pass in a language version. In dart_style 2.3.7 [you can pass in a language version but the parameter is optional](https://pub.dev/documentation/dart_style/latest/dart_style/DartFormatter/DartFormatter.html). In the forthcoming 3.0.0 release, that parameter will become mandatory. This updates every call to `DartFormatter()` to pass in the latest language version. * Update CHANGELOG and analysis_options.yaml. * Require Dart SDK 3.5.0.
-- f9f3ade by Robert Nystrom <[email protected]>: Pass a language version to DartFormatter(). We're in [the process of](dart-lang/dart_style#1403) moving dart_style to [a new formatting style](dart-lang/dart_style#1253). That involves making the formatter [aware of the language version of what it's formatting](dart-lang/dart_style#1402). That in turn means that the library API now lets you pass in a language version. In dart_style 2.3.7 [you can pass in a language version but the parameter is optional](https://pub.dev/documentation/dart_style/latest/dart_style/DartFormatter/DartFormatter.html). In the forthcoming 3.0.0 release, that parameter will become mandatory. This updates the two calls to `DartFormatter()` in intl_translation/bin to pass in a language version. It attempts to look for a surrounding package_config.json file and uses the language version from that (which is what other Dart tools do). If that files, it just defaults to using the latest language version that the formatter supports. PiperOrigin-RevId: 689754530
Dart format is moving to a new "tall" style designed to be more readable for the kind of deeply nested declarative code that is common in Flutter (#1253). When users install a new Dart SDK, they don't generally expect the formatter to radically change the style of their already-formatted code, and we don't want that to happen when the new style ships either.
We've discussed a few ways to let users control when they adopt the new tall style, and the best approach we've been able to come up with is to tie it to language version. Let's say that
dart format
support for the tall style ships in Dart SDK 3.x.0. The idea is:Any Dart file whose language version is 3.x or greater will automatically be formatted using the new tall style.
Any Dart file whose language version is older than 3.x will continue to use the current "short" style.
This means that by default, when you update to a new Flutter or Dart SDK, your formatting won't change. It's only when you change the Dart SDK constraint in your pubspec to opt into the new language version that you'll also get a formatting change. (We also intend to support some explicit way to opt in to the new style for older language versioned files.)
To implement that, dart_style needs to know the language version of everything it's formatting. Currently, it doesn't. This issue is to track adding support for that. It may need some elaboration, but the basic idea is:
The
FormatCommand
class which drives thedart format
command-line tool and accesses the file system directly should determine the language version of each file it processes. This means looking for either a pubspec or package configuration file in surrounding directories to determine the default language version. I'm not sure what the exact logic should be here, but it should probably follow howdart analyze
behaves. Ideally, there is some code we can reuse.Extend the
DartFormatter
library API to support passing in a language version for each file. If omitted, default to something reasonable (without hitting the file system). Probably just the most recent language version.If a compilation unit being formatted (from the command line or through the
DartFormatter
library API) has a@dart=
language version comment, honor that to determine the style used for that file.The text was updated successfully, but these errors were encountered: