fix: extract nested JS function declarations (#2653) - #2705
Conversation
There was a problem hiding this comment.
Graphify reviewed this change.
Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).
Formal verification. No changes could be formally verified in this run.
Graphify review — findings
This PR adds handling for named function declarations nested inside other JavaScript/TypeScript functions in the generic extractor (_extract_generic). A new recursive _scan_js_nested_functions helper walks function bodies to emit nodes for nested named functions, wire up contains edges from their enclosing function, track them as callable definitions, and register their bodies for further descent. It also changes _tracked_body_ids to key on body node objects directly rather than id(...). On the test side, it adds three new tests in test_extract.py covering single-level and deeply nested function declarations plus local variable suppression, and updates an existing test in test_js_dynamic_imports.py so nested-function calls now attribute to the inner function (with a contains edge from the outer) rather than the enclosing function. Reviewers may want to focus on the recursive scan logic, the interaction with existing closure-descent tracking (#1630/#2575), and the behavioral shift in call attribution reflected by the modified dynamic-imports test.
No blocking issues surfaced. 4 lower-confidence candidates did not survive cross-model review.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 887 functions depend on the 524 functions this change touches.
Health — this change adds coupling hotspots:
- worse:
extract_js()— 76 callers, 3 callees - worse:
walk()— 1 callers, 55 callees - new:
_scan_js_nested_functions()— 1 callers, 7 callees
Verification — 887 functions in the blast radius were not formally verified this run (proofs are advisory here).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 832 function(s) in the blast radius were not formally verified this run
Formal verification
Could not verify: Could not verify \_extract\_generic.
The verifier did not have enough to check \_extract\_generic, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: parameter `path` is annotated `Path` — outside the synthesizable primitive/collection set
· 1 grounded finding(s) anchored inline below; 2 more finding(s) on lines outside this diff (see the check run).
Summary
Fixes #2653.
Named JavaScript/TypeScript function declarations nested inside another function were not emitted as graph nodes. As a result, calls from nested functions could be attributed to the enclosing function or become dangling edges.
For example: