feat(javascript): link assignment right-hand sides to their writes (#6206)

* feat(javascript): link assignment right-hand sides to their writes

A declaration carries its value forward, but a later assignment to a
variable, a property or through a compound operator stopped the forward
trace at the right-hand-side read. The semantic IR now records one
syntactic assignment flow per simple assignment target (ranges, operator,
owning callable), and the graph projection connects each retained read
of the right-hand side to the write occurrence through a defines
relation. Compound assignments also consume the previous value of the
target; the written value itself stays unknown, keeping the boundary of
#4342 intact.

Fixes #6193

* fix(javascript): preserve computed key assignment ownership

* test(javascript): retain nested callback assignment ownership

* docs(javascript): record assignment influence verification

* test(mcp): isolate mocks and acknowledge cancellation boundaries

* test(javascript): retain CLI diagnostics and current-main verification

---------

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
This commit is contained in:
Iven Kooandgensokyo-dev authored and GitHub committed 2026-10-24 10:04:38 +08:00
1 parent 2968d1e932
commit 9df94a62cd
17 files changed
+702 -35

No files matched your search

@@ -34,6 +34,7 @@ import {
projectSemanticRequests,
} from "./JavaScriptSemanticGraphDataProjection.js";
import { projectSemanticResources } from "./JavaScriptSemanticGraphResourceProjection.js";
import { projectSemanticAssignments } from "./JavaScriptSemanticGraphAssignmentProjection.js";
import { projectSemanticObjects } from "./JavaScriptSemanticGraphObjectProjection.js";
import { projectSemanticValues } from "./JavaScriptSemanticGraphValueProjection.js";
import {
@@ -712,6 +713,8 @@ function* projectFileSteps(
returnSiteNodes,
argumentNodes: new Map(),
referenceNodes: [],
readNodes: [],
writeNodes: [],
callResolutions: new Map(
ir.callSites.map((call) => [
call.callSiteId,
@@ -858,7 +861,11 @@ function* projectDefinitionsAndReferences(
reference.bindingId === null
? undefined
: context.bindingNodes.get(reference.bindingId);
if (expression !== null) context.referenceNodes.push(expression);
if (expression !== null) {
context.referenceNodes.push(expression);
if (reference.role === "read") context.readNodes.push(expression);
if (reference.role === "write") context.writeNodes.push(expression);
}
if (binding === undefined || expression === null) continue;
if (reference.role === "read")
addRelation(context.state, {
@@ -977,6 +984,7 @@ const FILE_PROJECTION_PASSES: readonly ((
) => Iterator<void, void> | void)[] = [
projectSemanticValues,
projectSemanticObjects,
projectSemanticAssignments,
projectCalls,
projectSemanticPromises,
projectSemanticEvents,