Skip to content

ADFA-5231: Add pin-scoped live KtFile acquisition - #1744

Open
itsaky-adfa wants to merge 2 commits into
ADFA-5231-document-versionsfrom
ADFA-5231-pin-api
Open

ADFA-5231: Add pin-scoped live KtFile acquisition#1744
itsaky-adfa wants to merge 2 commits into
ADFA-5231-document-versionsfrom
ADFA-5231-pin-api

Conversation

@itsaky-adfa

@itsaky-adfa itsaky-adfa commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Stack 2 of 5 for ADFA-5231. Adds the mechanism only - nothing consumes it yet and the raw accessors stay public, so this layer changes no behaviour. Consumers arrive in the next PR.

The bug this exists to fix

ADFA-4165 established the invariant one live KtFile per open path. ADFA-3322 (#1484) replaced its enforcement with the per-version currentFiles cache and reintroduced the bug: KtSymbolIndex mints a fresh KtFile whenever a caller observes a new document version, while DeclarationProvider.ktFilesForPackage resolves a path to whatever the newest instance is. An analysis that started against an older instance therefore sees every declaration twice - once as its own PSI, once through the provider - and FIR reports the file as conflicting with itself.

What this adds

LiveKtFile, an internal sealed interface whose only implementation is private to KtSymbolIndex, so the only way to obtain one is withLiveKtFile / withLiveKtFileAsync. While a pin is held, both doors into the index - getCurrentVersionedKtFile and the getKtFile the Analysis API service providers use - resolve that one instance. A version bump during a pin is recorded and the refresh is launched when the last scope closes, so freshness is deferred rather than dropped.

The handle deliberately never exposes the KtFile as a value: PSI access and analysis are members taking a lambda, and returning the file directly from a block is rejected at runtime.

Notes for review:

  • The pin's version is stamped from the resolved instance's own version rather than re-read from FileManager, so isStale cannot report fresh for a stale instance. An earlier revision got this wrong and it is worth a look.
  • Pin.refreshOwed is @Volatile because it is written outside the compute section and read inside it; count, mutated only under the bin lock, is deliberately plain.
  • A narrow window between resolving an instance and installing its pin is documented rather than closed - closing it means publishing a pin before its file exists, so joiners would wait on an unresolved entry in the one path every caller depends on.

Testing

LiveKtFilePinTest - identity stability under a concurrent version bump, reentrancy, the deferred refresh, isStale, and the escape guard. Both new pin branches were mutation-tested: disabling either fails a specific test. The suite is fully green at this layer.

@claude claude 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.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.

Tip: disable this comment in your organization's Code Review settings.

@github-actions github-actions Bot deleted a comment from atlassian Bot Aug 25, 2026
@itsaky-adfa
itsaky-adfa requested a review from a team August 25, 2026 16:53
@itsaky-adfa itsaky-adfa self-assigned this Aug 25, 2026
@itsaky-adfa itsaky-adfa changed the title ADFA 5231 pin api ADFA-5231: Add pin-scoped live KtFile acquisition Aug 25, 2026
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