Skip to content

Commit f45d9b3

Browse files
committed
emit setFunctionName call for undecorated class with accessors
1 parent ab03576 commit f45d9b3

4 files changed

Lines changed: 68 additions & 22 deletions

File tree

  • packages
    • babel-helper-create-class-features-plugin/src
    • babel-plugin-proposal-decorators/test/fixtures
      • 2023-11-accessors
      • 2023-11-classes/expressions-named-evaluation

packages/babel-helper-create-class-features-plugin/src/decorators.ts

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,18 @@ function generateClassProperty(
184184
}
185185
}
186186

187+
function assignIdForAnonymousClass(
188+
path: NodePath<t.Class>,
189+
className: string | t.Identifier | t.StringLiteral | undefined,
190+
) {
191+
if (!path.node.id) {
192+
path.node.id =
193+
typeof className === "string"
194+
? t.identifier(className)
195+
: path.scope.generateUidIdentifier("Class");
196+
}
197+
}
198+
187199
function addProxyAccessorsFor(
188200
className: t.Identifier,
189201
element: NodePath<ClassDecoratableElement>,
@@ -1031,6 +1043,8 @@ function transformClass(
10311043
let protoInitLocal: t.Identifier;
10321044
let staticInitLocal: t.Identifier;
10331045
const classIdName = path.node.id?.name;
1046+
// Whether to generate a setFunctionName call to preserve the class name
1047+
const setClassName = typeof className === "object" ? className : undefined;
10341048
// Check if the decorator does not reference function-specific
10351049
// context or the given identifier name or contains yield or await expression.
10361050
// `true` means "maybe" and `false` means "no".
@@ -1141,9 +1155,7 @@ function transformClass(
11411155
setterKey = t.cloneNode(key);
11421156
}
11431157

1144-
if (!path.node.id) {
1145-
path.node.id = path.scope.generateUidIdentifier("Class");
1146-
}
1158+
assignIdForAnonymousClass(path, className);
11471159

11481160
addProxyAccessorsFor(
11491161
path.node.id,
@@ -1163,6 +1175,16 @@ function transformClass(
11631175
}
11641176

11651177
if (!classDecorators && !hasElementDecorators) {
1178+
if (!path.node.id && typeof className === "string") {
1179+
path.node.id = t.identifier(className);
1180+
}
1181+
if (setClassName) {
1182+
path.node.body.body.unshift(
1183+
createStaticBlockFromExpressions([
1184+
createSetFunctionNameCall(state, setClassName),
1185+
]),
1186+
);
1187+
}
11661188
// If nothing is decorated and no assignments inserted, return
11671189
return;
11681190
}
@@ -1292,9 +1314,7 @@ function transformClass(
12921314
}
12931315
}
12941316
} else {
1295-
if (!path.node.id) {
1296-
path.node.id = path.scope.generateUidIdentifier("Class");
1297-
}
1317+
assignIdForAnonymousClass(path, className);
12981318
classIdLocal = t.cloneNode(path.node.id);
12991319
}
13001320

@@ -1458,9 +1478,7 @@ function transformClass(
14581478

14591479
locals = [newFieldInitId, getId, setId];
14601480
} else {
1461-
if (!path.node.id) {
1462-
path.node.id = path.scope.generateUidIdentifier("Class");
1463-
}
1481+
assignIdForAnonymousClass(path, className);
14641482
addProxyAccessorsFor(
14651483
path.node.id,
14661484
newPath,
@@ -1965,7 +1983,7 @@ function transformClass(
19651983
classDecorationsId ?? t.arrayExpression(classDecorations),
19661984
t.numericLiteral(classDecorationsFlag),
19671985
needsInstancePrivateBrandCheck ? lastInstancePrivateName : null,
1968-
typeof className === "object" ? className : undefined,
1986+
setClassName,
19691987
t.cloneNode(superClass),
19701988
state,
19711989
version,

packages/babel-plugin-proposal-decorators/test/fixtures/2023-11-accessors/undecorated-static-private/output.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,19 @@ class Foo {
1515
Foo.#B = v;
1616
}
1717
}
18-
Foo = class _Class {
18+
Foo = class Foo {
1919
static #A;
2020
static get #a() {
21-
return _Class.#A;
21+
return Foo.#A;
2222
}
2323
static set #a(v) {
24-
_Class.#A = v;
24+
Foo.#A = v;
2525
}
2626
static #B = 123;
2727
static get #b() {
28-
return _Class.#B;
28+
return Foo.#B;
2929
}
3030
static set #b(v) {
31-
_Class.#B = v;
31+
Foo.#B = v;
3232
}
3333
};

packages/babel-plugin-proposal-decorators/test/fixtures/2023-11-accessors/undecorated-static-public/output.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,26 +22,26 @@ class Foo {
2222
Foo.#C = v;
2323
}
2424
}
25-
Foo = class _Class {
25+
Foo = class Foo {
2626
static #A;
2727
static get a() {
28-
return _Class.#A;
28+
return Foo.#A;
2929
}
3030
static set a(v) {
31-
_Class.#A = v;
31+
Foo.#A = v;
3232
}
3333
static #B = 123;
3434
static get b() {
35-
return _Class.#B;
35+
return Foo.#B;
3636
}
3737
static set b(v) {
38-
_Class.#B = v;
38+
Foo.#B = v;
3939
}
4040
static #C = 456;
4141
static get ['c']() {
42-
return _Class.#C;
42+
return Foo.#C;
4343
}
4444
static set ['c'](v) {
45-
_Class.#C = v;
45+
Foo.#C = v;
4646
}
4747
};

packages/babel-plugin-proposal-decorators/test/fixtures/2023-11-classes/expressions-named-evaluation/exec.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,34 @@ const noop = () => {}
155155
expect(logs).toEqual(["computing f", "computing symbol", "A0", "1", "2", "3", "4", "5", "6", "7", "8", "[9]", "#_10"]);
156156
}
157157

158+
{
159+
const logs = [];
160+
const dec = () => {
161+
return {
162+
init(v) {
163+
logs.push(v.name);
164+
return v;
165+
}
166+
}
167+
};
168+
const f = () => { logs.push("computing f"); return 8. }
169+
170+
class C {
171+
@dec static accessor A0 = class { static accessor q; };
172+
@dec static accessor "1" = class { accessor q; };
173+
@dec static accessor 2 = class extends class {} { static accessor p; };
174+
@dec static accessor 3n = class extends class {} { accessor #q; };
175+
@dec static accessor ["4"] = class { static accessor p; };
176+
@dec static accessor [5] = class { static accessor #p; };
177+
@dec static accessor [6n] = class { accessor p; };
178+
@dec static accessor [f()] = class { @dec static accessor 7 = class { static accessor p }; };
179+
@dec static accessor [{ [Symbol.toPrimitive]: () => (logs.push("computing symbol"), Symbol(9)) }] = class { static accessor p; };
180+
@dec static accessor #_10 = class { static accessor #p; };
181+
}
182+
183+
expect(logs).toEqual(["computing f", "computing symbol", "A0", "1", "2", "3", "4", "5", "6", "7", "8", "[9]", "#_10"]);
184+
}
185+
158186
{
159187
const logs = [];
160188
const dec = decFactory(logs);

0 commit comments

Comments
 (0)