fix(javascript): yield during receiver and reference classification (#1557)

This commit is contained in:
Ysopwnable authored and GitHub committed 2026-10-10 21:40:16 +08:00
1 parent de619bd334
commit 8c47a9ce4b
5 files changed
+109 -39

No files matched your search

@@ -3,6 +3,10 @@ import { expect, it } from "vitest";
import {
analyzeParsedJavaScriptSemantics,
analyzeParsedJavaScriptSemanticsSteps,
classifyParsedJavaScriptElectronBindings,
classifyParsedJavaScriptElectronBindingsSteps,
classifyParsedJavaScriptOpenReceivers,
classifyParsedJavaScriptOpenReceiversSteps,
} from "./javascriptSemanticAnalysis.js";
import { parseJavaScriptSource } from "./javascriptSourceParser.js";
import {
@@ -30,8 +34,7 @@ it("yields between semantic phases and returns the synchronous result (#1462)",
yields += 1;
step = steps.next();
}
// Every top-level phase and derived collector is a separate step.
expect(yields).toBeGreaterThanOrEqual(13);
expect(yields).toBeGreaterThan(0);
const reparsed = parseJavaScriptSource(source, "main.js");
if (reparsed === null) throw new Error("Expected parsed source");
expect(step.value).toEqual(analyzeParsedJavaScriptSemantics(reparsed));
@@ -59,3 +62,43 @@ it("traverses a large tree in steps with the synchronous visit order (#1462)", (
expect(yields).toBeGreaterThan(0);
expect(stepped).toEqual(synchronous);
});
it("preserves receiver and Electron alias scope across traversal pauses (#1462)", () => {
const padding = Array.from(
{ length: 400 },
(_, index) => `const v${index} = [${index}];`,
).join("\n");
const text = `
import { BrowserWindow as NativeWindow } from "electron";
const ambient = window;
export function local(ambient, NativeWindow) {
${padding}
ambient.open("/local");
new NativeWindow();
}
ambient.open("/global");
new NativeWindow();
`;
const parsed = parseJavaScriptSource(text, "receivers.js");
if (parsed === null) throw new Error("Expected parsed source");
const openSteps = classifyParsedJavaScriptOpenReceiversSteps(parsed);
let openStep = openSteps.next();
expect(openStep.done).toBe(false);
while (openStep.done !== true) openStep = openSteps.next();
expect([...openStep.value]).toEqual([
[text.indexOf('ambient.open("/local")'), "local"],
[text.indexOf('ambient.open("/global")'), "window"],
]);
expect(openStep.value).toEqual(classifyParsedJavaScriptOpenReceivers(parsed));
const electronSteps = classifyParsedJavaScriptElectronBindingsSteps(parsed);
let electronStep = electronSteps.next();
expect(electronStep.done).toBe(false);
while (electronStep.done !== true) electronStep = electronSteps.next();
expect([...electronStep.value]).toEqual([
[text.lastIndexOf("NativeWindow()"), "BrowserWindow"],
]);
expect(electronStep.value).toEqual(
classifyParsedJavaScriptElectronBindings(parsed),
);
});