Repository navigation
Description
Version
codebase-memory-mcp 0.11.0
Platform
macOS (Apple Silicon)
Install channel
GitHub release archive / install.sh / install.ps1
Binary variant
standard
What happened, and what did you expect?
Swift initializers are not extracted as functions. Every init produces no node, and calls made inside one are attributed to the file's module node instead. Calls from different initializers to the same callee collapse into one file-level edge, so trace_path and caller queries lose the initializer entirely.
It affects every initializer form: struct, class, convenience, failable, and initializers declared in extensions. The file parses cleanly (parse_partial_count: 0), so nothing reports the loss. Ordinary methods in the same types are attributed correctly.
The cause is that swift_func_types (internal/cbm/lang_specs.c:573) lists function_declaration, protocol_function_declaration and macro_declaration, but not init_declaration. The grammar's init_declaration also has no name field, so both definition extraction and the enclosing-function QN for calls need a name derived from the owning type.
Kotlin's secondary_constructor has the same shape and is already handled (kotlin_func_types in lang_specs.c:451, the branch in extract_defs.c:5272).
Expected: each initializer becomes a function node (for example Box.init), and its calls come from that node.
Reproduction
Inits.swift:
func helper() -> Int { 1 }
func other() -> Int { 2 }
struct Box {
let value: Int
init() {
value = helper()
}
func read() -> Int {
other()
}
}
final class Holder {
let value: Int
init(seed: Int) {
value = helper() + seed
}
convenience init() {
self.init(seed: other())
}
}
enum Mode {
case on
init?(flag: Bool) {
if helper() > 0 { self = .on } else { return nil }
}
}
extension Box {
init(raw: Int) {
value = other()
}
}codebase-memory-mcp cli --json index_repository '{"repo_path":"<dir>"}'
codebase-memory-mcp cli --json query_graph '{"project":"<project>","query":"MATCH (a)-[:CALLS]->(b) RETURN a.name AS caller, b.name AS callee ORDER BY caller, callee","format":"json"}'Result on 0.11.0 (parse_partial_count: 0, 11 nodes):
["Inits.swift", "helper"]
["Inits.swift", "other"]
["read", "other"]
There are five initializers with five calls between them. None becomes a node, and their calls collapse into two edges from the file. The method read is attributed correctly. Querying for nodes whose name contains init returns only the project node.
Logs
No response
Diagnostics trajectory (memory / performance / leak issues)
No response
Project scale (if relevant)
1 file, 11 nodes, 14 edges
Confirmations
- I searched existing issues and this is not a duplicate.
- My reproduction uses shareable code (a dummy snippet or a public OSS repository), not proprietary code.
Proposed fix. Mirror the Kotlin secondary_constructor handling:
- Add
init_declarationtoswift_func_types. - In
extract_class_methods, name the definition from the owning type. - In
compute_func_qn, resolve the enclosing type (init_declaration→class_body→ the declaring type) so a call's enclosing QN is the initializer's.
Tests in tests/test_extraction.c, failing on the current tree, will assert a function definition and call attribution for the struct, class, convenience, failable and extension forms.
Related: #2377 covers typed-throws initializers failing to parse. That is a grammar issue. This one is extraction and reproduces with plain initializers on the current grammar, so the two fixes are independent.
Prepared with AI assistance; I reviewed and verified the reproduction and results.
Activity
DeusData commentedon Oct 19, 2026
Thank you for covering the different initializer forms and separating extraction from the typed-throws grammar report. The file-level collapse of initializer calls is the key behavior to verify. The proposed ownership naming still needs review.
fix(extraction): keep Swift initializer edges to true targets
DeusData commentedon Oct 25, 2026
Thank you for the detailed Swift initializer examples. The missing initializer nodes and calls attributed to the file still need maintainer follow-up. Sorry for the delay; I’ll follow up soon.
DeusData commentedon Nov 3, 2026
Fixed on main in e0c7a1d (#2395, thanks to @Studnicky): calls inside Swift lifecycle members are now attributed to the member that makes them.