Skip to content

fix: inconsistent search scope in source modules and project structure provider#1361

Open
itsaky-adfa wants to merge 2 commits into
stagefrom
fix/ADFA-4059
Open

fix: inconsistent search scope in source modules and project structure provider#1361
itsaky-adfa wants to merge 2 commits into
stagefrom
fix/ADFA-4059

Conversation

@itsaky-adfa
Copy link
Copy Markdown
Contributor

@itsaky-adfa itsaky-adfa commented Jun 2, 2026

See ADFA-4059 for more details.

…e provider

Signed-off-by: Akash Yadav <akashyadav@appdevforall.org>

# Conflicts:
#	app/src/main/java/com/itsaky/androidide/app/IDEApplication.kt
@itsaky-adfa itsaky-adfa requested a review from a team June 2, 2026 18:15
@itsaky-adfa itsaky-adfa self-assigned this Jun 2, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 2, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6ed5ca69-b51d-41fc-8500-b148bfdb95a6

📥 Commits

Reviewing files that changed from the base of the PR and between b6f9a7b and 8d1fea7.

📒 Files selected for processing (1)
  • subprojects/kotlin-analysis-api/build.gradle.kts

📝 Walkthrough

Release Notes

  • Fix: remove hardcoded local kotlin-android path in build configuration (updated kt-android tag and checksum)
  • Core search/scope fixes:
    • Introduced AbstractSourceModule to centralize source-file discovery and compute base content scope using path-based membership (avoids stale PSI scopes)
    • AbstractKtModule now delegates base scope computation to a protected hook (computeBaseContentScope)
  • Compilation environment refactor:
    • Extracted shared IntelliJ/Kotlin setup into AbstractCompilationEnvironment used by production CompilationEnvironment and test fixtures
    • CompilationEnvironment now extends AbstractCompilationEnvironment and delegates initialization hooks
  • Indexing and symbol/index API changes:
    • FilteredIndex: made source activation/deactivation and related checks overridable (open) and switched internal checks to use isActive(...)
    • InMemoryIndex: expanded and normalized prefix-match handling (supports prefix-searchable vs non-searchable fields; empty prefix treated as "field present" for prefix buckets)
    • KtFileMetadataIndex now depends on Index (constructor accepts generic Index) and renamed factory from create() → sqliteBacked()
    • JvmSymbolIndex declared open to allow subclassing
  • Source/file indexing behavior:
    • SourceFileIndexer now skips indexing of local (inside-function) functions and properties
  • Service registration / Analysis API wiring:
    • Added AnalysisApiServiceProvider, AnalysisApiServiceProviders, and LspAnalysisApiServiceRegistrar to provide modular service registration
    • Removed legacy LspServiceRegistrar in favor of the new provider/registrar pattern
    • Refactored several providers/registrars (AbstractDeclarationProvider, DeclarationProvider changes)
  • Tests & test infra:
    • Added comprehensive Kotlin LSP test fixtures and rules: KtLspTest, KtLspTestEnvironment, KtLspTestRule, TestKtSourceModule
    • Added tests: SourceFileIndexerTest (local-symbol filtering), ContentScopeStalenessTest (stale-scope regression), KtLspTestEnvironmentTest (fixture verification)
  • Miscellaneous:
    • AnalysisPermissionOptions simplified to constructor-based properties
    • ProjectStructureProvider logging (SLF4J) removed
    • IDEApplication: removed setupIdeaStandaloneExecution import and call and no longer sets java.awt.headless = true at startup
    • Testing tweak: ILanguageServerRegistry.getDefault() → ILanguageServerRegistry.default

Risks and best-practice concerns

  • High risk: large architectural refactor of compilation environment and service-registration wiring; requires thorough integration testing (production and test paths) to ensure all services and lifecycle hooks are registered and disposed correctly.
  • High risk: removal of IDE standalone/headless initialization from IDEApplication; verify no regressions for headless environments or environments that depended on that setup.
  • Medium risk: path-based scope membership (AbstractSourceModule) can have edge cases with symlinks, mounts, or VFS refresh semantics—verify across platforms and common workspace setups.
  • Medium risk: build-change to kt-android artifact tag/checksum and the removal of the hardcoded local path may affect reproducible builds; ensure CI artifacts and mirrors are updated.
  • Medium risk: making FilteredIndex methods open and JvmSymbolIndex subclassable expands the public surface and could enable incompatible overrides—document expected override semantics.
  • Medium risk: KtFileMetadataIndex now depends on a generic Index abstraction; confirm SQLite-backed behaviors (transactions, durability) remain intact when used via the generic interface.
  • Best-practice: test fixture teardown contains a commented TODO around env.close(); ensure test resources are reliably closed to avoid leaks in CI.
  • Best-practice: verify that the new AnalysisApiServiceProviders fully replicate prior service registrations (including plugin-relative wiring) to prevent subtle runtime differences.

