fix(packages/coding-agent): corrected js import rewriting empty AST body

- Added guard for ASTs with no body and trimmed trailing EmptyStatement nodes before final-expression capture.
- Exposed wrapCode via context-manager export for external JS import-rewrite callers.
- Added regression test asserting final-expression wrapping when trailing semicolons follow await.
This commit is contained in:
can1357
2026-05-13 05:24:33 +02:00
parent 218fe8b892
commit db1a3fd7b1
3 changed files with 13 additions and 3 deletions
@@ -17,7 +17,7 @@ import type {
WorkerOutbound,
} from "./worker-protocol";
export { rewriteImports } from "./shared/rewrite-imports";
export { rewriteImports, wrapCode } from "./shared/rewrite-imports";
export type { JsDisplayOutput } from "./worker-protocol";
export interface VmRunState {
@@ -222,7 +222,11 @@ export function demoteTopLevelLexicals(code: string): string {
function returnFinalExpression(code: string): { source: string; returned: boolean } {
const ast = parseProgram(code);
const last = ast?.program.body.at(-1);
const body = ast?.program.body;
if (!body) return { source: code, returned: false };
let lastIndex = body.length - 1;
while (lastIndex >= 0 && body[lastIndex]?.type === "EmptyStatement") lastIndex--;
const last = lastIndex >= 0 ? body[lastIndex] : undefined;
if (last?.type !== "ExpressionStatement") return { source: code, returned: false };
const expression = last as BabelExpressionStatement;
@@ -1,6 +1,6 @@
import { describe, expect, it } from "bun:test";
import { rewriteImports } from "../../src/eval/js/context-manager";
import { rewriteImports, wrapCode } from "../../src/eval/js/context-manager";
// Test fixtures embed user-supplied `import(...)` syntax that the rewriter must
// transform. The strings are split so static-analysis heuristics don't read them
@@ -124,4 +124,10 @@ describe("rewriteImports", () => {
// Should not throw; should fall through to the VM which will surface the syntax error.
expect(() => rewriteImports(code)).not.toThrow();
});
it("captures the final expression even when trailing empty statements follow", () => {
const wrapped = wrapCode("await Promise.resolve(1);;");
expect(wrapped.finalExpressionReturned).toBe(true);
expect(wrapped.source).toContain("__omp_set_final_expr__((await Promise.resolve(1)))");
});
});