Skip to content

Commit 8855e4c

Browse files
[setPublicClassFields] Use define for static name/length (#14351)
* [setPublicClassFields] Use define for static `name`/`length` * Cache property access
1 parent cb74c37 commit 8855e4c

3 files changed

Lines changed: 54 additions & 3 deletions

File tree

  • packages
    • babel-helper-create-class-features-plugin/src
    • babel-plugin-proposal-class-properties/test/fixtures/assumption-setPublicClassFields/length-name-use-define

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

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,16 @@ export type PropNode =
936936
| t.StaticBlock;
937937
export type PropPath = NodePath<PropNode>;
938938

939+
function isNameOrLength({ key, computed }: t.ClassProperty) {
940+
if (key.type === "Identifier") {
941+
return !computed && (key.name === "name" || key.name === "length");
942+
}
943+
if (key.type === "StringLiteral") {
944+
return key.value === "name" || key.value === "length";
945+
}
946+
return false;
947+
}
948+
939949
export function buildFieldsInitNodes(
940950
ref: t.Identifier,
941951
superRef: t.Expression | undefined,
@@ -1019,10 +1029,19 @@ export function buildFieldsInitNodes(
10191029
);
10201030
break;
10211031
case isStatic && isPublic && isField && setPublicClassFields:
1022-
needsClassRef = true;
1032+
// Functions always have non-writable .name and .length properties,
1033+
// so we must always use [[Define]] for them.
1034+
// It might still be possible to a computed static fields whose resulting
1035+
// key is "name" or "length", but the assumption is telling us that it's
1036+
// not going to happen.
10231037
// @ts-expect-error checked in switch
1024-
staticNodes.push(buildPublicFieldInitLoose(t.cloneNode(ref), prop));
1025-
break;
1038+
if (!isNameOrLength(prop.node)) {
1039+
needsClassRef = true;
1040+
// @ts-expect-error checked in switch
1041+
staticNodes.push(buildPublicFieldInitLoose(t.cloneNode(ref), prop));
1042+
break;
1043+
}
1044+
// falls through
10261045
case isStatic && isPublic && isField && !setPublicClassFields:
10271046
needsClassRef = true;
10281047
staticNodes.push(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class A {
2+
static name = 1;
3+
static length = 2;
4+
static foo = 3;
5+
static [bar] = 4;
6+
static ["name"] = 5;
7+
static [name] = 6;
8+
static "name" = 7;
9+
10+
name = 8;
11+
length = 9;
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
let _bar, _name;
2+
3+
_bar = bar;
4+
_name = name;
5+
6+
class A {
7+
constructor() {
8+
this.name = 8;
9+
this.length = 9;
10+
}
11+
12+
}
13+
14+
babelHelpers.defineProperty(A, "name", 1);
15+
babelHelpers.defineProperty(A, "length", 2);
16+
A.foo = 3;
17+
A[_bar] = 4;
18+
babelHelpers.defineProperty(A, "name", 5);
19+
A[_name] = 6;
20+
babelHelpers.defineProperty(A, "name", 7);

0 commit comments

Comments
 (0)