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

@claudeclaudeBot 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-actionsgithub-actionsBot deleted a comment from atlassianBotAug 25, 2026
@itsaky-adfa
itsaky-adfa requested a review from a teamAugust 25, 2026 16:53
@itsaky-adfaitsaky-adfa self-assigned this Aug 25, 2026
@itsaky-adfaitsaky-adfa changed the title ADFA 5231 pin apiADFA-5231: Add pin-scoped live KtFile acquisitionAug 25, 2026
@itsaky-adfa
itsaky-adfaforce-pushed the ADFA-5231-pin-api branch 2 times, most recently from 399e25b to 3a8d1adCompareAugust 27, 2026 09:06
Sign up for freeto 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

@itsaky-adfa@dara-abijo-adfa