Version: code-review-graph 2.3.2 (Python 3.13, Windows 10)
Summary
On a mixed-language monorepo containing TypeScript, Python, Go, JavaScript, Kotlin, and Swift, CRG extracts CALLS edges for the first four languages but produces zero CALLS edges for Kotlin and Swift. Only structural edges (CONTAINS, IMPORTS_FROM, INHERITS) are emitted for those two languages.
This means get_edges_by_target(), search_edges_by_target_name(kind='CALLS'), get_impact_radius(), and any caller/callee/blast-radius query returns empty for Kotlin or Swift symbols, even when the symbol clearly has callers in the source.
Reproduction
Test repo: a 6,781-file mixed-language monorepo (D:\openclaw, publicly available at github.com/thelord810/openclaw). After code-review-graph build, direct sqlite3 inspection of .code-review-graph/graph.db:
SELECT language, COUNT(*) FROM nodes WHERE kind != 'File' GROUP BY language;
-- typescript: 54682
-- swift: 5763
-- kotlin: 1501
-- javascript: 1443
-- python: 199
-- go: 92
-- Edge kinds restricted to Kotlin files:
SELECT kind, COUNT(*) FROM edges WHERE file_path LIKE '%.kt' GROUP BY kind;
-- CONTAINS: 1389
-- IMPORTS_FROM: 1758
-- INHERITS: 293
-- (no CALLS row)
-- Edge kinds restricted to Swift files:
SELECT kind, COUNT(*) FROM edges WHERE file_path LIKE '%.swift' GROUP BY kind;
-- CONTAINS: 5257
-- IMPORTS_FROM: 1462
-- (no CALLS row, no INHERITS)
Compare to TypeScript (which has 281,273 CALLS edges) or Python (1,582 CALLS edges) — both emit first-class call resolution from the same parser infrastructure.
Specific check against a known class
apps/android/app/src/main/java/ai/openclaw/app/voice/TalkModeManager.kt is a 1,818-line Kotlin class with 50+ methods. CRG correctly extracts:
- The class node (
qualified_name = "...\TalkModeManager.kt::TalkModeManager")
- All 50+ method nodes with correct line ranges
- CONTAINS edges class→methods
But get_edges_by_target(class_qn) returns 1 edge (the File→Class CONTAINS) and get_edges_by_target("TalkModeManager.start") returns 1 CONTAINS edge — no CALLS edges for either.
The same pattern holds for any Kotlin or Swift symbol in the repo. This is not a query issue or qualified-name mismatch — it's that the tree-sitter Kotlin and Swift grammars (or CRG's extractor step over them) simply aren't producing CALLS edges.
Why this matters for consumers
CRG's value proposition on mixed mobile/backend monorepos is severely reduced if Kotlin (Android) and Swift (iOS) code can't participate in caller/callee and blast-radius queries. A change to a backend TS function shows full blast radius; a change to a shared Kotlin utility shows only the file containing the utility.
I built a wrapper (code_graph.py in an internal intel layer) that detects zero-CALLS languages and falls back to an IMPORTS_FROM walk as a degraded approximation, tagging results with metadata['degraded'] = True. That works for v1 but the fix should ideally live upstream in CRG so every consumer gets function-level resolution for all languages.
What I've ruled out
- Not an exclude issue: Kotlin/Swift files ARE being parsed — 1,501 Kotlin nodes and 5,763 Swift nodes show up, they just have no outgoing CALLS edges.
- Not a qualified-name mismatch:
search_edges_by_target_name("start", kind="CALLS") over the whole DB returns TS/Python/Go hits only, never Kotlin.
- Not a test-file filter: the issue shows up for production Kotlin code (
TalkModeManager.kt, not *Test.kt).
- Not specific to the 2.3.2 upgrade: same pattern observed in 2.2.1 on the initial build; upgrading to 2.3.2 did not change the Kotlin/Swift edge kinds.
Suggested fix direction
Looking at CRG's extractor layout (I haven't sent a PR yet, just sketching):
- The TypeScript/Python extractors seem to walk the tree-sitter CST for call expressions (
call_expression in TS, call in Python) and emit CALLS edges.
- The Kotlin grammar node for a method call is
call_expression; Swift's is call_expression too.
- Either the Kotlin/Swift extractors aren't implementing this visitor, or they're emitting edges with a kind other than
CALLS that gets filtered out before insertion.
I'd be happy to test a patch if you can point me at the Kotlin/Swift extractor files.
Related
PR #202 (lngyeen) in 2.3.0 added Swift extension detection and inheritance edges — good step for structural coverage, but CALLS is still absent.
Happy to provide the openclaw graph.db for reproduction if useful (it's ~416 MB, can share via gist link to the commit hash).
Version: code-review-graph 2.3.2 (Python 3.13, Windows 10)
Summary
On a mixed-language monorepo containing TypeScript, Python, Go, JavaScript, Kotlin, and Swift, CRG extracts
CALLSedges for the first four languages but produces zero CALLS edges for Kotlin and Swift. Only structural edges (CONTAINS,IMPORTS_FROM,INHERITS) are emitted for those two languages.This means
get_edges_by_target(),search_edges_by_target_name(kind='CALLS'),get_impact_radius(), and any caller/callee/blast-radius query returns empty for Kotlin or Swift symbols, even when the symbol clearly has callers in the source.Reproduction
Test repo: a 6,781-file mixed-language monorepo (
D:\openclaw, publicly available at github.com/thelord810/openclaw). Aftercode-review-graph build, direct sqlite3 inspection of.code-review-graph/graph.db:Compare to TypeScript (which has 281,273 CALLS edges) or Python (1,582 CALLS edges) — both emit first-class call resolution from the same parser infrastructure.
Specific check against a known class
apps/android/app/src/main/java/ai/openclaw/app/voice/TalkModeManager.ktis a 1,818-line Kotlin class with 50+ methods. CRG correctly extracts:qualified_name = "...\TalkModeManager.kt::TalkModeManager")But
get_edges_by_target(class_qn)returns 1 edge (the File→Class CONTAINS) andget_edges_by_target("TalkModeManager.start")returns 1 CONTAINS edge — no CALLS edges for either.The same pattern holds for any Kotlin or Swift symbol in the repo. This is not a query issue or qualified-name mismatch — it's that the tree-sitter Kotlin and Swift grammars (or CRG's extractor step over them) simply aren't producing CALLS edges.
Why this matters for consumers
CRG's value proposition on mixed mobile/backend monorepos is severely reduced if Kotlin (Android) and Swift (iOS) code can't participate in caller/callee and blast-radius queries. A change to a backend TS function shows full blast radius; a change to a shared Kotlin utility shows only the file containing the utility.
I built a wrapper (
code_graph.pyin an internal intel layer) that detects zero-CALLS languages and falls back to anIMPORTS_FROMwalk as a degraded approximation, tagging results withmetadata['degraded'] = True. That works for v1 but the fix should ideally live upstream in CRG so every consumer gets function-level resolution for all languages.What I've ruled out
search_edges_by_target_name("start", kind="CALLS")over the whole DB returns TS/Python/Go hits only, never Kotlin.TalkModeManager.kt, not*Test.kt).Suggested fix direction
Looking at CRG's extractor layout (I haven't sent a PR yet, just sketching):
call_expressionin TS,callin Python) and emit CALLS edges.call_expression; Swift's iscall_expressiontoo.CALLSthat gets filtered out before insertion.I'd be happy to test a patch if you can point me at the Kotlin/Swift extractor files.
Related
PR #202 (lngyeen) in 2.3.0 added Swift extension detection and inheritance edges — good step for structural coverage, but CALLS is still absent.
Happy to provide the openclaw graph.db for reproduction if useful (it's ~416 MB, can share via gist link to the commit hash).