Skip to content

Commit 0c1f628

Browse files
authored
Stdin name search (#1566)
Use --stdin-name as a file path for inferring the language version. If --stdin-name is given, then look for a surrounding package config to infer the default language version from for code read from stdin. To avoid that behavior, you can pass in a language version explicitly using --language-version. Fix #1530.
1 parent 49832b6 commit 0c1f628

File tree

6 files changed

+190
-106
lines changed

6 files changed

+190
-106
lines changed

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,19 @@
5454
arguments as the `dart format` command. You can invoke it with
5555
`dart run dart_style:format <args...>`.
5656

57+
* **Treat the `--stdin-name` name as a path when inferring language version.**
58+
When reading input on stdin, the formatter still needs to know what language
59+
version to parse the code as. If the `--stdin-name` option is set, then that
60+
is treated as a file path and the formatter looks for a package config
61+
surrounding that file path to infer the language version from.
62+
63+
If you don't want that behavior, pass in an explicit language version using
64+
`--language-version=`, or use `--language-version=latest` to parse the input
65+
using the latest language version supported by the formatter.
66+
67+
If `--stdin-name` and `--language-version` are both omitted, then parses
68+
stdin using the latest supported language version.
69+
5770
## 2.3.7
5871

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

lib/src/cli/format_command.dart

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,12 @@ class FormatCommand extends Command<int> {
107107
help: 'Track selection (given as "start:length") through formatting.',
108108
hide: !verbose);
109109
argParser.addOption('stdin-name',
110-
help: 'Use this path in error messages when input is read from stdin.',
111-
defaultsTo: 'stdin',
110+
help:
111+
'The path that code read from stdin is treated as coming from.\n\n'
112+
'This path is used in error messages and also to locate a\n'
113+
'surrounding package to infer the code\'s language version.\n'
114+
'To avoid searching for a surrounding package config, pass\n'
115+
'in a language version using --language-version.',
112116
hide: !verbose);
113117
}
114118

@@ -223,7 +227,7 @@ class FormatCommand extends Command<int> {
223227
if (argResults.wasParsed('stdin-name') && argResults.rest.isNotEmpty) {
224228
usageException('Cannot pass --stdin-name when not reading from stdin.');
225229
}
226-
var stdinName = argResults['stdin-name'] as String;
230+
var stdinName = argResults['stdin-name'] as String?;
227231

228232
var options = FormatterOptions(
229233
languageVersion: languageVersion,

lib/src/io.dart

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import 'source_code.dart';
1717

1818
/// Reads and formats input from stdin until closed.
1919
Future<void> formatStdin(
20-
FormatterOptions options, List<int>? selection, String name) async {
20+
FormatterOptions options, List<int>? selection, String? path) async {
2121
var selectionStart = 0;
2222
var selectionLength = 0;
2323

@@ -26,19 +26,35 @@ Future<void> formatStdin(
2626
selectionLength = selection[1];
2727
}
2828

29+
var languageVersion = options.languageVersion;
30+
if (languageVersion == null && path != null) {
31+
// TODO(rnystrom): Remove the experiment check when the experiment ships.
32+
if (options.experimentFlags.contains(tallStyleExperimentFlag)) {
33+
var cache = LanguageVersionCache();
34+
languageVersion = await cache.find(File(path), path);
35+
36+
// If the lookup failed, don't try to parse the code.
37+
if (languageVersion == null) return;
38+
}
39+
}
40+
41+
// If they didn't specify a version or a path, default to the latest.
42+
languageVersion ??= DartFormatter.latestLanguageVersion;
43+
44+
var name = path ?? 'stdin';
45+
2946
var completer = Completer<void>();
3047
var input = StringBuffer();
3148
stdin.transform(const Utf8Decoder()).listen(input.write, onDone: () {
3249
var formatter = DartFormatter(
33-
languageVersion:
34-
options.languageVersion ?? DartFormatter.latestLanguageVersion,
50+
languageVersion: languageVersion!,
3551
indent: options.indent,
3652
pageWidth: options.pageWidth,
3753
experimentFlags: options.experimentFlags);
3854
try {
3955
options.beforeFile(null, name);
4056
var source = SourceCode(input.toString(),
41-
uri: name,
57+
uri: path,
4258
selectionStart: selectionStart,
4359
selectionLength: selectionLength);
4460
var output = formatter.formatSource(source);
@@ -138,17 +154,10 @@ Future<bool> _processFile(
138154
// version.
139155
Version? languageVersion;
140156
if (cache != null) {
141-
try {
142-
// Look for a package config. If we don't find one, default to the latest
143-
// language version.
144-
languageVersion = await cache.find(file);
145-
} catch (error) {
146-
stderr.writeln('Could not read package configuration for '
147-
'$displayPath:\n$error');
148-
stderr.writeln('To avoid searching for a package configuration, '
149-
'specify a language version using "--language-version".');
150-
return false;
151-
}
157+
languageVersion = await cache.find(file, displayPath);
158+
159+
// If the lookup failed, don't try to parse the file.
160+
if (languageVersion == null) return false;
152161
} else {
153162
languageVersion = options.languageVersion;
154163
}

lib/src/language_version_cache.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class LanguageVersionCache {
3333

3434
/// Looks for a package surrounding [file] and, if found, returns the default
3535
/// language version specified by that package.
36-
Future<Version?> find(File file) async {
36+
Future<Version?> find(File file, String displayPath) async {
3737
Profile.begin('look up package config');
3838
try {
3939
// Use the cached version (which may be `null`) if present.
@@ -55,6 +55,12 @@ class LanguageVersionCache {
5555

5656
// We weren't able to resolve this file's directory, so don't try again.
5757
return _directoryVersions[directory] = null;
58+
} catch (error) {
59+
stderr.writeln('Could not read package configuration for '
60+
'$displayPath:\n$error');
61+
stderr.writeln('To avoid searching for a package configuration, '
62+
'specify a language version using "--language-version".');
63+
return null;
5864
} finally {
5965
Profile.end('look up package config');
6066
}

0 commit comments

Comments
 (0)