菜单

FIR (前端 IR)

相关源文件

FIR(前端 IR)是 Kotlin 编译器前端使用的现代中间表示。它充当 PSI(程序结构接口)树生成和编译器后端 IR 阶段之间的桥梁。FIR 提供了一个结构化且类型化的 Kotlin 代码表示,能够进行高级分析、强大的诊断和各种优化。

FIR 架构概述

FIR 被设计为一个模块化系统,包含多个阶段,这些阶段逐步丰富和解析代码表示。

来源

关键组件

声明解析

FirDeclarationsResolveTransformer 实现的声明解析阶段处理 Kotlin 代码中的所有声明。

该转换器处理

  • 属性和字段
  • 函数和构造函数
  • 类、接口和枚举
  • 类型别名和其他声明

声明解析过程解析

  • 可见性、修饰符和其他状态属性
  • 泛型声明的类型参数
  • 返回类型和参数类型
  • 委托和继承关系

来源

表达式解析

FirExpressionsResolveTransformer 处理表达式解析。

此转换器解析

  • 限定访问表达式(属性访问、方法调用)
  • 函数和构造函数调用
  • 运算符和中缀函数
  • 智能转换和类型操作
  • 字面量、常量和更复杂的表达式

来源

调用解析

调用解析是一个复杂的过程,由 FirCallResolver 实现。

调用解析过程

  1. 创建调用信息结构
  2. 使用塔解析器查找候选函数/属性
  3. 应用解析阶段来检查每个候选
  4. 处理接收者(调度和扩展)
  5. 处理参数及其类型
  6. 选择最具体的候选
  7. 使用解析的类型信息完成调用

来源

类型推断

类型推断在整个解析过程中是集成的,但在以下方面尤其重要:

  • 泛型函数调用
  • Lambda 表达式
  • 可调用引用

类型推断系统组件包括:

  • FirCallCompleter:管理整体类型推断过程
  • PostponedArgumentsAnalyzer:处理推迟的参数,如 lambda
  • ConstraintSystemCompleter:完成约束系统
  • FirPCLAInferenceSession:管理推迟的可调用和 Lambda 参数

来源

解析原子和候选

FIR 解析系统使用几个重要概念:

  1. 解析原子ConeResolutionAtom):表示需要解析的实体(表达式、Lambda、可调用引用)

  2. 候选Candidate):表示调用的潜在函数或属性匹配,包含

    • 符号(函数或属性)
    • 系统(用于类型推断的约束系统)
    • 替换器(类型替换)
    • 适用性(候选匹配的程度)

来源

调用完成

调用解析的最后阶段涉及使用解析的类型信息来完成调用。

FirCallCompletionResultsWriterTransformer 负责将调用解析的结果写回 FIR 树。

来源

测试基础设施

FIR 拥有广泛的测试基础设施以确保正确性。

测试系统包括:

  • 诊断测试:比较 FIR 生成的诊断与预期输出。
  • 轻量级树测试:使用轻量级树而不是完整 PSI 来测试 FIR。
  • 兼容性测试:将 FIR 结果与 K1(遗留前端)结果进行比较。
  • 配置测试:使用不同配置进行测试(类型别名展开、语言版本等)。

来源

与编译器架构的集成

FIR 位于 Kotlin 编译器管道中的 PSI 生成和中间件 IR 之间。

FIR 与 K1(遗留前端)并行工作,但提供了更现代的前端处理方法,具有更好的性能、增量编译支持和改进的诊断。

来源

  • 初始任务描述中提供的 Mermaid 图

总结

FIR(前端 IR)是 Kotlin 编译器的一个关键组件,它在源代码表示和中间件 IR 之间架起了桥梁。通过一系列转换阶段,它解析声明、表达式和类型,提供 Kotlin 代码的完全类型化表示,从而实现精确的诊断和高效的代码生成。