Walkthrough

This PR extracts a reusable AbstractCompilationEnvironment, introduces provider-based analysis service registration, refactors source-module scope discovery, improves index overridability and prefix matching, skips local declarations during source indexing, and adds JVM test fixtures and regression tests.

Changes

Kotlin Compilation Environment Refactoring

Layer / File(s) Summary
Abstract compilation environment and initialization
lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/AbstractCompilationEnvironment.kt, lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/CompilationEnvironment.kt
AbstractCompilationEnvironment centralizes IntelliJ/Kotlin Analysis API setup, compiler configuration, and lifecycle; CompilationEnvironment now extends it, adds coroutine-scoped initialization, diagnostics publishing, and FIR invalidation publishing.
Service registration abstraction and providers
lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/registrar/AnalysisApiServiceProvider.kt, lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/registrar/AnalysisApiServiceProviders.kt, lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/registrar/LspAnalysisApiServiceRegistrar.kt
Adds AnalysisApiServiceProvider types and builder, a provider registry (AnalysisApiServiceProviders), and LspAnalysisApiServiceRegistrar that applies provider registrations to mock application/project component managers (replacing removed monolithic registrar).
Compiler configuration and invalidation
lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/KotlinLanguageServer.kt
Switches metadata index construction to KtFileMetadataIndex.sqliteBacked(...) and integrates FIR session invalidation publishing in file/module modification flows.

Module System and Source File Discovery

Layer / File(s) Summary
Abstract module base and scope computation
lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/modules/AbstractKtModule.kt, lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/modules/AbstractSourceModule.kt
Adds computeBaseContentScope() hook and AbstractSourceModule which implements source-file discovery (walk content roots, filter .kt/.java) and a path-based GlobalSearchScope to avoid stale-VFS issues.
KtSourceModule refactoring and declaration providers
lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/modules/KtSourceModule.kt, lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/services/DeclarationsProvider.kt
KtSourceModule now inherits AbstractSourceModule (removing its own file-walk); DeclarationProvider now extends AbstractDeclarationProvider which centralizes project and defines ktFilesForPackage hook.

Index System Improvements

Layer / File(s) Summary
FilteredIndex overridability
lsp/indexing/src/main/kotlin/org/appdevforall/codeonthego/indexing/FilteredIndex.kt
Makes active-source management methods open for subclasses and refactors query/get/contains to consistently consult isActive(sourceId).
InMemoryIndex prefix-match enhancement
lsp/indexing/src/main/kotlin/org/appdevforall/codeonthego/indexing/InMemoryIndex.kt
resolveMatchingKeys now supports bucketed prefix-searchable fields (case-insensitive) and a case-sensitive fallback for non-prefix fields; empty prefix on bucketed fields returns bucket contents.
JvmSymbolIndex and KtFileMetadataIndex abstractions
lsp/jvm-symbol-index/src/main/kotlin/org/appdevforall/codeonthego/indexing/jvm/JvmSymbolIndex.kt, lsp/jvm-symbol-index/src/main/kotlin/org/appdevforall/codeonthego/indexing/jvm/KtFileMetadataIndex.kt
JvmSymbolIndex is now open; KtFileMetadataIndex depends on Index<KtFileMetadata> rather than a concrete SQLite type and exposes sqliteBacked factory.
Source file indexer local declaration skip
lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/index/SourceFileIndexer.kt
analyzeFunction and analyzeProperty early-return for local declarations (dcl.isLocal), preventing indexing of locals.

Test Infrastructure and Fixtures

