* fix(typescript): fix HOC pattern false positives and add export default HOC support
Fixes two related issues from #1876:
1. False positives: `const x = arr.map(a => ...)` was incorrectly classified
as a Function node. Split HOC patterns into identifier vs member_expression
variants and apply a #not-any-of? blocklist for 36 array methods
(map, filter, reduce, forEach, etc.) across all four query files.
Runtime safety-net in tsExtractFunctionName uses a module-level ARRAY_METHODS
constant (avoids per-call Set re-allocation).
2. Missing support: `export default defineEventHandler(async (e) => { ... })`
and similar HOC-wrapped default exports were invisible. Added 4
export_statement patterns (TS + JS, legacy + registry-primary) and extended
tsExtractFunctionName to derive the function name from the callee identifier.
Now correctly distinguishes:
- `const data = arr.map(account => ({...}))` → Const only (was Function+Const)
- `const Button = forwardRef(...)` → Function:Button (unchanged)
- `const Card = React.memo(...)` → Function:memo (unchanged)
- `export default defineEventHandler(...)` → Function:defineEventHandler (new)
Tests: add 2 fixture files and 4 test cases to typescript-hoc-wrapped suite
covering the export default HOC positive case and array method exclusion
negative case.
Closes#1876
Co-authored-by: Claude <noreply@anthropic.com>
AI-model: claude-sonnet-4-6
* fix(ingestion): tighten HOC callback attribution
Share the TypeScript and JavaScript HOC blocklists across query and runtime paths, suppress stale array-method and built-in export-default wrappers, and derive export-default HOC names from the file instead of the wrapper helper.
Also update the pinned unit and integration tests so CI reflects the new callback suppression contract.
Co-authored-by: Claude <noreply@anthropic.com>
AI-model: claude-sonnet-4-6
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
* fix(ingestion): stop emitting phantom Function defs for array-method callbacks
The HOC-wrapped-arrow scope-query pattern (`const X = HOC(args => ...)`),
added for React idioms such as forwardRef/memo/useCallback, also matched
array higher-order-method callbacks like `const x = arr.map(a => ...)`.
Those produced a spurious `@declaration.function` named after the
binding, on top of its value def, so calls inside the callback attributed
to a phantom `Function:x` instead of the enclosing scope.
- Add a shared `isArrayMethodCallbackArrow` detector
(`ARRAY_CALLBACK_METHODS` blocklist) and suppress the
`@declaration.function` emit-side in both the JS and TS scope-captures
emitters, leaving the value binding as the sole def.
- Add `selectNodeBearingDef` in scope-extractor: the tested
collapse-rule contract (function-like > value > first) the deferred
node-creation migration will consume to keep one graph node per
binding.
This corrects the registry-primary scope model and CALLS-edge
attribution (calls inside array-method callbacks now source from the
enclosing File scope). The duplicate graph *node* itself is still
created by the legacy parse-worker path and is removed by the follow-up
node-creation migration.
Refs #1876
Co-authored-by: Cursor <cursoragent@cursor.com>
* test(ingestion): strengthen array-callback coverage; document receiver-blind suppression
Follow-ups from the production-readiness review of PR #1906:
- array-callback.ts: document that isArrayMethodCallbackArrow is
receiver-blind — an in-set method name on a NON-array receiver
(Map/Set.forEach, RxJS observable.map, query-builder .sort, lodash
chain .filter) is also suppressed. Accepted limitation, not a bug:
the binding holds the call's result value, not a callable.
- captures unit tests (JS + TS): add a non-array-receiver
characterization case, and extend the it.each lists to cover
findLast, findLastIndex, reduceRight — the full 13-entry
ARRAY_CALLBACK_METHODS set is now exercised in both languages.
- js-array-method-callback-attribution integration test: tighten the
File-sourced CALLS assertions from toBeGreaterThan(0) to
toHaveLength(1) (now also catches over-attribution).
- scope-extractor.ts: note that the dead selectNodeBearingDef export is
intentional and tracked by #1876 (deferred node-creation migration).
Comment-and-test only; no production behavior change. Verified locally:
tsc clean, prettier/eslint clean, captures unit 106 passed,
scope-extractor 31 passed, integration 3 passed.
Refs #1876
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>