mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-19 23:19:50 +08:00
cf582f4274
The Kotlin property hook consumes the whole `property_declaration` subtree,
so the dispatcher only scanned it for function-as-value candidates and never
walked it for calls. Every call inside a property initializer was therefore
dropped from the graph entirely — not misattributed, gone:
private val fieldLambda: () -> Unit = { target() } // no caller
private val samField = Runnable { target() } // no caller
private val plain = compute() // no caller
private val delegated by lazy { compute() } // no caller
That is exactly how Android/MSDK callbacks are declared, so anything reached
only through such a callback looked like it had no callers and its blast
radius came back far too small.
Fix: after minting the property node, walk its RHS — the named child after
the `=` token plus a `property_delegate` — through visitFunctionBody with the
property pushed on the scope stack. This is Go's #693/#744 fix ported;
tree-sitter-kotlin exposes no fields at all, hence the `=` anchor instead of
Go's `child_by_field_name("value")`.
Not touched, by design: the `scope == "local"` early return, the
hook-declined destructuring branch, and the declaration's own children
(modifiers, `val`/`var`, name+type, extension receiver, `getter`/`setter`).
Both arms move together — the Rust kernel and the TS extractor — so
kernel-kotlin-parity stays byte-identical; the torture fixture gains the
lambda/SAM/anonymous-object initializer shapes.
Measured on a 113-file Android/Kotlin app: strictly additive, 0 lost nodes /
edges / refs, +7 nodes (anonymous-object overrides that were invisible),
+109 edges (+47 calls, +35 instantiates, +20 references), and the real case
that motivated this — a `CameraFrameListener` field — now shows up as a
caller of the method it invokes.