feat(javascript): discover semantic call literals in feature traces (#7840)

* feat(javascript): discover semantic call literals in feature traces

* fix(javascript): bound retained call literals by transfer capacity

* test(javascript): align feature no-match diagnostic
This commit is contained in:
morluto authored and GitHub committed 2026-10-29 01:25:23 +08:00
1 parent 685f6db960
commit f9e7571a3d
20 files changed
+681 -15

No files matched your search

@@ -31,6 +31,99 @@ import { getterExpansionSource } from "../../../tests/fixtures/javascriptGetterE
const SHA256 = "a".repeat(64);
it("retains direct call literals and resolves literal queries to their call site", () => {
const source =
'api.rpc("proc_0", 7, false, null, dynamic, ...values, `fixed`, -3);';
const graph = graphFor(source);
const call = graph.nodes.find(({ kind }) => kind === "call-site");
const argumentsValue = call?.properties.arguments;
expect(argumentsValue).toEqual([
expect.objectContaining({
index: 0,
value: "proc_0",
source_range: expect.any(Object),
}),
expect.objectContaining({ index: 1, value: 7 }),
expect.objectContaining({ index: 2, value: false }),
expect.objectContaining({ index: 3, value: null }),
expect.objectContaining({ index: 6, value: "fixed" }),
expect.objectContaining({ index: 7, value: -3 }),
]);
if (call === undefined) throw new Error("Expected call site");
const trace = queryJavaScriptSemanticGraph(
graph,
javaScriptSemanticQueryInputSchema.parse({
seed: { kind: "literal", value: "proc_0" },
direction: "forward-influence",
}),
);
expect(trace.seed_node_ids).toContain(call.node_id);
});
it("reports the primitive byte bound when a direct argument is too large", () => {
const source = `rpc(${JSON.stringify("x".repeat(175_000))});`;
const ir = analyzeJavaScriptSemantics(source);
expect(ir.coverage.resourceLimits).toContain("primitive-bytes");
const graph = graphFor(source, ir);
const call = graph.nodes.find(({ kind }) => kind === "call-site");
expect(call?.properties.arguments).toBeUndefined();
expect(graph.coverage.status).not.toBe("complete");
const unknown = graph.unknowns.find(
(entry) =>
entry.node_id === call?.node_id && entry.reason === "resource-limit",
);
expect(unknown?.detail).toMatch(/primitive string-byte budget exceeded/i);
expect(
graph.evidence_contexts.find(
(entry) => entry.context_id === unknown?.evidence.context_id,
),
).toMatchObject({
coverage: {
limits: expect.arrayContaining([
expect.objectContaining({
name: "javascript_semantic_primitive_bytes",
}),
]),
},
});
});
it("keeps a large call's graph within the worker record limit and reports omitted arguments", () => {
const value = JSON.stringify("x".repeat(140_000));
const source = `rpc(${Array.from({ length: 64 }, () => value).join(",")});`;
const graph = graphFor(source);
const call = graph.nodes.find(({ kind }) => kind === "call-site");
if (call === undefined) throw new Error("Expected call site");
const values = call.properties.arguments;
expect(Array.isArray(values)).toBe(true);
if (!Array.isArray(values)) throw new Error("Expected retained arguments");
expect(values.length).toBeGreaterThan(0);
expect(values.length).toBeLessThan(64);
expect(
Buffer.byteLength(`${JSON.stringify({ kind: "node", value: call })}\n`),
).toBeLessThanOrEqual(8 * 1024 * 1024);
const unknown = graph.unknowns.find(
(entry) =>
entry.node_id === call.node_id &&
entry.detail.includes("worker transfer record ceiling"),
);
expect(unknown).toMatchObject({ reason: "resource-limit" });
expect(
graph.evidence_contexts.find(
(entry) => entry.context_id === unknown?.evidence.context_id,
),
).toMatchObject({
coverage: {
limits: expect.arrayContaining([
expect.objectContaining({
name: "javascript_analysis_transfer_record_bytes",
value: 8 * 1024 * 1024,
}),
]),
},
});
});
it("projects bounded alias selection as a resource-limit unknown", () => {
const source = aliasSelectionBudgetSource();
const ir = analyzeJavaScriptSemantics(source);