Skip to content

Commit

Permalink
Fix static accessors with subclasses
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolo-ribaudo committed Apr 16, 2023
1 parent fd2f1e9 commit cc101de
Show file tree
Hide file tree
Showing 12 changed files with 87 additions and 38 deletions.
Expand Up @@ -165,24 +165,29 @@ function generateClassProperty(
}

function addProxyAccessorsFor(
className: t.Identifier,
element: NodePath<ClassDecoratableElement>,
originalKey: t.PrivateName | t.Expression,
targetKey: t.PrivateName,
version: DecoratorVersionKind,
isComputed = false,
): void {
const { static: isStatic } = element.node;

const thisArg =
version === "2023-03" && isStatic ? className : t.thisExpression();

const getterBody = t.blockStatement([
t.returnStatement(
t.memberExpression(t.thisExpression(), t.cloneNode(targetKey)),
t.memberExpression(t.cloneNode(thisArg), t.cloneNode(targetKey)),
),
]);

const setterBody = t.blockStatement([
t.expressionStatement(
t.assignmentExpression(
"=",
t.memberExpression(t.thisExpression(), t.cloneNode(targetKey)),
t.memberExpression(t.cloneNode(thisArg), t.cloneNode(targetKey)),
t.identifier("v"),
),
),
Expand Down Expand Up @@ -538,7 +543,14 @@ function transformClass(
const newField = generateClassProperty(newId, valueNode, isStatic);

const [newPath] = element.replaceWith(newField);
addProxyAccessorsFor(newPath, key, newId, computed);
addProxyAccessorsFor(
path.node.id,
newPath,
key,
newId,
version,
computed,
);
}
}

Expand Down Expand Up @@ -698,7 +710,14 @@ function transformClass(

locals = [newFieldInitId, getId, setId];
} else {
addProxyAccessorsFor(newPath, key, newId, isComputed);
addProxyAccessorsFor(
path.node.id,
newPath,
key,
newId,
version,
isComputed,
);
locals = newFieldInitId;
}
} else if (kind === FIELD) {
Expand Down
@@ -0,0 +1,12 @@
// https://github.com/tc39/proposal-decorators/issues/468

class A {
static accessor x;

@(() => {}) static accessor y;
}

class B extends A {}

expect(() => B.x).not.toThrow();
expect(() => B.y).not.toThrow();
Expand Up @@ -3,22 +3,22 @@ const dec = () => {};
_computedKey = 'c';
class Foo {
static get a() {
return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _A);
return babelHelpers.classStaticPrivateFieldSpecGet(Foo, Foo, _A);
}
static set a(v) {
babelHelpers.classStaticPrivateFieldSpecSet(this, Foo, _A, v);
babelHelpers.classStaticPrivateFieldSpecSet(Foo, Foo, _A, v);
}
static get b() {
return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _B);
return babelHelpers.classStaticPrivateFieldSpecGet(Foo, Foo, _B);
}
static set b(v) {
babelHelpers.classStaticPrivateFieldSpecSet(this, Foo, _B, v);
babelHelpers.classStaticPrivateFieldSpecSet(Foo, Foo, _B, v);
}
static get [_computedKey]() {
return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _C);
return babelHelpers.classStaticPrivateFieldSpecGet(Foo, Foo, _C);
}
static set [_computedKey](v) {
babelHelpers.classStaticPrivateFieldSpecSet(this, Foo, _C, v);
babelHelpers.classStaticPrivateFieldSpecSet(Foo, Foo, _C, v);
}
}
(() => {
Expand Down
@@ -1,16 +1,16 @@
const dec = () => {};
class Foo {}
function _get_a() {
return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _A);
return babelHelpers.classStaticPrivateFieldSpecGet(Foo, Foo, _A);
}
function _set_a(v) {
babelHelpers.classStaticPrivateFieldSpecSet(this, Foo, _A, v);
babelHelpers.classStaticPrivateFieldSpecSet(Foo, Foo, _A, v);
}
function _get_b() {
return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _B);
return babelHelpers.classStaticPrivateFieldSpecGet(Foo, Foo, _B);
}
function _set_b(v) {
babelHelpers.classStaticPrivateFieldSpecSet(this, Foo, _B, v);
babelHelpers.classStaticPrivateFieldSpecSet(Foo, Foo, _B, v);
}
var _b = {
get: _get_b,
Expand Down
@@ -1,22 +1,22 @@
const dec = () => {};
class Foo {
static get a() {
return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _A);
return babelHelpers.classStaticPrivateFieldSpecGet(Foo, Foo, _A);
}
static set a(v) {
babelHelpers.classStaticPrivateFieldSpecSet(this, Foo, _A, v);
babelHelpers.classStaticPrivateFieldSpecSet(Foo, Foo, _A, v);
}
static get b() {
return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _B);
return babelHelpers.classStaticPrivateFieldSpecGet(Foo, Foo, _B);
}
static set b(v) {
babelHelpers.classStaticPrivateFieldSpecSet(this, Foo, _B, v);
babelHelpers.classStaticPrivateFieldSpecSet(Foo, Foo, _B, v);
}
static get ['c']() {
return babelHelpers.classStaticPrivateFieldSpecGet(this, Foo, _C);
return babelHelpers.classStaticPrivateFieldSpecGet(Foo, Foo, _C);
}
static set ['c'](v) {
babelHelpers.classStaticPrivateFieldSpecSet(this, Foo, _C, v);
babelHelpers.classStaticPrivateFieldSpecSet(Foo, Foo, _C, v);
}
}
var _A = {
Expand Down
@@ -0,0 +1,12 @@
// https://github.com/tc39/proposal-decorators/issues/468

class A {
static accessor x;

@(() => {}) static accessor y;
}

class B extends A {}

expect(() => B.x).not.toThrow();
expect(() => B.y).not.toThrow();
@@ -0,0 +1,3 @@
{
"minNodeVersion": "16.11.0"
}
Expand Up @@ -8,23 +8,23 @@ class Foo {
}
static #A = _init_a(this);
static get a() {
return this.#A;
return Foo.#A;
}
static set a(v) {
this.#A = v;
Foo.#A = v;
}
static #B = _init_b(this, 123);
static get b() {
return this.#B;
return Foo.#B;
}
static set b(v) {
this.#B = v;
Foo.#B = v;
}
static #C = _init_computedKey(this, 456);
static get [_computedKey]() {
return this.#C;
return Foo.#C;
}
static set [_computedKey](v) {
this.#C = v;
Foo.#C = v;
}
}
Expand Up @@ -2,16 +2,16 @@ const dec = () => {};
class Foo {
static #A;
static get #a() {
return this.#A;
return Foo.#A;
}
static set #a(v) {
this.#A = v;
Foo.#A = v;
}
static #B = 123;
static get #b() {
return this.#B;
return Foo.#B;
}
static set #b(v) {
this.#B = v;
Foo.#B = v;
}
}
Expand Up @@ -2,23 +2,23 @@ const dec = () => {};
class Foo {
static #A;
static get a() {
return this.#A;
return Foo.#A;
}
static set a(v) {
this.#A = v;
Foo.#A = v;
}
static #B = 123;
static get b() {
return this.#B;
return Foo.#B;
}
static set b(v) {
this.#B = v;
Foo.#B = v;
}
static #C = 456;
static get ['c']() {
return this.#C;
return Foo.#C;
}
static set ['c'](v) {
this.#C = v;
Foo.#C = v;
}
}
Expand Up @@ -41,10 +41,10 @@ new class extends babelHelpers.identity {
static get k() {}
static set l(v) {}
static get m() {
return this.#C;
return Class.#C;
}
static set m(v) {
this.#C = v;
Class.#C = v;
}
set #r(v) {
_set_r(this, v);
Expand Down
@@ -0,0 +1,3 @@
{
"minNodeVersion": "16.11.0"
}

0 comments on commit cc101de

Please sign in to comment.