Skip to content

fix: build the Kotlin import graph from packages, not file paths - #912

Open
zlum wants to merge 3 commits into
peteromallet:mainfrom
zlum:fix/kotlin-import-graph
Open

zlum wants to merge 3 commits into
peteromallet:mainfrom
zlum:fix/kotlin-import-graph

Conversation

@zlum

@zlum zlum commented Oct 30, 2026

Copy link
Copy Markdown

Problem

On an Android project every Kotlin file had zero importers, so all of them were reported as orphaned and as untested critical modules (112/112 files on the project I scanned).

resolve_kotlin_import maps import a.b.C to a/b/C.kt under a fixed list of roots that misses Android's app/src/main/java. Even with the right root, it can't see most edges: Kotlin imports name declarations rather than files, one file may declare many top-level names, and code in the same package uses them with no import at all (tests usually live in the same package as the code they test).

Fix

  • New dep_graph_builder option on generic_lang (a whole-graph builder taking precedence over the per-import resolver).
  • languages/kotlin/deps.py: indexes each file's package and non-private top-level declarations, then links explicit imports (nested names, aliases), wildcard imports and same-package identifier uses. Comments and strings are ignored, but string-template expressions count.
  • Classes registered in AndroidManifest.xml (activity, application, service, receiver, provider; relative names resolved via the manifest package or Gradle namespace) get the __entrypoint__ importer, as C# does.
  • Kotlin zone rules: *.gradle.kts → config, /androidTest/ → test, so build scripts aren't asked for unit tests.

Result on the project: 0 false orphans, test coverage maps tests to their same-package modules, and the one remaining cycle reported is a real one.

Tested: new tests pass; the full suite on Windows has the same 32 failures as main (path/CRLF issues unrelated to this change). Verified against a real Android app (Kotlin, 113 production files).

🤖 Generated with Claude Code

zlum and others added 3 commits October 30, 2026 14:39
The Kotlin resolver mapped `import a.b.C` to `a/b/C.kt` under a fixed
list of source roots that misses Android's `app/src/main/java`, so on an
Android project every file had zero importers: all of them were reported
as orphaned and as untested critical modules.

Kotlin imports name declarations, not files, and same-package code needs
no import at all, so a per-import path resolver cannot see most edges.
Add a `dep_graph_builder` option to generic languages and give Kotlin a
builder that indexes each file's package and top-level declarations, then
links explicit imports (nested names, aliases), wildcard imports and
same-package uses. Classes registered in AndroidManifest.xml get the
`__entrypoint__` importer (as C# does), and *.gradle.kts scripts are
entry points.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A private top-level function or class is visible only in its own file,
so a same-named local elsewhere in the package (a `val lines` next to a
private `fun Layout.lines()`) created a false edge and a false cycle.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
build.gradle.kts and settings.gradle.kts were production files, so the
coverage detector asked for unit tests of the build scripts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
github-actions Bot added a commit to citizenadam/desloppify that referenced this pull request Oct 30, 2026

This branch has not been deployed

No deployments
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