Skip to content

Commit

Permalink
Ensure non-static decorators are applied when a class is instantiated. (
Browse files Browse the repository at this point in the history
#15059)

* rename test cases

* fix: protoInit call should not be injected to static field initializer
  • Loading branch information
JLHwung committed Oct 19, 2022
1 parent 66d4fe9 commit db2789f
Show file tree
Hide file tree
Showing 16 changed files with 635 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,7 @@ function transformClass(

const elementDecoratorInfo: (DecoratorInfo | ComputedPropInfo)[] = [];

// The initializer of the first non-static field will be injected with the protoInit call
let firstFieldPath:
| NodePath<t.ClassProperty | t.ClassPrivateProperty>
| undefined;
Expand Down Expand Up @@ -767,7 +768,11 @@ function transformClass(
element.node.decorators = null;
}

if (!firstFieldPath && (kind === FIELD || kind === ACCESSOR)) {
if (
!firstFieldPath &&
!isStatic &&
(kind === FIELD || kind === ACCESSOR)
) {
firstFieldPath = element as NodePath<
t.ClassProperty | t.ClassPrivateProperty
>;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
var log = [];

function push(x) {
log.push(x);
return x;
}

function logClassDecoratorRun(a, b, c) {
push(a);
return function (el, { addInitializer }) {
push(b);
addInitializer(function () {
push(c);
});
return el;
};
}

function logAccessorDecoratorRun(a, b, c, d) {
push(a);
return function (el, { addInitializer }) {
push(b);
addInitializer(function () {
push(c);
});
return {
init: () => push(d),
};
};
}

function logFieldDecoratorRun(a, b) {
push(a);
return function (el) { push(b); return el; };
}

@logClassDecoratorRun(0, 19, 21)
@logClassDecoratorRun(1, 18, 20)
class A {
@logAccessorDecoratorRun(2, 11, 23, 27)
@logAccessorDecoratorRun(3, 10, 22, 26)
accessor a;

@logFieldDecoratorRun(4, 15)
@logFieldDecoratorRun(5, 14)
b;

@logFieldDecoratorRun(6, 17)
@logFieldDecoratorRun(7, 16)
#c;

@logAccessorDecoratorRun(8, 13, 25, 29)
@logAccessorDecoratorRun(9, 12, 24, 28)
accessor #d;

constructor() {
this.a = this.#d = null;
}
}

var nums = Array.from({ length: 22 }, (_, i) => i);
expect(log).toEqual(nums);

new A();

var nums = Array.from({ length: 30 }, (_, i) => i);
expect(log).toEqual(nums);
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
var log = [];

function push(x) {
log.push(x);
return x;
}

function logClassDecoratorRun(a, b, c) {
push(a);
return function (el, { addInitializer }) {
push(b);
addInitializer(function () {
push(c);
});
return el;
};
}

function logAccessorDecoratorRun(a, b, c, d) {
push(a);
return function (el, { addInitializer }) {
push(b);
addInitializer(function () {
push(c);
});
return {
init: () => push(d),
};
};
}

function logMethodDecoratorRun(a, b, c, d) {
push(a);
return function (el, { addInitializer }) {
push(b);
addInitializer(function () {
push(c);
});
return () => (el(), push(d))
};
}

@logClassDecoratorRun(0, 19, 21)
@logClassDecoratorRun(1, 18, 20)
class A {
@logAccessorDecoratorRun(2, 11, 23, 31)
@logAccessorDecoratorRun(3, 10, 22, 30)
accessor a;

@logMethodDecoratorRun(4, 13, 25, 35)
@logMethodDecoratorRun(5, 12, 24, 34)
b() {};

@logMethodDecoratorRun(6, 15, 27, 37)
@logMethodDecoratorRun(7, 14, 26, 36)
#c() {};

@logAccessorDecoratorRun(8, 17, 29, 33)
@logAccessorDecoratorRun(9, 16, 28, 32)
accessor #d;

constructor() {
this.b();
this.#c();
this.a = this.#d = null;
}
}

var nums = Array.from({ length: 22 }, (_, i) => i);
expect(log).toEqual(nums);

new A();

var nums = Array.from({ length: 38 }, (_, i) => i);
expect(log).toEqual(nums);
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ class A {
accessor #d;
}

var nums = Array.from({ length: 30 }, (_, i) => i);
expect(log).toEqual(nums);

new A();

var nums = Array.from({ length: 38 }, (_, i) => i);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
var log = [];

function push(x) {
log.push(x);
return x;
}

function logClassDecoratorRun(a, b, c) {
push(a);
return function (el, { addInitializer }) {
push(b);
addInitializer(function () {
push(c);
});
return el;
};
}

function logAccessorDecoratorRun(a, b, c, d) {
push(a);
return function (el, { addInitializer }) {
push(b);
addInitializer(function () {
push(c);
});
return {
init: () => push(d),
};
};
}

function logMethodDecoratorRun(a, b, c, d) {
push(a);
return function (el, { addInitializer }) {
push(b);
addInitializer(function () {
push(c);
});
return () => (el(), push(d))
};
}

@logClassDecoratorRun(0, 19, 29)
@logClassDecoratorRun(1, 18, 28)
class A {
static {
A.b(), A.#c();
}

@logAccessorDecoratorRun(2, 15, 31, 35)
@logAccessorDecoratorRun(3, 14, 30, 34)
accessor a;

@logMethodDecoratorRun(4, 11, 21, 25)
@logMethodDecoratorRun(5, 10, 20, 24)
static b() {};

@logMethodDecoratorRun(6, 13, 23, 27)
@logMethodDecoratorRun(7, 12, 22, 26)
static #c() {};

@logAccessorDecoratorRun(8, 17, 33, 37)
@logAccessorDecoratorRun(9, 16, 32, 36)
accessor #d;

constructor() {
this.a = this.#d = null;
}
}

var nums = Array.from({ length: 30 }, (_, i) => i);
expect(log).toEqual(nums);

new A();

var nums = Array.from({ length: 38 }, (_, i) => i);
expect(log).toEqual(nums);

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ class A {
accessor #h;
}

var nums = Array.from({ length: 46 }, (_, i) => i);
expect(log).toEqual(nums);

new A();

var nums = Array.from({ length: 54 }, (_, i) => i);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
var log = [];

function push(x) {
log.push(x);
return x;
}

function logClassDecoratorRun(a, b, c) {
push(a);
return function (el, { addInitializer }) {
push(b);
addInitializer(function () {
push(c);
});
return el;
};
}

function logAccessorDecoratorRun(a, b, c, d) {
push(a);
return function (el, { addInitializer }) {
push(b);
addInitializer(function () {
push(c);
});
return {
init: () => push(d),
};
};
}

function logMethodDecoratorRun(a, b, c, d) {
push(a);
return function (el, { addInitializer }) {
push(b);
addInitializer(function () {
push(c);
});
return () => (el(), push(d))
};
}

@logClassDecoratorRun(0, 19, 29)
@logClassDecoratorRun(1, 18, 28)
class A {
@logMethodDecoratorRun(2, 15, 31, 35)
@logMethodDecoratorRun(3, 14, 30, 34)
a() {}

@logAccessorDecoratorRun(4, 11, 21, 25)
@logAccessorDecoratorRun(5, 10, 20, 24)
static accessor b;

@logAccessorDecoratorRun(6, 13, 23, 27)
@logAccessorDecoratorRun(7, 12, 22, 26)
static accessor #c;

@logMethodDecoratorRun(8, 17, 33, 37)
@logMethodDecoratorRun(9, 16, 32, 36)
#d() {}

constructor() {
this.a();
this.#d();
}
}

var nums = Array.from({ length: 30 }, (_, i) => i);
expect(log).toEqual(nums);

new A();

var nums = Array.from({ length: 38 }, (_, i) => i);
expect(log).toEqual(nums);
Loading

0 comments on commit db2789f

Please sign in to comment.