diff --git a/changelog_unreleased/javascript/10813.md b/changelog_unreleased/javascript/10813.md new file mode 100644 index 000000000..7fd23485e --- /dev/null +++ b/changelog_unreleased/javascript/10813.md @@ -0,0 +1,18 @@ +#### Support async do expressions proposal (#10813 by @sosukesuzuki) + +https://github.com/tc39/proposal-async-do-expressions + +```js +// Input +const x = async do { + await requestAPI().json(); +}; + +// Prettier stable +SyntaxError: Unexpected token, expected ";" (1:17) + +// Prettier main +const x = async do { + await requestAPI().json(); +}; +``` diff --git a/src/language-js/parser-babel.js b/src/language-js/parser-babel.js index 34d942020..d91cc54eb 100644 --- a/src/language-js/parser-babel.js +++ b/src/language-js/parser-babel.js @@ -37,6 +37,7 @@ const parseOptions = { "decimal", "classStaticBlock", "moduleBlocks", + "asyncDoExpressions", ], tokens: true, ranges: true, diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index f30f93e04..00e5ea291 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -620,7 +620,7 @@ function printPathNoParens(path, options, print, args) { return parts; } case "DoExpression": - return ["do ", print("body")]; + return [node.async ? "async " : "", "do ", print("body")]; case "BreakStatement": parts.push("break"); diff --git a/tests/format/js/async-do-expressions/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/async-do-expressions/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..1e44c20a3 --- /dev/null +++ b/tests/format/js/async-do-expressions/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,87 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`async-do-expressions.js [espree] format 1`] = ` +"Unexpected token do (1:7) +> 1 | async do { + | ^ + 2 | 1; + 3 | }; + 4 |" +`; + +exports[`async-do-expressions.js [meriyah] format 1`] = ` +"[1:8]: Unexpected token: 'do' (1:8) +> 1 | async do { + | ^ + 2 | 1; + 3 | }; + 4 |" +`; + +exports[`async-do-expressions.js format 1`] = ` +====================================options===================================== +parsers: ["babel"] +printWidth: 80 + | printWidth +=====================================input====================================== +async do { + 1; +}; + +(async do {}); + +let x = async do { + if (foo()) { f() } + else if (bar()) { g() } + else { h() } +}; + +async do { + await 42 +} + +function iter() { + return async do { + return 1; + } +}; + +let x = async do { + let tmp = f(); + tmp * tmp + 1 +}; + +=====================================output===================================== +(async do { + 1; +}); + +(async do {}); + +let x = async do { + if (foo()) { + f(); + } else if (bar()) { + g(); + } else { + h(); + } +}; + +(async do { + await 42; +}); + +function iter() { + return async do { + return 1; + }; +} + +let x = async do { + let tmp = f(); + tmp * tmp + 1; +}; + +================================================================================ +`; diff --git a/tests/format/js/async-do-expressions/async-do-expressions.js b/tests/format/js/async-do-expressions/async-do-expressions.js new file mode 100644 index 000000000..fbd33b898 --- /dev/null +++ b/tests/format/js/async-do-expressions/async-do-expressions.js @@ -0,0 +1,26 @@ +async do { + 1; +}; + +(async do {}); + +let x = async do { + if (foo()) { f() } + else if (bar()) { g() } + else { h() } +}; + +async do { + await 42 +} + +function iter() { + return async do { + return 1; + } +}; + +let x = async do { + let tmp = f(); + tmp * tmp + 1 +}; diff --git a/tests/format/js/async-do-expressions/jsfmt.spec.js b/tests/format/js/async-do-expressions/jsfmt.spec.js new file mode 100644 index 000000000..0fab4456d --- /dev/null +++ b/tests/format/js/async-do-expressions/jsfmt.spec.js @@ -0,0 +1 @@ +run_spec(__dirname, ["babel"], { errors: { espree: true, meriyah: true } }); diff --git a/tests/format/js/babel-plugins/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/babel-plugins/__snapshots__/jsfmt.spec.js.snap index 919e06844..cf3b93fc4 100644 --- a/tests/format/js/babel-plugins/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/js/babel-plugins/__snapshots__/jsfmt.spec.js.snap @@ -1,5 +1,35 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`async-do-expressions.js [espree] format 1`] = ` +"Unexpected token do (1:7) +> 1 | async do { await requestAPI().json() }; + | ^ + 2 |" +`; + +exports[`async-do-expressions.js [meriyah] format 1`] = ` +"[1:8]: Unexpected token: 'do' (1:8) +> 1 | async do { await requestAPI().json() }; + | ^ + 2 |" +`; + +exports[`async-do-expressions.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "babel-ts", "babel-flow"] +printWidth: 80 + | printWidth +=====================================input====================================== +async do { await requestAPI().json() }; + +=====================================output===================================== +(async do { + await requestAPI().json(); +}); + +================================================================================ +`; + exports[`async-generators.js format 1`] = ` ====================================options===================================== parsers: ["babel", "babel-ts", "babel-flow"] diff --git a/tests/format/js/babel-plugins/async-do-expressions.js b/tests/format/js/babel-plugins/async-do-expressions.js new file mode 100644 index 000000000..d6fdc93e1 --- /dev/null +++ b/tests/format/js/babel-plugins/async-do-expressions.js @@ -0,0 +1 @@ +async do { await requestAPI().json() }; diff --git a/tests/format/js/babel-plugins/jsfmt.spec.js b/tests/format/js/babel-plugins/jsfmt.spec.js index c86bffb3f..87e4633cf 100644 --- a/tests/format/js/babel-plugins/jsfmt.spec.js +++ b/tests/format/js/babel-plugins/jsfmt.spec.js @@ -28,6 +28,7 @@ run_spec(__dirname, ["babel", "babel-ts", "babel-flow"], { "module-string-names.js", "class-static-block.js", "module-blocks.js", + "async-do-expressions.js", ], meriyah: [ "decimal.js", @@ -52,6 +53,7 @@ run_spec(__dirname, ["babel", "babel-ts", "babel-flow"], { "import-assertions-static.js", "module-string-names.js", "module-blocks.js", + "async-do-expressions.js", ], }, });