Skip to content

Commit

Permalink
[setPublicClassFields] Use define for static name/length
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolo-ribaudo committed Mar 12, 2022
1 parent a7b1181 commit fcfaa05
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 3 deletions.
27 changes: 24 additions & 3 deletions packages/babel-helper-create-class-features-plugin/src/fields.ts
Expand Up @@ -936,6 +936,18 @@ export type PropNode =
| t.StaticBlock;
export type PropPath = NodePath<PropNode>;

function isNameOrLength(node: t.ClassProperty) {
if (node.key.type === "Identifier") {
return (
!node.computed && (node.key.name === "name" || node.key.name === "length")
);
}
if (node.key.type === "StringLiteral") {
return node.key.value === "name" || node.key.value === "length";
}
return false;
}

export function buildFieldsInitNodes(
ref: t.Identifier,
superRef: t.Expression | undefined,
Expand Down Expand Up @@ -1019,10 +1031,19 @@ export function buildFieldsInitNodes(
);
break;
case isStatic && isPublic && isField && setPublicClassFields:
needsClassRef = true;
// Functions always have non-writable .name and .length properties,
// so we must always use [[Define]] for them.
// It might still be possible to a computed static fields whose resulting
// key is "name" or "length", but the assumption is telling us that it's
// not going to happen.
// @ts-expect-error checked in switch
staticNodes.push(buildPublicFieldInitLoose(t.cloneNode(ref), prop));
break;
if (!isNameOrLength(prop.node)) {
needsClassRef = true;
// @ts-expect-error checked in switch
staticNodes.push(buildPublicFieldInitLoose(t.cloneNode(ref), prop));
break;
}
// falls through
case isStatic && isPublic && isField && !setPublicClassFields:
needsClassRef = true;
staticNodes.push(
Expand Down
@@ -0,0 +1,11 @@
class A {
static name = 1;
static length = 2;
static foo = 3;
static [bar] = 4;
static ["name"] = 5;
static [name] = 6;

name = 7;
length = 8;
}
@@ -0,0 +1,19 @@
let _bar, _name;

_bar = bar;
_name = name;

class A {
constructor() {
this.name = 7;
this.length = 8;
}

}

babelHelpers.defineProperty(A, "name", 1);
babelHelpers.defineProperty(A, "length", 2);
A.foo = 3;
A[_bar] = 4;
babelHelpers.defineProperty(A, "name", 5);
A[_name] = 6;

0 comments on commit fcfaa05

Please sign in to comment.