diff --git a/docs/analysis/low-level-api-fir/low-level-api-fir.md b/docs/analysis/low-level-api-fir/low-level-api-fir.md index fd1bcd34b6e..3876be59b6d 100644 --- a/docs/analysis/low-level-api-fir/low-level-api-fir.md +++ b/docs/analysis/low-level-api-fir/low-level-api-fir.md @@ -1,71 +1,66 @@ -# Low Level API +# Low-Level API FIR -Low-level API (LL API for short) is an interlayer between Analysis API FIR Implementation and FIR compiler. Low-level API is responsible for: - -* Finding corresponding `FirElement` by `KtElement` -* Lazy resolving of `FirDeclaration` -* Collecting diagnostics for `FirDeclaration` -* Incremental code analysis -* Implementing FIR providers using IntelliJ indexes +Low-level API FIR (LL API or LL FIR for short) is an interlayer between Analysis API FIR Implementation and FIR compiler. +Low-level API FIR is responsible but not limited for: +- Finding corresponding [FirElement](../../../compiler/fir/tree/gen/org/jetbrains/kotlin/fir/FirElement.kt) by `KtElement` +- Lazy resolution of declarations ([FirElementWithResolveState](../../../compiler/fir/tree/gen/org/jetbrains/kotlin/fir/FirElementWithResolveState.kt)) +- Collecting diagnostics for [FirDeclaration](../../../compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirDeclaration.kt) +- Incremental code analysis +- Implementing FIR providers using the Analysis API implementor's declaration/package/etc. providers (e.g., IntelliJ indexes in the IDE) You can read about how FIR compiler works [here](../../fir/fir-basics.md). -The entry point for LL API is `FirModuleResolveState`.` FirModuleResolveState` is a view of project modules visible from the current module. -The lifetime of -`FirModuleResolveState` is limited by Kotlin Out of Block Modification. +The entry point for LL API is [LLFirResolveSession](../../../analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LLFirResolveSession.kt). +`LLFirResolveSession` represents a project view from a use-site [KtModule](../../../analysis/project-structure/src/org/jetbrains/kotlin/analysis/project/structure/KtModule.kt). +The lifetime of `LLFirResolveSession` is limited by modification events. -## Mapping KtElement to FirElement (KT -> FIR) & Incremental Analysis +[LowLevelFirApiFacade](../../../analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/LowLevelFirApiFacade.kt) +file contains a useful API surface to interact with Low Level API FIR from Analysis API FIR. -To implement some stuff in Analysis API, we need to get resolved `FirElement` by the given `KtElement`. Also, this functionality is -considered to be used not very often (mostly, for the files opened in the editor) as it resolves declarations to the `BODY_RESOLVE` and -collects `KT -> FIR` mappings for it. +## Documentation -Finding `KT -> FIR` mappings works like the following: - -* For every `KtFile` we need mapping for, we have `FileStructure` which contains a tree like-structure of `FileStructureElement` -* `FileStructureElement` can be one of the following: - * `ReanalyzableStructureElement` represents a non-local declaration that can be incrementally reanalyzed after non-out of block change - inside it. - * `NonReanalyzableDeclarationStructureElement` represents non-local declaration which can not be incrementally reanalyzed - * `RootFileStructureElement` represents file except all declarations inside -* `FileStructureElement` form a nested tree-like structure -* Then we want to get `KT -> FIR` mapping we find containing `FileStructureElement`. If is not up-to-date we rebuild it and then take from - it. - -The following declarations can be reanalyzed (in other words, can be represented as ReanalyzableStructureElement): - -* Functions with explicit return type -* Properties with explicit type -* Secondary constructors -* Getters/setters of the property with explicit type - -# Lazy Declaration resolving - -FIR in compiler mode works by sequentially running every resolve phase on all files at once like shown in pseudo-code: - -```kotlin -for (phase in allResolvePhases) { - for (file in allFirFiles) { - runPhaseOnFile(file, phase) - } -} -``` - -Such behavior does not work for the Analysis API. Analysis API needs to resolve one specific declaration to the minimum possible phase. To -solve that problem, there are *lazy phases*. Lazy phases can be run only on a single declaration, not on the whole `FirFile`. - -Suppose we need to resolve some `FirDeclaration` to phase number `N`: - -* First, we resolve containing `FirFile` to the `IMPORTS` phase, -* Then we resolve file annotations, -* When we find a non-local container for our declaration as only non-local declarations can be lazily resolved for now, -* Finally, resolve *only* that container from phase number `1` to phase `N` - -All resolve happens under containing file-based *write lock*. +There are a bunch of different areas. +Docs for each area are sorted by context depth – from the basic overview to the deepest implementation details. +- Mapping from `KtElement` to `FirElement` (*KT -> FIR*) & Incremental Analysis & Collecting diagnostics + 1. [FirElementBuilder](../../../analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/FirElementBuilder.kt) + is responsible for mapping from `KtElement` to `FirElement`. + 2. [FileStructure](../../../analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructure.kt) + is a tree like-structure of `FileStructureElement` which is associated with some `KtFile`. + Aggregates information about *KT -> FIR* mapping and diagnostics for associated file. + 3. [FileStructureElement](../../../analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructureElement.kt) + is a representation of specific `KtElement`. + Is responsible for *KT -> FIR* mapping and diagnostics for the specific `KtElement`. + 4. [FileStructureElementDiagnosticRetriever](../../../analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/FileStructureElementDiagnosticRetriever.kt) + is responsible to collect diagnostics for `FileStructureElement`. + 5. [LLFirDeclarationModificationService](../../../analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/LLFirDeclarationModificationService.kt) + is a service which is responsible for `FileStructure` invalidation in the case of associated PSI modification. +- Lazy resolution + 1. [FirResolvePhase](../../../compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirResolvePhase.kt) + to understand what the compiler phases are and what is the basic difference between the CLI and the Analysis API modes. + 2. [LLFirModuleLazyDeclarationResolver](../../../analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/LLFirModuleLazyDeclarationResolver.kt) + is the entry point for lazy resolution. + Receives some `FirElementWithResolveState` element and a desired phase and resolve this element to this phase. + 3. [LLFirResolveDesignationCollector](../../../analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/LLFirResolveDesignationCollector.kt) + is a designation collector. + Collects `LLFirResolveTarget` for the specific `FirElementWithResolveState`. + Decides which element can be resolved lazily and which cannot. + 4. [LLFirResolveTarget](../../../analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/targets/LLFirResolveTarget.kt) + is an instruction on how to resolve specific `FirElementWithResolveState`. + 5. [LLFirLazyResolverRunner](../../../analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirLazyResolverRunner.kt) + is responsible + for running [LLFirLazyResolver](../../../analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirLazyResolver.kt) + for the specific phase and making sure that it worked correctly. + 6. [LLFirTargetResolver](../../../analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirTargetResolver.kt) + is the core part of lazy resolution. + We have a separate implementation of `LLFirTargetResolver` for each compiler phase, + each of which is responsible for all the resolution logic for the associated phase. + 7. [LLFirLockProvider](../../../analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/builder/LLFirLockProvider.kt) + is responsible for locking logic which is widely used by `LLFirTargetResolver` during resolution. +- [ContextCollector](../../../analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/ContextCollector.kt) + represents resolution context of a specific place in code (a context) ## Project Module Structure -The `FirModuleResolveState` represents a view from a specific module (**root module**) to the dependent modules. A module is represented by: - -* `FirIdeSourcesSession` the implementation of `FirSession` (FIR compiler representation of a module) -* `ModuleFileCache` the `KtFile -> FirFile` cache & also caches for FIR providers +The `LLFirResolveSession` represents a view from a specific module (**root module**) to the dependent modules. A module is represented by: +* `LLFirSession` – the implementation of `FirSession` (FIR compiler representation of a module) +* `ModuleFileCache` – the `KtFile -> FirFile` cache & also caches for FIR providers