v0.9.38
Graphify-Labs/graphifyv0.9.38Aug 9, 2026by safishamsi
AI Summary
A correctness release that fixes a regression in callback scoping, collects Kotlin property initializer calls, and resolves various Swift and SQL resolution issues.
Key Highlights
- Fixes a callback-scoping regression from 0.9.37 where sibling closures suppressed calls.
- Collects Kotlin calls in property initializers, lazy delegates, and companion objects.
- Resolves Swift receiver-type inference for Environment attributes and factory bindings.
- Stops SQL CTE names from becoming table refs that could bind to unrelated symbols.
Full Release Notes
Correctness release: fixes a callback-scoping regression from 0.9.37, collects Kotlin property-initializer calls, resolves Swift attribute/factory receivers, stops SQL CTE names becoming table refs, and captures nested/module-scope dynamic imports.
- Fix: the 0.9.37 callback-body fix (#2552) no longer lets a local declared in one callback suppress a call in a sibling callback (#2568, thanks @imagineers-tyler). Each callback body's local names are now scoped to that body instead of unioned under the shared declaration, so a real `indirect_call` in one sibling closure is no longer dropped because another sibling declared a same-named local. This can only restore dropped edges, never fabricate.
- Fix: Kotlin calls in a property initializer are now collected (#2565, thanks @kskchaitanya1993). A class property (`val repo = createRepo()`), a `by lazy { ... }` delegate, a companion-object property, and a top-level property initializer now produce `calls` edges attributed to the enclosing class (or file), including fully-qualified calls. A plain literal initializer produces no edge.
- Fix: Swift receiver-type inference now handles `@Environment(Store.self)` properties and factory-initialised bindings (#2561, thanks @fakewaffle). A member call on a receiver typed only through an `@Environment(Type.self)` attribute, or bound to an in-corpus factory whose return type is known (`let x = ServiceFactory.make()`), now resolves. Ambiguous or non-concrete returns (opaque `some P`, arrays, out-of-corpus) stay unresolved rather than guessing.
- Fix: the SQL extractor no longer emits a `reads_from` edge to a CTE name (#2577, thanks @wilyan09007). A `WITH cte AS (...)` name is scoped to its query and is no longer treated as a table, so it no longer mints a bare stub that could bind to an unrelated same-named symbol; an outer real table sharing a subquery-CTE's name still resolves.
- Fix: a dynamic `await import('…')` inside a nested function or at module scope now produces an edge (#2575, thanks @phudayyy), and `dynamic_import` edges are now included in `affected`. Calls inside a nested named function are also collected now. A dynamic import already captured as a deferred `imports_from` is not double-counted.