mirror of
https://github.com/morluto/rea.git
synced 2026-11-14 18:52:48 +00:00
fix(javascript): project getter class static work onto the captured receiver
Static blocks and static field values run when a class is defined, so a getter that returns a class whose static work writes through an alias of the getter's receiver changes that receiver. The definition-time walk now visits static work too; `this` inside it stays the class. Refs #9229 Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
This commit is contained in:
1 parent
91297ca745
commit
39c820c90d
2 files changed
+34
-1
No files matched your search
@@ -233,6 +233,24 @@ describe("getter receiver mutation aliases (#1665, #2654)", () => {
|
||||
).toMatchObject({ status: "literal", value: 1 });
|
||||
});
|
||||
|
||||
it.each([
|
||||
["static block", "class { static { self.x = 2; } }"],
|
||||
["static field value", "class { static s = (self.x = 2); }"],
|
||||
[
|
||||
"static block of a nested heritage class",
|
||||
"class extends (class { static { self.x = 2; } }) {}",
|
||||
],
|
||||
])(
|
||||
"invalidates the receiver after a %s writes through a captured alias",
|
||||
(_label, result) => {
|
||||
expect(
|
||||
resultValue(
|
||||
`const box = { x: 1, get trigger() { const self = this; return ${result}; } }; box.trigger; return box.x;`,
|
||||
),
|
||||
).toMatchObject({ status: "unknown" });
|
||||
},
|
||||
);
|
||||
|
||||
it("terminates recursive receiver getters", () => {
|
||||
expect(
|
||||
resultValue(
|
||||
|
||||
@@ -405,12 +405,27 @@ const computedDefinitionMembers = (node: t.Function | t.Class): t.Node[] => {
|
||||
);
|
||||
};
|
||||
|
||||
/** Expressions a definition runs immediately; deferred bodies and class-receiver initializers stay out. */
|
||||
/**
|
||||
* Expressions a definition runs immediately: heritage, computed keys, static
|
||||
* blocks and static field values. Deferred bodies and instance initializers
|
||||
* stay out; `this` inside static work is the class, not the enclosing receiver.
|
||||
*/
|
||||
const definitionTimeExpressions = (node: t.Function | t.Class): t.Node[] => [
|
||||
...(t.isClass(node) && node.superClass != null ? [node.superClass] : []),
|
||||
...computedDefinitionMembers(node).flatMap((member) =>
|
||||
"key" in member ? [member.key] : [],
|
||||
),
|
||||
...(t.isClass(node)
|
||||
? node.body.body.flatMap((member): t.Node[] =>
|
||||
t.isStaticBlock(member)
|
||||
? [member]
|
||||
: (t.isClassProperty(member) || t.isClassPrivateProperty(member)) &&
|
||||
member.static &&
|
||||
member.value != null
|
||||
? [member.value]
|
||||
: [],
|
||||
)
|
||||
: []),
|
||||
];
|
||||
|
||||
/** Collect invocation operands once; receiver interpretation belongs to the getter owner. */
|
||||
|
||||
Reference in new issue
Block a user