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

@@ -51,6 +51,7 @@ import {
import type { JsonValue } from "../../domain/jsonValue.js";
import {
JAVASCRIPT_ANALYSIS_RESOURCE_DEFAULTS,
JAVASCRIPT_ANALYSIS_TRANSFER_RECORD_BYTES,
JAVASCRIPT_SEMANTIC_ITEM_MAXIMUM,
javaScriptAnalysisCoverageLimits,
javaScriptSemanticCeilingCoverage,
@@ -71,6 +72,7 @@ import {
semanticFamilyStatus,
} from "./JavaScriptSemanticGraphProjection.js";
import {
constructSemanticGraphNode,
addSemanticFallbackRoot as addFallbackRoot,
addSemanticGraphUnknown,
recordSemanticUnknownOmission,
@@ -771,14 +773,102 @@ function* createCallSiteNodes(
call.callerCallableId === null
? null
: (callables.get(call.callerCallableId)?.node_id ?? null);
const node = retainNode(state, file, {
kind: "call-site",
const nodeInput = {
kind: "call-site" as const,
roleKey: `call:${call.callSiteId}`,
location: call.location,
label: call.kind,
functionNodeId: owner,
};
// Include the complete node and worker JSON envelope before retaining any
// arguments. Each entry is charged by its encoded size and comma, so even
// worst-case escaping cannot overflow the worker's single-record ceiling.
let recordBytes = 0;
if (call.arguments.some((argument) => Object.hasOwn(argument, "literal"))) {
const baseline = constructSemanticGraphNode(file, nodeInput, state);
recordBytes = Buffer.byteLength(
`${JSON.stringify({ kind: "node", value: { ...baseline, properties: { arguments: [] } } })}\n`,
);
}
const argumentsValue: JsonValue[] = [];
let transferOmitted = 0;
for (const argument of call.arguments) {
if (!Object.hasOwn(argument, "literal")) continue;
const item = {
index: argument.index,
value: argument.literal ?? null,
source_range:
argument.valueExpressionLocation === null
? null
: {
start: { ...argument.valueExpressionLocation.start },
end: { ...argument.valueExpressionLocation.end },
},
};
const size =
Buffer.byteLength(JSON.stringify(item)) +
(argumentsValue.length === 0 ? 0 : 1);
if (recordBytes + size > JAVASCRIPT_ANALYSIS_TRANSFER_RECORD_BYTES) {
transferOmitted += 1;
continue;
}
argumentsValue.push(item);
recordBytes += size;
}
const node = retainNode(state, file, {
...nodeInput,
...(argumentsValue.length === 0
? {}
: { properties: { arguments: argumentsValue } }),
});
if (node !== null) result.set(call.callSiteId, node);
if (node !== null) {
result.set(call.callSiteId, node);
if (transferOmitted > 0) {
const detail = `${String(transferOmitted)} direct call arguments exceeded the ${String(JAVASCRIPT_ANALYSIS_TRANSFER_RECORD_BYTES)}-byte worker transfer record ceiling.`;
addSemanticGraphUnknown(state, {
node_id: node.node_id,
family: "call-flow",
relation_kinds: ["argument-to-parameter"],
reason: "resource-limit",
detail,
candidate_node_ids: [],
evidence: {
...unknownSemanticEvidence(file, call.location),
coverage: partialApplicationCoverage(
javaScriptAnalysisCoverageLimits({
transfer_record_bytes:
JAVASCRIPT_ANALYSIS_TRANSFER_RECORD_BYTES,
}),
null,
),
limitations: [detail],
},
});
}
if (
call.arguments.some(
(argument) => argument.literalResourceLimit === "primitive-bytes",
)
) {
const limit = "primitive-bytes";
addSemanticGraphUnknown(state, {
node_id: node.node_id,
family: "call-flow",
relation_kinds: ["argument-to-parameter"],
reason: "resource-limit",
detail: semanticResourceLimitReason(limit),
candidate_node_ids: [],
evidence: {
...unknownSemanticEvidence(file, call.location),
coverage: partialApplicationCoverage(
semanticResourceLimitCoverage([limit]),
null,
),
limitations: [semanticResourceLimitReason(limit)],
},
});
}
}
}
return result;
}