Skip to content

fix(extraction): index const-bound functions inside a body as symbols (#1669) - #1774

Merged
colbymchenry merged 5 commits into
mainfrom
forge/fix-1669-declarator-bound-nested-functions
Sep 8, 2026
Merged

colbymchenry merged 5 commits into
mainfrom
forge/fix-1669-declarator-bound-nested-functions

Conversation

@colbymchenry

Copy link
Copy Markdown
Owner

Fixes #1669.

Lands / rebases #1679 onto current main (CHANGELOG conflict with #1772 / #1674+#1639 only).

Problem

const handleClear = () => {…} inside a component — every React handler written without useCallback — was never a symbol. The body walker named nested function declarations and hook-bound arrows (const x = useCallback(…)), but a plain declarator-bound arrow or function expression fell through, so the handler was absent from callers / callees / impact ("Symbol not found", which reads exactly like "no callers") and its calls attributed to the component. The same declaration at module scope already names a function.

Change

  • Body walker (wasm) and kernel: an anonymous arrow_function / function_expression that is the whole value of a variable_declarator with a plain identifier name is extracted as a function, contained by the enclosing one, with its own calls. extractFunction already resolves the name from the declarator. A destructuring binding, an inline JSX arrow and a non-function value stay as they were. JS family only.
  • torture.tsx gains the shape so kernel-tsjs-parity pins both arms.
  • React-router / expo-router expectations updated so a navigation such a handler makes is the handler's own navigates edge (same shape a useCallback handler already has).

#1718 / fuzzy lexical reachability is already on main — nested handlers become real symbols without becoming fuzzy false positives across files.

Verification (Linux)

  • Fail→pass: pre-fix dist: handleClear missing, handleSelect (useCallback) present. Post-fix: both indexed as Widget::handleClear / Widget::handleSelect.
  • E2E issue repro: codegraph init → 12 nodes; callers handleClear → Widget; query kind:function lists both handlers.
  • CODEGRAPH_KERNEL_EXPECT=1 vitest: nested-declarator-functions, react-router, expo-router, kernel-tsjs-parity, fuzzy-lexical-reach — all passed.

Re-index after upgrading to pick up the new symbols.

danusha2345 and others added 5 commits September 3, 2026 15:30
…#1669)

`const handleClear = () => {…}` inside a component — every React handler
that skips useCallback — was never a symbol: the body walker only named
nested function declarations and hook-bound arrows, so the handler was
absent from callers/impact ("Symbol not found", indistinguishable from
"no callers") and its calls attributed to the component. Bind the arrow
or function expression to its declarator the way module scope already
does, in both the wasm walker and the kernel.

A navigation such a handler makes is now the handler's own edge and a hop
in the Screens `via` chain — the shape a useCallback handler already has —
so the react-router and expo-router expectations follow that convention.
…ound-nested-functions

# Conflicts:
#	CHANGELOG.md
…ound-nested-functions

# Conflicts:
#	CHANGELOG.md
…ound-nested-functions

# Conflicts:
#	CHANGELOG.md
#	src/extraction/tree-sitter.ts
Resolves CHANGELOG conflict with #1674/#1639 truncation reporting (#1772).
Fixes #1669.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Function-valued consts inside a function body are never indexed (React handlers invisible to callers/impact)

1 participant