Docs: change analysis docs structure
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
# Low Level API
|
||||
|
||||
Low-level API (LL API fopr 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
|
||||
|
||||
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.
|
||||
|
||||
## Mapping KtElement to FirElement (KT -> FIR) & Incremental Analysis
|
||||
|
||||
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.
|
||||
|
||||
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*.
|
||||
|
||||
## 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
|
||||
Reference in New Issue
Block a user