Layer / File(s) Summary
Test base class and JUnit rule
lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/fixtures/KtLspTest.kt, lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/fixtures/KtLspTestRule.kt
Adds KtLspTest Robolectric-backed test base with helpers and KtLspTestRule to provision temp source roots and test environment lifecycle.
Test environment fixture and module implementation
lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/fixtures/KtLspTestEnvironment.kt, lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/fixtures/TestKtSourceModule.kt
KtLspTestEnvironment extends the new abstract compilation environment to create SDK/stdlib/source/library modules, wire in-memory symbol indexes, and provide createSourceFile + analyze helpers; TestKtSourceModule supplies test module metadata.
Test cases and regression tests
lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/compiler/index/SourceFileIndexerTest.kt, lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/fixtures/KtLspTestEnvironmentTest.kt, lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/compiler/modules/ContentScopeStalenessTest.kt
Adds tests verifying local-declaration skipping in the index, fixture correctness (source creation and cross-file resolution), and content-scope staleness regression coverage.

Supporting and Cleanup Changes

Layer / File(s) Summary
Application setup and service cleanup
app/src/main/java/com/itsaky/androidide/app/IDEApplication.kt, lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/services/AnalysisPermissionOptions.kt, lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/services/ProjectStructureProvider.kt
Removes the setupIdeaStandaloneExecution import/call and the java.awt.headless property set from application startup; refactors AnalysisPermissionOptions to constructor-based properties and removes SLF4J logger from ProjectStructureProvider.
Dependency and API updates
subprojects/kotlin-analysis-api/build.gradle.kts, testing/lsp/src/main/java/com/itsaky/androidide/lsp/api/LSPTest.kt, shared/src/main/java/com/itsaky/androidide/utils/Either.kt
Updates an external Kotlin-Android artifact tag and checksum, switches a test accessor to ILanguageServerRegistry.default, and includes a minor EOF brace edit.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • jatezzz
  • dara-abijo-adfa

Poem

🐰 I hopped through code, refactored with care,
Abstracted the env so tests breathe fresh air,
Services now register from providers bright,
Scopes find files by path, indexes skip the slight,
Tests hum, builds pass — carrot cake to share!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: inconsistent search scope in source modules and project structure provider' directly reflects the main changes in the PR: refactoring search scope handling in AbstractSourceModule/KtSourceModule and removing logging from ProjectStructureProvider.
Description check ✅ Passed The description provides a reference to issue ADFA-4059 with a working link, which is related to the changeset. While minimal, it meaningfully connects the PR to tracked work.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/ADFA-4059

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/fixtures/KtLspTestRule.kt (1)

30-33: 💤 Low value

The env.project.write { } block is currently a no-op.

With env.close() commented out, the write block does nothing and env is never disposed, leaving its resources held for the duration of the suite. This is acknowledged via the TODO, but worth resolving so the environment is torn down between tests.

Want me to open an issue to track teardown of env (investigating why env.close() fails under test), or draft a working disposal sequence?

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/fixtures/KtLspTestRule.kt`
around lines 30 - 33, The env.project.write { } block is a no-op because
env.close() is commented out, so ensure the test environment is reliably torn
down by calling env.close() from the rule's teardown rather than leaving it
inside the write block: move the disposal into a proper tearDown/after method in
KtLspTestRule, call env.close() (or Disposer.dispose(env) if close() is
unstable) inside a try/catch to swallow/log any exceptions, and null out the env
reference after successful disposal so resources are released between tests;
reference env, env.close(), env.project.write { }, and the KtLspTestRule
teardown method when applying the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/modules/AbstractSourceModule.kt`:
- Around line 10-28: The file uses kotlin.io.path.walk which is marked
experimental; add an opt-in for ExperimentalPathApi at the top of the file
(file-level) so the compiler allows use of kotlin.io.path.walk (or alternatively
enable -Xopt-in=kotlin.io.path.ExperimentalPathApi for the module); update
AbstractSourceModule (where computeFiles calls walk) to have
`@OptIn`(kotlin.io.path.ExperimentalPathApi::class) applied file-wide to suppress
the experimental API error.

In
`@lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/fixtures/KtLspTestRule.kt`:
- Around line 28-35: The TemporaryFolder created as tempDir is manually created
(tempDir.create()) and not registered as a JUnit rule, so its cleanup never
runs; update the teardown in the finally block of KtLspTestRule to explicitly
delete the tempDir (call tempDir.delete()) before or after env.project.write/
env.close() to ensure the temp src folder and written sources are removed;
reference the tempDir TemporaryFolder instance and the env teardown block (the
finally that currently checks ::env.isInitialized and calls env.project.write)
and add the explicit cleanup call there so temporary files are removed even when
tests fail.

