From cfa5f27afe0ebacb2940f8b0a78c08f340d06b8f Mon Sep 17 00:00:00 2001 From: Georgii Dolzhykov Date: Fri, 20 Jan 2023 12:58:44 +0200 Subject: [PATCH] Avoid adding unnecessary indent to nested await (#14192) --- changelog_unreleased/javascript/14192.md | 22 ++++++++++++++++ src/language-js/printer-estree.js | 10 +++++++- .../js/async/__snapshots__/jsfmt.spec.js.snap | 25 +++++++++++++++++++ tests/format/js/async/nested2.js | 6 +++++ 4 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 changelog_unreleased/javascript/14192.md create mode 100644 tests/format/js/async/nested2.js diff --git a/changelog_unreleased/javascript/14192.md b/changelog_unreleased/javascript/14192.md new file mode 100644 index 000000000..9845ef85b --- /dev/null +++ b/changelog_unreleased/javascript/14192.md @@ -0,0 +1,22 @@ +#### Avoid unnecessarily indenting nested `await` expressions (#14192 by @thorn0) + +A refinement of [this change in v2.3](https://prettier.io/blog/2021/05/09/2.3.0.html#improve-formatting-for-nested-await-expressions-in-heads-of-member-and-call-expressions-10342httpsgithubcomprettierprettierpull10342-by-thorn0httpsgithubcomthorn0). Sometimes there is no need to force indentation of nested `await` expressions. + + +```jsx +// Prettier stable +await Promise.all( + ( + await readdir("src") + ).map((path) => { + import(`./${path}`); + }) +); + +// Prettier main +await Promise.all( + (await readdir("src")).map((path) => { + import(`./${path}`); + }), +); +``` diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index da598d746..44a6f5cb7 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -29,6 +29,7 @@ import { markerForIfWithoutBlockAndSameLineComment, isArrayOrTupleExpression, isObjectOrRecordExpression, + startsWithNoLookaheadToken, } from "./utils/index.js"; import { locStart, locEnd } from "./loc.js"; import isBlockComment from "./utils/is-block-comment.js"; @@ -325,11 +326,18 @@ function printPathNoParens(path, options, print, args) { (isMemberExpression(parent) && parent.object === node) ) { parts = [indent([softline, ...parts]), softline]; + // avoid printing `await (await` on one line const parentAwaitOrBlock = path.findAncestor( (node) => node.type === "AwaitExpression" || node.type === "BlockStatement" ); - if (parentAwaitOrBlock?.type !== "AwaitExpression") { + if ( + parentAwaitOrBlock?.type !== "AwaitExpression" || + !startsWithNoLookaheadToken( + parentAwaitOrBlock.argument, + (leftmostNode) => leftmostNode === node + ) + ) { return group(parts); } } diff --git a/tests/format/js/async/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/async/__snapshots__/jsfmt.spec.js.snap index 8e3523352..98e1299bd 100644 --- a/tests/format/js/async/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/js/async/__snapshots__/jsfmt.spec.js.snap @@ -198,6 +198,31 @@ const getAccountCount = async () => ================================================================================ `; +exports[`nested2.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +async function f() { +await Promise.all( + (await readdir("src")).map(async (path) => { + import(\`./\${path}\`); + }) +);} + +=====================================output===================================== +async function f() { + await Promise.all( + (await readdir("src")).map(async (path) => { + import(\`./\${path}\`); + }), + ); +} + +================================================================================ +`; + exports[`parens.js format 1`] = ` ====================================options===================================== parsers: ["babel", "flow", "typescript"] diff --git a/tests/format/js/async/nested2.js b/tests/format/js/async/nested2.js new file mode 100644 index 000000000..5b7ec8637 --- /dev/null +++ b/tests/format/js/async/nested2.js @@ -0,0 +1,6 @@ +async function f() { +await Promise.all( + (await readdir("src")).map(async (path) => { + import(`./${path}`); + }) +);}