/
index.ts
51 lines (46 loc) 路 1.62 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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),
[],
),
);
},
},
},
};
});