Skip to content

Commit

Permalink
fix: handle decorated async private method and generator (babel#16258)
Browse files Browse the repository at this point in the history
  • Loading branch information
JLHwung authored and liuxingbaoyu committed Mar 5, 2024
1 parent 0d5b334 commit df047d1
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 17 deletions.
Expand Up @@ -634,12 +634,6 @@ function addCallAccessorsFor(
);
}

function isNotTsParameter(
node: t.Identifier | t.Pattern | t.RestElement | t.TSParameterProperty,
): node is t.Identifier | t.Pattern | t.RestElement {
return node.type !== "TSParameterProperty";
}

function movePrivateAccessor(
element: NodePath<t.ClassPrivateMethod>,
key: t.PrivateName,
Expand Down Expand Up @@ -702,6 +696,25 @@ function maybeSequenceExpression(exprs: t.Expression[]) {
return t.sequenceExpression(exprs);
}

/**
* Create FunctionExpression from a ClassPrivateMethod.
* The returned FunctionExpression node takes ownership of the private method's body and params.
*
* @param {t.ClassPrivateMethod} node
* @returns
*/
function createFunctionExpressionFromPrivateMethod(node: t.ClassPrivateMethod) {
const { params, body, generator: isGenerator, async: isAsync } = node;
return t.functionExpression(
undefined,
// @ts-expect-error todo: Improve typings: TSParameterProperty is only allowed in constructor
params,
body,
isGenerator,
isAsync,
);
}

function createSetFunctionNameCall(
state: PluginPass,
className: t.Identifier | t.StringLiteral,
Expand Down Expand Up @@ -1122,18 +1135,9 @@ function transformClass(

replaceSupers.replace();

const {
params,
body,
async: isAsync,
} = element.node as t.ClassPrivateMethod;

privateMethods = [
t.functionExpression(
undefined,
params.filter(isNotTsParameter),
body,
isAsync,
createFunctionExpressionFromPrivateMethod(
element.node as t.ClassPrivateMethod,
),
];

Expand Down
@@ -0,0 +1,23 @@
let counter = 0;

class Foo {
@(function (fn) {
counter++;
expect(fn.constructor.name).toBe("AsyncFunction");
})
async #a() {}

@(function (fn) {
counter++;
expect(fn.constructor.name).toBe("GeneratorFunction");
})
*#g() {}

@(function (fn) {
counter++;
expect(fn.constructor.name).toBe("AsyncGeneratorFunction");
})
async *#ag() {}
}

expect(counter).toBe(3);
@@ -0,0 +1,10 @@
class Foo {
@dec
async #a() {}

@dec
*#g() {}

@dec
async *#ag() {}
}
@@ -0,0 +1,3 @@
{
"minNodeVersion": "10.0.0"
}
@@ -0,0 +1,26 @@
var _initProto, _dec, _call_a, _dec2, _call_g, _dec3, _call_ag, _Foo;
_dec = dec;
_dec2 = dec;
_dec3 = dec;
var _ag = /*#__PURE__*/new WeakMap();
var _g = /*#__PURE__*/new WeakMap();
var _a = /*#__PURE__*/new WeakMap();
class Foo {
constructor() {
babelHelpers.classPrivateFieldInitSpec(this, _ag, {
writable: true,
value: _call_ag
});
babelHelpers.classPrivateFieldInitSpec(this, _g, {
writable: true,
value: _call_g
});
babelHelpers.classPrivateFieldInitSpec(this, _a, {
writable: true,
value: _call_a
});
_initProto(this);
}
}
_Foo = Foo;
[_call_a, _call_g, _call_ag, _initProto] = babelHelpers.applyDecs2311(_Foo, [[_dec, 2, "a", async function () {}], [_dec2, 2, "g", function* () {}], [_dec3, 2, "ag", async function* () {}]], [], 0, _ => _a.has(babelHelpers.checkInRHS(_))).e;
@@ -0,0 +1,23 @@
let counter = 0;

class Foo {
@(function (fn) {
counter++;
expect(fn.constructor.name).toBe("AsyncFunction");
})
async #a() {}

@(function (fn) {
counter++;
expect(fn.constructor.name).toBe("GeneratorFunction");
})
*#g() {}

@(function (fn) {
counter++;
expect(fn.constructor.name).toBe("AsyncGeneratorFunction");
})
async *#ag() {}
}

expect(counter).toBe(3);
@@ -0,0 +1,10 @@
class Foo {
@dec
async #a() {}

@dec
*#g() {}

@dec
async *#ag() {}
}
@@ -0,0 +1,3 @@
{
"minNodeVersion": "16.11.0"
}
@@ -0,0 +1,15 @@
var _initProto, _dec, _call_a, _dec2, _call_g, _dec3, _call_ag;
_dec = dec;
_dec2 = dec;
_dec3 = dec;
class Foo {
static {
[_call_a, _call_g, _call_ag, _initProto] = babelHelpers.applyDecs2311(this, [[_dec, 2, "a", async function () {}], [_dec2, 2, "g", function* () {}], [_dec3, 2, "ag", async function* () {}]], [], 0, _ => #a in _).e;
}
constructor() {
_initProto(this);
}
#ag = _call_ag;
#g = _call_g;
#a = _call_a;
}

0 comments on commit df047d1

Please sign in to comment.