fix(kotlin): extract secondary constructors and the calls in their bodies - #3025
fix(kotlin): extract secondary constructors and the calls in their bodies#3025rajatnagda45 wants to merge 1 commit into
Conversation
…dies
secondary_constructor is a callable class member (`constructor(...) { … }`)
with a body, but it was missing from the Kotlin function_types — so every
secondary constructor was dropped, and with it all the calls made from its
body (field initialization, validation, this()/super() delegation). That
silently erased a real slice of the construction-time call graph.
Like Swift's deinit/subscript, a secondary_constructor has no name field, so
the engine labels it `.constructor()`. Its body is a bare `block` (no `body`
field), so add `block` to Kotlin's body_fallback_child_types — this only
fires for the secondary constructor, since function/class declarations expose
their body via a field. Also add it to function_boundary_types so its body is
a proper call scope. Adds a regression test.
There was a problem hiding this comment.
Graphify reviewed this change.
Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).
Formal verification. No changes could be formally verified in this run.
Graphify review — findings
Adds Kotlin secondary constructors to the extractor by including secondary_constructor in the config's function types and boundaries, labeling the name-less node .constructor() in _extract_generic, and adding block to the body fallback so the constructor body is walked. This recovers the previously dropped constructor method node along with every call made from its body (field init, validation, delegation).
No blocking issues surfaced.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 2146 functions depend on the 935 functions this change touches.
Health — this change adds coupling hotspots:
- new:
extract()— 490 callers, 42 callees - new:
_rebuild_code()— 98 callers, 50 callees - new:
_extract_generic()— 18 callers, 24 callees - new:
extract_xaml()— 19 callers, 17 callees - new:
dispatch_command()— 2 callers, 122 callees - new:
extract_objc()— 27 callers, 9 callees - new:
extract_js()— 80 callers, 3 callees - new:
_get_extractor()— 26 callers, 6 callees - …and 32 more — each is listed as a finding
Verification — 2146 functions in the blast radius were not formally verified this run (proofs are advisory here).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 1995 function(s) in the blast radius were not formally verified this run
Formal verification
Could not verify: Could not verify \_extract\_generic.
The verifier did not have enough to check \_extract\_generic, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: parameter `path` is annotated `Path` — outside the synthesizable primitive/collection set
· 40 more finding(s) on lines outside this diff (see the check run).
Problem
A Kotlin
secondary_constructor(constructor(...) { … }) is a callable class member with a body, but it was missing from the Kotlinfunction_types. So every secondary constructor was dropped — and with it all the calls made from its body: field initialization, validation,this()/super()delegation. That silently erased a real slice of the construction-time call graph.Before (this input)
Only
.validate()was emitted — the constructor node and theconstructor → validatecall were both gone.Fix
secondary_constructorhas nonamefield, so — exactly like Swift'sdeinit/subscript— the engine labels it.constructor().block(nobodyfield), soblockis added to Kotlin'sbody_fallback_child_types. This only fires for the secondary constructor, since function/class declarations expose their body via a field.function_boundary_typesso the body is a proper call scope.Test
Adds a regression test asserting the
.constructor()node exists, hangs off its class via amethodedge, and that a call made in the constructor body resolves. Fails before, passes after.All 12 existing Kotlin language tests pass, and a broad engine-touching sweep (648 tests across
test_languages,test_cross_language_call_resolution,test_language_resolvers,test_extract,test_analyze) is green — the sharedengine.pychange (one name-less-callable case) is safe across languages.