JetBrains/kotlin
Analysis API
Active contributors: Dmitrii Gridin, Marco Pennekamp, Kirill Rakhman
The Analysis API is the IDE-facing query surface over the Kotlin compiler. It lives under analysis/ and is the contract between the IntelliJ Kotlin plugin (in JetBrains/intellij-community) and the compiler in this repository. The API exposes symbols, types, and resolution information through a stable, lifetime-checked façade so that IDEs do not have to know about FIR or descriptor internals.
Purpose
Provide a stable, lifetime-aware API to perform semantic analysis on Kotlin code. Both the K1 (descriptor-based) and K2 (FIR-based) frontends are wired to the same surface, so IDE features written against the Analysis API work in either frontend mode.
Directory layout
analysis/
├── analysis-api/ Public API surface (Ka* types)
├── analysis-api-platform-interface/ Abstraction over the host (IntelliJ vs Standalone)
├── analysis-api-impl-base/ Shared impl utilities used by both backends
├── analysis-api-fir/ K2 (FIR) implementation
├── analysis-api-fe10/ K1 (legacy) implementation
├── analysis-api-standalone/ Standalone (non-IDE) entry point
├── low-level-api-fir/ Low-level, on-demand FIR resolve (LL*)
├── light-classes-base/ Common bits for light classes
├── symbol-light-classes/ Light Java classes from FIR symbols
├── decompiled/ Decompiled-code views (libraries, .class files)
├── stubs/ PSI stub support
├── kt-references/ Kotlin reference resolution
├── analysis-test-framework/ Shared test framework
├── analysis-internal-utils/ Internal utilities
├── analysis-tools/ CLI / debugging tools
├── test-data-manager/ Variant-aware test data tooling
├── docs/ Design notes and contribution guides
└── AGENTS.md Onboarding for Analysis API developersKey abstractions
| Type | Where | Role |
|---|---|---|
analyze { ... } |
analysis/analysis-api/.../analysis/api/analyze.kt |
The entry point. Opens an analysis session for a KtElement. |
KaSession |
analysis/analysis-api/.../KaSession.kt |
Scope holding all analysis services for the active context. |
KaSymbol |
analysis/analysis-api/.../symbols/KaSymbol.kt |
A reference to a declaration (class, function, property, ...). |
KaType |
analysis/analysis-api/.../types/KaType.kt |
A type as seen from the API. |
KaCallableSymbol, KaClassSymbol, ... |
analysis/analysis-api/.../symbols/... |
Specialized symbol types. |
KaFirX impls |
analysis/analysis-api-fir/.../KaFir* |
K2-backed implementations. |
LLFirSession, LLFirResolveSession |
analysis/low-level-api-fir/.../session |
Low-level FIR session that drives on-demand resolution for the IDE. |
KaFirDiagnostics, KaFirDiagnosticsImpl |
analysis/analysis-api-fir/gen/... |
Mirror of compiler/fir/checkers diagnostics for IDE consumption. |
Architectural model
From analysis/AGENTS.md:
PSI (syntax) → Analysis API (semantics) → Symbols, Types, ResolutionThe Analysis API divides concerns into three roles:
- Platform — provides declarations, project structure, and modification events. Two impls: IntelliJ (used by the IDE plugin) and Standalone (
analysis-api-standalone/, used by tooling and CI). - Engine — performs analysis using platform-provided info. Two impls: K1 (
analysis-api-fe10/) and K2 (analysis-api-fir/). - User — code that calls
analyze { ... }and reads symbols/types.
How a query flows
graph LR
User["User code<br/>analyze(element) { … }"] --> Session["KaSession"]
Session --> ImplBase["analysis-api-impl-base"]
ImplBase --> Engine["KaFirSession (K2)<br/>or KaFe10Session (K1)"]
Engine -->|K2| LLFir["LLFirResolveSession"]
LLFir --> FIR["compiler/fir resolve"]
Engine -->|K1| Front["compiler/frontend (K1)"]For K2 specifically, the low-level FIR API (analysis/low-level-api-fir/) drives lazy, on-demand FIR resolution: only the parts of FIR a query needs are resolved, and only up to the phase the query needs. This keeps IDE responsiveness reasonable on large projects.
Lifetime and validity
A KaSession is bound to a modification of the project model. Symbols obtained from one session are not portable to another. The convention is enforced via withValidityAssertion: every Analysis API implementation method asserts the session is still valid before doing any work.
This is one of the most important rules to follow when contributing to the API. New Ka* methods should:
- Validate lifetime ownership with
withValidityAssertion. - Mark experimental APIs with
@KaExperimentalApi. - Mark implementation details with
@KaImplementationDetail. - Prefer interfaces to classes for binary compatibility.
- Return nullable types for operations that can fail (avoid exceptions for non-exceptional cases).
Diagnostics
K2 diagnostics declared in compiler/fir/checkers/ are mirrored here as KaFirDiagnostic* (in analysis/analysis-api-fir/gen/.../KaFirDiagnostics*). When K2 adds a new diagnostic, the mirror file regenerates — this is one of the most-modified paths in the repo. The Analysis API's diagnostic surface is what IDE inspection authors and tooling write code against.
Light classes
Java-aware tooling (Lombok, the IDEA Java plugin) wants a PsiClass view of a Kotlin declaration. The Analysis API provides this via analysis/symbol-light-classes/ (FIR-backed) and analysis/decompiled/light-classes-for-decompiled/ (for .class files in libraries). The K1 equivalent is compiler/light-classes/.
Standalone mode
analysis/analysis-api-standalone/ lets you spin up an Analysis API instance outside of IntelliJ — useful for build-time linting, code generation, and CI tools. It bundles an in-memory project model.
Testing
The Analysis API uses a variant-aware test framework (analysis/test-data-manager/ plus analysis/analysis-test-framework/). Test data lives under each module's testData/ and is managed with manageTestDataGlobally:
./gradlew manageTestDataGlobally --mode=update --test-data-path=analysis/analysis-api/testData/components/resolver/
./gradlew manageTestDataGlobally --mode=update --test-class-pattern=.*ResolveTest.*
./gradlew manageTestDataGlobally --mode=update --golden-only
./gradlew manageTestDataGlobally --mode=update --incrementalThis handles variant chains correctly (e.g., a golden .txt file and its .js.txt/.wasm.txt variants).
Integration points
- Consumed by: the IntelliJ Kotlin plugin (different repo), Detekt, and other Kotlin static-analysis tools.
- Backed by: K2 (
compiler/fir/) and K1 (compiler/frontend/). - Co-travelers:
compiler/psi/(PSI types) andanalysis/symbol-light-classes/(Java-PSI views).
Where to start
For a new public API: analysis/analysis-api/ and analysis/docs/contribution-guide/api-development.md. For an implementation: analysis-api-fir/ (K2) and analysis-api-fe10/ (K1) — the dual-impl rule applies. The analysis/AGENTS.md document is the canonical onboarding reference.
See Frontend (K2 / FIR) for the K2 backend that powers most of this and PSI for the syntax layer the API sits on top of.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.