Skip to content

fix(kotlin): extract secondary constructors and the calls in their bodies - #3025

Open
rajatnagda45 wants to merge 1 commit into
Graphify-Labs:v8from
rajatnagda45:fix/kotlin-secondary-constructor
Open

fix(kotlin): extract secondary constructors and the calls in their bodies#3025
rajatnagda45 wants to merge 1 commit into
Graphify-Labs:v8from
rajatnagda45:fix/kotlin-secondary-constructor

Conversation

@rajatnagda45

Copy link
Copy Markdown
Contributor

Problem

A Kotlin secondary_constructor (constructor(...) { … }) is a callable class member 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.

Before (this input)

class Service {
    var name: String = ""
    constructor(n: String) { name = n; validate() }
    fun validate() { }
}

Only .validate() was emitted — the constructor node and the constructor → validate call were both gone.

Fix

  • A secondary_constructor has no name field, so — exactly like Swift's deinit/subscript — the engine labels it .constructor().
  • Its body is a bare block (no body field), so block is added to Kotlin's body_fallback_child_types. This only fires for the secondary constructor, since function/class declarations expose their body via a field.
  • It's added to function_boundary_types so the body is a proper call scope.

Test

Adds a regression test asserting the .constructor() node exists, hangs off its class via a method edge, 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 shared engine.py change (one name-less-callable case) is safe across languages.

…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.

@graphify-labs graphify-labs Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant