mirror of
https://github.com/morluto/rea
synced 2026-10-25 22:08:11 -04:00
fix(javascript): share iteration and equality invocation facts
This commit is contained in:
@@ -225,9 +225,30 @@ it("follows superclass getter effects through the selected receiver", () => {
|
||||
returned(`
|
||||
const shared = { value: 1 };
|
||||
class Base { get trigger2() { this.state.value = 2; return 0; } }
|
||||
class Box extends Base { state = shared; get trigger() { return super.trigger2; } }
|
||||
class Box extends Base { state = shared; get trigger2() { return 0; } get trigger() { return super.trigger2; } }
|
||||
new Box().trigger;
|
||||
return shared.value;
|
||||
`)?.status,
|
||||
).toBe("unknown");
|
||||
});
|
||||
|
||||
it("summarizes per-iteration disposal inside invoked getters", () => {
|
||||
expect(
|
||||
returned(`
|
||||
const shared = {value: 1, [Symbol.dispose]() {this.value = 2;}};
|
||||
const box = {state: shared, get trigger() {for (using owned of [this.state]) {} return 0;}};
|
||||
box.trigger;
|
||||
return shared.value;
|
||||
`)?.status,
|
||||
).toBe("unknown");
|
||||
});
|
||||
|
||||
it("keeps same-receiver equality in an inert getter precise", () => {
|
||||
expect(
|
||||
returned(`
|
||||
const state = {value: 1, get trigger() {return this == this;}};
|
||||
state.trigger;
|
||||
return state.value;
|
||||
`),
|
||||
).toEqual({ status: "literal", value: 1 });
|
||||
});
|
||||
|
||||
@@ -196,10 +196,9 @@ const emitterIdentity = (
|
||||
...read.binding.initializers,
|
||||
...read.binding.referenceInitializers,
|
||||
];
|
||||
const replaced = [
|
||||
...binding.initializers,
|
||||
...binding.referenceInitializers,
|
||||
].some(({ assignment }) => assignment);
|
||||
const replaced = binding.definitions.some(
|
||||
({ kind }) => kind === "assignment",
|
||||
);
|
||||
const origin = origins.length === 1 ? origins[0] : undefined;
|
||||
const complete =
|
||||
!replaced ||
|
||||
|
||||
@@ -365,6 +365,14 @@ class GetterResultWalker {
|
||||
#visit(current: GetterWork): void {
|
||||
const expression = unwrapJavaScriptExpression(current.node).node;
|
||||
if (t.isIdentifier(expression) && this.#alias(current, expression)) return;
|
||||
if (t.isForOfStatement(expression)) {
|
||||
this.#enqueue(() => ({
|
||||
...current,
|
||||
node: expression.right,
|
||||
path: [null, ...current.path],
|
||||
}));
|
||||
return;
|
||||
}
|
||||
if (t.isThisExpression(expression) || t.isSuper(expression))
|
||||
this.#thisValue(current, expression);
|
||||
else if (
|
||||
|
||||
@@ -10,8 +10,8 @@ export const semanticCoercionOperands = (
|
||||
if (node.operator === "instanceof") return [node.left, node.right];
|
||||
if (
|
||||
["==", "!="].includes(node.operator) &&
|
||||
isObject(node.left) &&
|
||||
isObject(node.right)
|
||||
((t.isThisExpression(node.left) && t.isThisExpression(node.right)) ||
|
||||
(isObject(node.left) && isObject(node.right)))
|
||||
)
|
||||
return [];
|
||||
return node.operator === "in" ? [node.left] : [node.left, node.right];
|
||||
|
||||
@@ -323,11 +323,10 @@ const accessorEffectOperands = (
|
||||
});
|
||||
if (
|
||||
t.isVariableDeclarator(node) &&
|
||||
node.init != null &&
|
||||
t.isVariableDeclaration(parent) &&
|
||||
(parent.kind === "using" || parent.kind === "await using")
|
||||
)
|
||||
operands.push({ kind: "escape", node: node.init });
|
||||
operands.push({ kind: "escape", node: node.init ?? node.id });
|
||||
for (const child of childNodes(node).reverse())
|
||||
pending.push({ node: child, parent: node });
|
||||
}
|
||||
@@ -445,7 +444,7 @@ export function* collectSemanticMemberMutationsSteps(
|
||||
const target = receiverReference
|
||||
? [...receiver, ...reference.path]
|
||||
: reference.path;
|
||||
if (operand.kind === "escape")
|
||||
if (operand.kind === "escape" || t.isSuper(operand.node))
|
||||
effects.push({ node: targetRoot, path: target });
|
||||
else
|
||||
pending.push({
|
||||
|
||||
Reference in New Issue
Block a user