In `@subprojects/kotlin-analysis-api/build.gradle.kts`:
- Around line 12-31: Replace the local absolute-file dependency in the
dependencies { api(files(...)) } block with the original externalAssets {
jarDependency("kt-android") { ... } } wiring: restore the externalAssets block
that uses AssetSource.External(url = uri(...), sha256Checksum = "..."), re-add
the AssetSource import if removed, and remove the hardcoded api(files(...))
entry so the build fetches the shared kt-android JAR via the external asset
mechanism with integrity verification.

---

Nitpick comments:
In
`@lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/fixtures/KtLspTestRule.kt`:
- Around line 30-33: The env.project.write { } block is a no-op because
env.close() is commented out, so ensure the test environment is reliably torn
down by calling env.close() from the rule's teardown rather than leaving it
inside the write block: move the disposal into a proper tearDown/after method in
KtLspTestRule, call env.close() (or Disposer.dispose(env) if close() is
unstable) inside a try/catch to swallow/log any exceptions, and null out the env
reference after successful disposal so resources are released between tests;
reference env, env.close(), env.project.write { }, and the KtLspTestRule
teardown method when applying the change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1fd0c255-3161-4eb6-b157-b71e6449a3ad

📥 Commits

Reviewing files that changed from the base of the PR and between 1793332 and b6f9a7b.

📒 Files selected for processing (29)
  • app/src/main/java/com/itsaky/androidide/app/IDEApplication.kt
  • lsp/indexing/src/main/kotlin/org/appdevforall/codeonthego/indexing/FilteredIndex.kt
  • lsp/indexing/src/main/kotlin/org/appdevforall/codeonthego/indexing/InMemoryIndex.kt
  • lsp/jvm-symbol-index/src/main/kotlin/org/appdevforall/codeonthego/indexing/jvm/JvmSymbolIndex.kt
  • lsp/jvm-symbol-index/src/main/kotlin/org/appdevforall/codeonthego/indexing/jvm/KtFileMetadataIndex.kt
  • lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/KotlinLanguageServer.kt
  • lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/AbstractCompilationEnvironment.kt
  • lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/CompilationEnvironment.kt
  • lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/index/SourceFileIndexer.kt
  • lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/modules/AbstractKtModule.kt
  • lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/modules/AbstractSourceModule.kt
  • lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/modules/KtSourceModule.kt
  • lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/registrar/AnalysisApiServiceProvider.kt
  • lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/registrar/AnalysisApiServiceProviders.kt
  • lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/registrar/LspAnalysisApiServiceRegistrar.kt
  • lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/registrar/LspServiceRegistrar.kt
  • lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/services/AnalysisPermissionOptions.kt
  • lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/services/DeclarationsProvider.kt
  • lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/services/ProjectStructureProvider.kt
  • lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/compiler/index/SourceFileIndexerTest.kt
  • lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/compiler/modules/ContentScopeStalenessTest.kt
  • lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/fixtures/KtLspTest.kt
  • lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/fixtures/KtLspTestEnvironment.kt
  • lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/fixtures/KtLspTestEnvironmentTest.kt
  • lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/fixtures/KtLspTestRule.kt
  • lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/fixtures/TestKtSourceModule.kt
  • shared/src/main/java/com/itsaky/androidide/utils/Either.kt
  • subprojects/kotlin-analysis-api/build.gradle.kts
  • testing/lsp/src/main/java/com/itsaky/androidide/lsp/api/LSPTest.kt
💤 Files with no reviewable changes (2)
  • lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/registrar/LspServiceRegistrar.kt
  • app/src/main/java/com/itsaky/androidide/app/IDEApplication.kt

Comment thread subprojects/kotlin-analysis-api/build.gradle.kts Outdated
@itsaky-adfa itsaky-adfa marked this pull request as draft June 2, 2026 18:28
Signed-off-by: Akash Yadav <akashyadav@appdevforall.org>
@itsaky-adfa itsaky-adfa marked this pull request as ready for review June 2, 2026 18:48
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