Skip to content

Commit b9a2244

Browse files
Improve output when wrapping functions (e.g. async functions) (#15922)
Co-authored-by: Nicolò Ribaudo <[email protected]>
1 parent 1fb3b7a commit b9a2244

File tree

76 files changed

+396
-700
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+396
-700
lines changed

packages/babel-helper-remap-async-to-generator/src/index.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
/* @noflow */
2-
31
import type { NodePath } from "@babel/traverse";
42
import wrapFunction from "@babel/helper-wrap-function";
53
import annotateAsPure from "@babel/helper-annotate-as-pure";
@@ -65,7 +63,7 @@ export default function (
6563
path.parentPath.isObjectProperty() ||
6664
path.parentPath.isClassProperty();
6765

68-
if (!isProperty && !isIIFE && path.isExpression()) {
66+
if (!isProperty && !isIIFE && path.isCallExpression()) {
6967
annotateAsPure(path);
7068
}
7169

packages/babel-helper-wrap-function/src/index.ts

Lines changed: 30 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -10,56 +10,18 @@ import {
1010
isRestElement,
1111
returnStatement,
1212
isCallExpression,
13+
cloneNode,
14+
toExpression,
1315
} from "@babel/types";
1416
import type * as t from "@babel/types";
1517

16-
type ExpressionWrapperBuilder<ExtraBody extends t.Node[]> = (
17-
replacements?: Parameters<ReturnType<typeof template.expression>>[0],
18-
) => t.CallExpression & {
19-
callee: t.FunctionExpression & {
20-
body: {
21-
body: [
22-
t.VariableDeclaration & {
23-
declarations: [
24-
{ init: t.FunctionExpression | t.ArrowFunctionExpression },
25-
];
26-
},
27-
...ExtraBody,
28-
];
29-
};
30-
};
31-
};
32-
33-
const buildAnonymousExpressionWrapper = template.expression(`
34-
(function () {
35-
var REF = FUNCTION;
36-
return function NAME(PARAMS) {
37-
return REF.apply(this, arguments);
38-
};
39-
})()
40-
`) as ExpressionWrapperBuilder<
41-
[t.ReturnStatement & { argument: t.FunctionExpression }]
42-
>;
43-
44-
const buildNamedExpressionWrapper = template.expression(`
45-
(function () {
46-
var REF = FUNCTION;
47-
function NAME(PARAMS) {
48-
return REF.apply(this, arguments);
49-
}
50-
return NAME;
51-
})()
52-
`) as ExpressionWrapperBuilder<
53-
[t.FunctionDeclaration, t.ReturnStatement & { argument: t.Identifier }]
54-
>;
55-
56-
const buildDeclarationWrapper = template.statements(`
57-
function NAME(PARAMS) { return REF.apply(this, arguments); }
58-
function REF() {
59-
REF = FUNCTION;
60-
return REF.apply(this, arguments);
18+
const buildWrapper = template.statement(`
19+
function NAME(PARAMS) {
20+
return (REF = REF || FUNCTION).apply(this, arguments);
6121
}
62-
`);
22+
`) as (
23+
replacements: Parameters<ReturnType<typeof template.expression>>[0],
24+
) => t.FunctionDeclaration;
6325

6426
function classOrObjectMethod(
6527
path: NodePath<t.ClassMethod | t.ClassPrivateMethod | t.ObjectMethod>,
@@ -140,40 +102,32 @@ function plainFunction(
140102
params.push(path.scope.generateUidIdentifier("x"));
141103
}
142104

143-
const wrapperArgs = {
144-
NAME: functionId || null,
145-
REF: path.scope.generateUidIdentifier(functionId ? functionId.name : "ref"),
105+
const ref = path.scope.generateUidIdentifier(
106+
functionId ? functionId.name : "ref",
107+
);
108+
109+
let wrapper: t.Function = buildWrapper({
110+
NAME: functionId,
111+
REF: ref,
146112
FUNCTION: built,
147113
PARAMS: params,
148-
};
114+
});
115+
116+
if (!isDeclaration) {
117+
wrapper = toExpression(wrapper);
118+
nameFunction({
119+
node: wrapper,
120+
parent: (path as NodePath<t.FunctionExpression>).parent,
121+
scope: path.scope,
122+
});
123+
}
149124

150-
if (isDeclaration) {
151-
const container = buildDeclarationWrapper(wrapperArgs);
152-
path.replaceWith(container[0]);
153-
path.insertAfter(container[1]);
125+
if (isDeclaration || wrapper.id || (!ignoreFunctionLength && params.length)) {
126+
path.replaceWith(wrapper);
127+
path.parentPath.scope.push({ id: cloneNode(ref) });
154128
} else {
155-
let container;
156-
157-
if (functionId) {
158-
container = buildNamedExpressionWrapper(wrapperArgs);
159-
} else {
160-
container = buildAnonymousExpressionWrapper(wrapperArgs);
161-
162-
const returnFn = container.callee.body.body[1].argument;
163-
nameFunction({
164-
node: returnFn,
165-
parent: (path as NodePath<t.FunctionExpression>).parent,
166-
scope: path.scope,
167-
});
168-
functionId = returnFn.id;
169-
}
170-
171-
if (functionId || (!ignoreFunctionLength && params.length)) {
172-
path.replaceWith(container);
173-
} else {
174-
// we can omit this wrapper as the conditions it protects for do not apply
175-
path.replaceWith(built);
176-
}
129+
// we can omit this wrapper as the conditions it protects for do not apply
130+
path.replaceWith(built);
177131
}
178132
}
179133

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1+
var _fn;
12
function fn() {
2-
return _fn.apply(this, arguments);
3-
}
4-
function _fn() {
5-
_fn = babelHelpers.asyncToGenerator(function* () {
3+
return (_fn = _fn || babelHelpers.asyncToGenerator(function* () {
64
yield 0;
75
try {
86
var _stack = [];
@@ -14,6 +12,5 @@ function _fn() {
1412
} finally {
1513
yield babelHelpers.dispose(_stack, _error, _hasError);
1614
}
17-
});
18-
return _fn.apply(this, arguments);
15+
})).apply(this, arguments);
1916
}
Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1+
var _gen;
12
function gen() {
2-
return _gen.apply(this, arguments);
3-
}
4-
function _gen() {
5-
_gen = babelHelpers.skipFirstGeneratorNext(function* () {
3+
return (_gen = _gen || babelHelpers.skipFirstGeneratorNext(function* () {
64
let _functionSent = yield;
75
let sent = _functionSent;
8-
});
9-
return _gen.apply(this, arguments);
6+
})).apply(this, arguments);
107
}
Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1+
var _foo;
12
function foo() {
2-
return _foo.apply(this, arguments);
3-
}
4-
function _foo() {
5-
_foo = babelHelpers.wrapAsyncGenerator(babelHelpers.skipFirstGeneratorNext(function* () {
3+
return (_foo = _foo || babelHelpers.wrapAsyncGenerator(babelHelpers.skipFirstGeneratorNext(function* () {
64
let _functionSent = yield;
75
_functionSent = yield babelHelpers.awaitAsyncGenerator(_functionSent);
8-
}));
9-
return _foo.apply(this, arguments);
6+
}))).apply(this, arguments);
107
}
Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1+
var _ref;
12
export default function () {
2-
return _ref.apply(this, arguments);
3-
}
4-
function _ref() {
5-
_ref = babelHelpers.skipFirstGeneratorNext(function* () {
3+
return (_ref = _ref || babelHelpers.skipFirstGeneratorNext(function* () {
64
let _functionSent = yield;
75
return _functionSent;
8-
});
9-
return _ref.apply(this, arguments);
6+
})).apply(this, arguments);
107
}
Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1+
var _gen;
12
export default function gen() {
2-
return _gen.apply(this, arguments);
3-
}
4-
function _gen() {
5-
_gen = babelHelpers.skipFirstGeneratorNext(function* () {
3+
return (_gen = _gen || babelHelpers.skipFirstGeneratorNext(function* () {
64
let _functionSent = yield;
75
return _functionSent;
8-
});
9-
return _gen.apply(this, arguments);
6+
})).apply(this, arguments);
107
}
Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1+
var _gen;
12
export function gen() {
2-
return _gen.apply(this, arguments);
3-
}
4-
function _gen() {
5-
_gen = babelHelpers.skipFirstGeneratorNext(function* () {
3+
return (_gen = _gen || babelHelpers.skipFirstGeneratorNext(function* () {
64
let _functionSent = yield;
75
return _functionSent;
8-
});
9-
return _gen.apply(this, arguments);
6+
})).apply(this, arguments);
107
}
Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
const foo = function () {
2-
var _gen = babelHelpers.skipFirstGeneratorNext(function* () {
1+
var _gen;
2+
const foo = function gen() {
3+
return (_gen = _gen || babelHelpers.skipFirstGeneratorNext(function* () {
34
let _functionSent = yield;
45
return _functionSent;
5-
});
6-
function gen() {
7-
return _gen.apply(this, arguments);
8-
}
9-
return gen;
10-
}();
6+
})).apply(this, arguments);
7+
};
Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1+
var _gen;
12
function gen() {
2-
return _gen.apply(this, arguments);
3-
}
4-
function _gen() {
5-
_gen = babelHelpers.skipFirstGeneratorNext(function* () {
3+
return (_gen = _gen || babelHelpers.skipFirstGeneratorNext(function* () {
64
let _functionSent = yield;
75
return _functionSent;
8-
});
9-
return _gen.apply(this, arguments);
6+
})).apply(this, arguments);
107
}

0 commit comments

Comments
 (0)