Open-Source Wikis

/

Kotlin

/

Compiler

/

Frontend (K2 / FIR)

JetBrains/kotlin

Frontend (K2 / FIR)

Active contributors: Kirill Rakhman, Dmitriy Novozhilov, Mikhail Glukhikh

The K2 frontend lives in compiler/fir/ and is Kotlin's primary frontend since version 2.0 (May 2024). It replaced K1 (the legacy frontend at compiler/frontend/) as the default but K1 remains in the tree for the IDE plugin's compatibility window.

Purpose

K2 takes a parsed KtFile (or its lighter equivalent for performance-sensitive paths) and produces a fully resolved FIR (Frontend Intermediate Representation) tree, plus a stream of diagnostics. The output is then either translated to backend IR (via compiler/fir/fir2ir/) or consumed by the Analysis API for IDE features.

Directory layout

compiler/fir/
├── tree/                       FIR tree types and renderers (Fir*)
├── cones/                      Type-system primitives (ConeKotlinType, ...)
├── raw-fir/                    PSI → raw FIR builder
├── resolve/                    Resolution phases
├── checkers/                   Diagnostic checkers + generated FirErrors
├── providers/                  Symbol providers (declarations, library symbols)
├── semantics/                  Semantic analyzers used inside resolution
├── entrypoint/                 The K2 frontend entry points
├── fir2ir/                     FIR → backend IR translator
├── fir-jvm/, fir-js/,
│   fir-native/                 Platform-specific frontend extensions
├── fir-deserialization/        Reading library declarations as FIR
├── fir-serialization/          Writing FIR for klibs
├── analysis-tests/             Diagnostic tests (FIR-specific runners)
├── modularized-tests/          Multi-module compilation tests
├── plugin-utils/               Hooks for FIR-aware compiler plugins
├── diagnostic-renderers/       Pretty-printing of diagnostics
└── dump/                       Text dumps of FIR for testing

Key abstractions

Type File Role
FirElement compiler/fir/tree/.../FirElement.kt Root of the FIR class hierarchy.
FirRegularClass, FirSimpleFunction, FirProperty, ... compiler/fir/tree/... Declaration nodes.
FirSymbol compiler/fir/tree/.../symbols A reference to a declaration; primary identity in K2.
FirResolvePhase compiler/fir/resolve/.../FirResolvePhase.kt Enumeration of resolve phases (RAW_FIR through BODY_RESOLVE).
ConeKotlinType compiler/fir/cones/.../ConeKotlinType.kt The K2 type system's foundational type.
FirSession compiler/fir/.../session Container for resolve services, providers, and configuration.
FirDeclarationChecker, FirExpressionChecker compiler/fir/checkers/... Single-element checker base classes for diagnostics.
FirErrors compiler/fir/checkers/gen/.../FirErrors.kt Generated table of diagnostic factories.

How resolve works

K2 processes code in phases. The fundamental invariant (stated in compiler/AGENTS.md):

In phase B following phase A, all FIR elements visible in B are resolved to phase A.

The phases (see FirResolvePhase) progress from RAW_FIR (just-built tree, no resolution) up through IMPORTS, SUPER_TYPES, TYPES, STATUS, EXPECT_ACTUAL_MATCHING, CONTRACTS, IMPLICIT_TYPES_BODY_RESOLVE, and BODY_RESOLVE. Each phase enriches FIR nodes with information that later phases can rely on. The Analysis API's "low-level FIR" (analysis/low-level-api-fir/) drives this same machinery on demand for IDE features.

graph LR
    RAW["RAW_FIR<br/>(from PSI)"] --> IMP[IMPORTS]
    IMP --> SUP[SUPER_TYPES]
    SUP --> TY[TYPES]
    TY --> ST[STATUS]
    ST --> EA[EXPECT_ACTUAL]
    EA --> CT[CONTRACTS]
    CT --> IB[IMPLICIT_TYPES_BODY_RESOLVE]
    IB --> BR[BODY_RESOLVE]

Diagnostics

Diagnostics in K2 are defined in two places:

  • A central list in compiler/fir/checkers/checkers-component-generator/src/.../FirDiagnosticsList.kt.
  • Generated tables in compiler/fir/checkers/gen/.../FirErrors.kt and FirErrorsDefaultMessages.kt (one of the most-modified files in the repo).

Checkers themselves live in compiler/fir/checkers/ and inherit from FirDeclarationChecker, FirExpressionChecker, etc. The Analysis API mirrors the FIR diagnostic list in analysis/analysis-api-fir/gen/.../KaFirDiagnostics* so IDEs can consume them.

fir2ir

compiler/fir/fir2ir/ walks resolved FIR and produces backend IR. This is where the frontend hands off to the backends. It depends on compiler/ir/ir.tree/ for the output type.

Platform-specific extensions

Each Kotlin target adds its own frontend bits:

  • compiler/fir/fir-jvm/ — JVM-specific resolution (e.g., Java interop, platform types).
  • compiler/fir/fir-js/ — JS-specific (external declarations, dynamic type).
  • compiler/fir/fir-native/ — Native interop hooks.

compiler/fir/fir-deserialization/ reads previously compiled libraries (their klib metadata or class file metadata) back into FIR symbols so user code can resolve against them.

Testing

FIR tests have specialized infrastructure. The most relevant runner setups live in compiler/fir/analysis-tests/ and compiler/fir/fir2ir/test/. Test data uses the standard K2 directive vocabulary; see compiler/fir/analysis-tests/AGENTS.md for the full list.

Integration points

  • Consumed by compiler/fir/fir2ir/ (and via that, every backend).
  • Consumed by analysis/analysis-api-fir/ and analysis/low-level-api-fir/ for IDE tooling.
  • Plugin extension points in compiler/fir/plugin-utils/ (and consumed in plugins/).
  • CLI driver in compiler/cli/cli-jvm/ etc. invokes the FIR pipeline based on -language-version (K2 is the default since 2.0).

Where to start

When extending K2 (adding a checker, a new phase, a new frontend feature), start in compiler/fir/checkers/ for diagnostics or compiler/fir/resolve/ for actual resolution logic. The compiler/fir/analysis-tests/AGENTS.md and docs/fir/fir-basics.md files are the canonical references. Cross-check the patterns and conventions page for K2/K1 dual-implementation expectations.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Frontend (K2 / FIR) – Kotlin wiki | Factory