Skip to content

fix: resolve JVM imports in Gradle/Maven module source roots - #739

Open
ariancovac wants to merge 1 commit into
peteromallet:mainfrom
ariancovac:fix/kotlin-multi-module-import-resolution
Open

ariancovac wants to merge 1 commit into
peteromallet:mainfrom
ariancovac:fix/kotlin-multi-module-import-resolution

Conversation

@ariancovac

Copy link
Copy Markdown

Problem

Multi-module Gradle/Maven projects keep each module's sources under a module directory (android/src/main/java, feature/x/src/main/kotlin). The Java and Kotlin import resolvers only tried scan-root-relative paths (src/main/java, src, app/src/main/java, .), so in any multi-module project every cross-file import failed to resolve:

  • the import graph came back with zero edges,
  • importer_count == 0 for essentially the whole codebase,
  • graph-based detectors (orphaned, coupling, cycles, single_use, test coverage) flagged the entire project — e.g. the orphaned detector reported 118 "orphaned" files including MainActivity, MediaKitApplication, and settings.gradle.kts.

Verified against a real 3-module Android project (modules android/, download-private/, detekt-rules/): before the fix, 118/120 source files were flagged orphaned; after the fix, 0.

Fix

  • Add discover_jvm_source_roots(scan_path) to resolver_cache.py: an os.walk (pruning build/, node_modules/, dot-dirs, depth-capped) that finds <module>/src/main/java|kotlin roots, memoized per scan root and cleared by reset_import_cache().
  • resolve_java_import / resolve_kotlin_import now try the discovered module roots first, then the historical fallbacks (behavior for single-module/flat layouts is unchanged).
  • New test test_jvm_resolvers_find_imports_in_gradle_modules covers Kotlin + Java module resolution, ensures build-output copies never win over real sources, and exercises the cache reset.

Full suite: 601 passed in tests/lang (the 2 failures in test_treesitter_imports_direct.pytest_backend_import_resolvers_cover_language_specific_paths, test_script_import_resolvers_cover_cached_paths_and_extensions — also fail on clean main on Windows; pre-existing, unrelated).

Multi-module Gradle/Maven projects keep each module's sources under
<module>/src/main/java|kotlin (e.g. android/src/main/java). The Java and
Kotlin import resolvers only tried scan-root-relative paths, so in
multi-module projects every cross-file import failed to resolve, the
import graph came back empty, and graph-based detectors (orphaned,
coupling, cycles, single_use) flagged essentially the whole codebase.

Discover src/main/java and src/main/kotlin roots under the scan path
(pruning build output), memoized per scan root, and try them before the
historical fallbacks.
@awdemos

awdemos commented Sep 12, 2026

Copy link
Copy Markdown

Reviewed against current main — the fix is real and well-built (exclusion-aware discover_jvm_source_roots walk, depth-capped, lru-cached, cleared in reset_import_cache), but one thing needs correcting before this is mergeable:

The existing test failure is introduced by this PR, not pre-existing. test_backend_import_resolvers_cover_language_specific_paths fails on this branch (1 failed, 9 passed) and passes on clean main on Linux. The body claims it "also fails on clean main on Windows" — I could not reproduce that. Mechanism: _jvm_candidate_roots drops the historical src/main/kotlin fallback that resolve_kotlin_import had, so when an earlier resolve_java_import call memoizes discovered roots before the test creates the kotlin dir, the lookup returns None.

Restoring os.path.join(scan_path, "src", "main", "kotlin") to the fallback list makes all 10 tests pass.

Follow-up (non-blocking): reset_import_cache() is only called from tests, so in a long-lived process the discovery cache can go stale across scans — worth wiring into the scan lifecycle.

Also note src/jvmMain/kotlin-style KMP main source roots are still not discovered (this covers Gradle/Maven src/main/java|kotlin); pairs naturally with #677 which handles the KMP test side.

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.

2 participants