Implement async-do-expressions transform (#13117)
Co-authored-by: Brian Ng <bng412@gmail.com>
This commit is contained in:
parent
28d7442aae
commit
50e0e353ee
@ -0,0 +1,3 @@
|
|||||||
|
src
|
||||||
|
test
|
||||||
|
*.log
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
# @babel/plugin-proposal-async-do-expressions
|
||||||
|
|
||||||
|
> Transforms async do expressions to ES2021
|
||||||
|
|
||||||
|
See our website [@babel/plugin-proposal-async-do-expressions](https://babeljs.io/docs/en/babel-plugin-proposal-async-do-expressions) for more information.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
Using npm:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install --save-dev @babel/plugin-proposal-async-do-expressions
|
||||||
|
```
|
||||||
|
|
||||||
|
or using yarn:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
yarn add @babel/plugin-proposal-async-do-expressions --dev
|
||||||
|
```
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"name": "@babel/plugin-proposal-async-do-expressions",
|
||||||
|
"version": "7.13.11",
|
||||||
|
"description": "Transform async do expressions to ES2021",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/babel/babel.git",
|
||||||
|
"directory": "packages/babel-plugin-proposal-async-do-expressions"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "public"
|
||||||
|
},
|
||||||
|
"main": "./lib/index.js",
|
||||||
|
"exports": {
|
||||||
|
".": "./lib/index.js"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"babel-plugin"
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-hoist-variables": "workspace:^7.13.0",
|
||||||
|
"@babel/helper-plugin-utils": "workspace:^7.13.0",
|
||||||
|
"@babel/plugin-syntax-async-do-expressions": "workspace:^7.13.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.13.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/core": "workspace:*",
|
||||||
|
"@babel/helper-plugin-test-runner": "workspace:*",
|
||||||
|
"@babel/traverse": "workspace:*",
|
||||||
|
"@babel/types": "workspace:*"
|
||||||
|
},
|
||||||
|
"homepage": "https://babel.dev/docs/en/next/babel-plugin-proposal-async-do-expressions"
|
||||||
|
}
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
import { declare } from "@babel/helper-plugin-utils";
|
||||||
|
import syntaxAsyncDoExpressions from "@babel/plugin-syntax-async-do-expressions";
|
||||||
|
import hoistVariables from "@babel/helper-hoist-variables";
|
||||||
|
import type * as t from "@babel/types";
|
||||||
|
import type { NodePath } from "@babel/traverse";
|
||||||
|
|
||||||
|
export default declare(({ types: t, assertVersion }) => {
|
||||||
|
assertVersion("^7.13.0");
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: "proposal-async-do-expressions",
|
||||||
|
inherits: syntaxAsyncDoExpressions,
|
||||||
|
visitor: {
|
||||||
|
DoExpression: {
|
||||||
|
exit(path: NodePath<t.DoExpression>) {
|
||||||
|
if (!path.is("async")) {
|
||||||
|
// non-async do expressions are handled by proposal-do-expressions
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { scope } = path;
|
||||||
|
// Hoist variable declaration to containing function scope
|
||||||
|
// `async do { var x = 1; x }` -> `var x; (async() => { x = 1; return x })()`
|
||||||
|
hoistVariables(
|
||||||
|
path,
|
||||||
|
(id: t.Identifier) => {
|
||||||
|
scope.push({ id: t.cloneNode(id) });
|
||||||
|
},
|
||||||
|
"var",
|
||||||
|
);
|
||||||
|
const bodyPath = path.get("body");
|
||||||
|
|
||||||
|
// add implicit returns to all ending expression statements
|
||||||
|
const completionRecords = bodyPath.getCompletionRecords();
|
||||||
|
|
||||||
|
for (const p of completionRecords) {
|
||||||
|
if (p.isExpressionStatement()) {
|
||||||
|
p.replaceWith(t.returnStatement(p.node.expression));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
path.replaceWith(
|
||||||
|
t.callExpression(
|
||||||
|
t.arrowFunctionExpression([], bodyPath.node, /* async */ true),
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
const x = async do { 21 + 21 };
|
||||||
|
|
||||||
|
expect(x).toBeInstanceOf(Promise);
|
||||||
|
x.then((v) => expect(v).toBe(42)).catch(err => { throw err });
|
||||||
@ -0,0 +1 @@
|
|||||||
|
const x = async do { 21 + 21 };
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
const x = (async () => {
|
||||||
|
return 21 + 21;
|
||||||
|
})();
|
||||||
@ -0,0 +1 @@
|
|||||||
|
async do {}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
(async () => {})();
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
const x = async do { var y = 21; y + y }
|
||||||
|
|
||||||
|
expect(y).toBe(21);
|
||||||
|
x.then((resolved) => {
|
||||||
|
expect(resolved).toBe(42);
|
||||||
|
}).catch(err => { throw err });
|
||||||
@ -0,0 +1 @@
|
|||||||
|
const x = async do { var y = 21; y + y }
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
var y;
|
||||||
|
|
||||||
|
const x = (async () => {
|
||||||
|
y = 21;
|
||||||
|
return y + y;
|
||||||
|
})();
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
const x = async do { await Promise.resolve(); var y = 21; y + y }
|
||||||
|
|
||||||
|
expect(y).toBe(undefined);
|
||||||
|
x.then((resolved) => {
|
||||||
|
expect(y).toBe(21);
|
||||||
|
expect(resolved).toBe(42);
|
||||||
|
}).catch(err => { throw err });
|
||||||
@ -0,0 +1 @@
|
|||||||
|
const x = async do { await Promise.resolve(); var y = 21; y + y }
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
var y;
|
||||||
|
|
||||||
|
const x = (async () => {
|
||||||
|
await Promise.resolve();
|
||||||
|
y = 21;
|
||||||
|
return y + y;
|
||||||
|
})();
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
const x = async do { let x = 21; x + x };
|
||||||
|
|
||||||
|
expect(x).toBeInstanceOf(Promise);
|
||||||
|
x.then((v) => expect(v).toBe(42)).catch(err => { throw err });
|
||||||
@ -0,0 +1 @@
|
|||||||
|
const x = async do { let x = 21; x + x };
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
const x = (async () => {
|
||||||
|
let x = 21;
|
||||||
|
return x + x;
|
||||||
|
})();
|
||||||
|
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
const x = async do { throw new Error("sync") };
|
||||||
|
|
||||||
|
expect(x).toBeInstanceOf(Promise);
|
||||||
|
x.then(() => { throw new Error("expected an error: sync is thrown.") })
|
||||||
|
.catch(err => { expect(err.message).toEqual("sync") });
|
||||||
@ -0,0 +1 @@
|
|||||||
|
const x = async do { throw new Error("sync") };
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
const x = (async () => {
|
||||||
|
throw new Error("sync");
|
||||||
|
})();
|
||||||
4
packages/babel-plugin-proposal-async-do-expressions/test/fixtures/options.json
vendored
Normal file
4
packages/babel-plugin-proposal-async-do-expressions/test/fixtures/options.json
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"plugins": ["proposal-async-do-expressions"],
|
||||||
|
"minNodeVersion": "8.0.0"
|
||||||
|
}
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
// sync do expressions are not handled by this plugin
|
||||||
|
(do {});
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"plugins": ["proposal-async-do-expressions"],
|
||||||
|
"minNodeVersion": "6.0.0"
|
||||||
|
}
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
// sync do expressions are not handled by this plugin
|
||||||
|
(do {});
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
import runner from "@babel/helper-plugin-test-runner";
|
||||||
|
|
||||||
|
runner(import.meta.url);
|
||||||
18
yarn.lock
18
yarn.lock
@ -1021,6 +1021,22 @@ __metadata:
|
|||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
|
"@babel/plugin-proposal-async-do-expressions@workspace:packages/babel-plugin-proposal-async-do-expressions":
|
||||||
|
version: 0.0.0-use.local
|
||||||
|
resolution: "@babel/plugin-proposal-async-do-expressions@workspace:packages/babel-plugin-proposal-async-do-expressions"
|
||||||
|
dependencies:
|
||||||
|
"@babel/core": "workspace:*"
|
||||||
|
"@babel/helper-hoist-variables": "workspace:^7.13.0"
|
||||||
|
"@babel/helper-plugin-test-runner": "workspace:*"
|
||||||
|
"@babel/helper-plugin-utils": "workspace:^7.13.0"
|
||||||
|
"@babel/plugin-syntax-async-do-expressions": "workspace:^7.13.0"
|
||||||
|
"@babel/traverse": "workspace:*"
|
||||||
|
"@babel/types": "workspace:*"
|
||||||
|
peerDependencies:
|
||||||
|
"@babel/core": ^7.13.0
|
||||||
|
languageName: unknown
|
||||||
|
linkType: soft
|
||||||
|
|
||||||
"@babel/plugin-proposal-async-generator-functions@npm:^7.13.15":
|
"@babel/plugin-proposal-async-generator-functions@npm:^7.13.15":
|
||||||
version: 7.13.15
|
version: 7.13.15
|
||||||
resolution: "@babel/plugin-proposal-async-generator-functions@npm:7.13.15"
|
resolution: "@babel/plugin-proposal-async-generator-functions@npm:7.13.15"
|
||||||
@ -1512,7 +1528,7 @@ __metadata:
|
|||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
"@babel/plugin-syntax-async-do-expressions@workspace:packages/babel-plugin-syntax-async-do-expressions":
|
"@babel/plugin-syntax-async-do-expressions@workspace:^7.13.0, @babel/plugin-syntax-async-do-expressions@workspace:packages/babel-plugin-syntax-async-do-expressions":
|
||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@babel/plugin-syntax-async-do-expressions@workspace:packages/babel-plugin-syntax-async-do-expressions"
|
resolution: "@babel/plugin-syntax-async-do-expressions@workspace:packages/babel-plugin-syntax-async-do-expressions"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user