从 Kotlin 编译器 API 的变化开始: 2.2.2X -> 2.3.0-Beta1

大家好!众所周知,我有在平时维护一个简单的Kotlin编译器插件项目: Kotlin Suspend Transform Compiler Plugin。 想必经常维护编译器插件的小伙伴们也清楚,每次 Kotlin 的主要版本递进,编译器的API都会或多或少的发生变化, 也给编译器插件的更新维护带来不小的挑战。那么借此机会,我会在每次发生API变化的更新出现后, 籍由此系列记录一下能有哪些编译器API的变化可以被我发现。

不算是一种技术分享文,所以不保证有什么技术含金量喔~

今天要记录的版本变化是:v2.2.2X -> 2.3.0-Beta1。


首先先直接列举一下这次更新出现的所有错误和警告:

perl 复制代码
[KOTLIN] e: file:///Users/forte/IdeaProjects/suspend-transform-kotlin-compile-plugin/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformComponentRegistrar.kt:38:1 Class 'SuspendTransformComponentRegistrar' is not abstract and does not implement abstract base class member:
val pluginId: String
[KOTLIN] e: file:///suspend-transform-kotlin-compile-plugin/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirTransformer.kt:40:51 Unresolved reference 'getContainingClassSymbol'.
[KOTLIN] e: file:///suspend-transform-kotlin-compile-plugin/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirTransformer.kt:891:84 Unresolved reference 'getContainingClassSymbol'.
[KOTLIN] e: file:///suspend-transform-kotlin-compile-plugin/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/ir/SuspendTransformTransformer.kt:406:34 'val symbols: Symbols' is deprecated. This API is deprecated. Use `irBuiltIns` instead.
[KOTLIN] e: file:///suspend-transform-kotlin-compile-plugin/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/ir/SuspendTransformTransformer.kt:462:38 'val symbols: Symbols' is deprecated. This API is deprecated. Use `irBuiltIns` instead.

看来这次变化的东西不是非常多,也是很仁慈了。接下来一个个来看看吧~

SuspendTransformComponentRegistrar.pluginId

更新到 2.3.0 之后,SuspendTransformComponentRegistrar 新增了一个需要被实现的抽象属性:pluginId: String。

vbnet 复制代码
[KOTLIN] e: file:///Users/forte/IdeaProjects/suspend-transform-kotlin-compile-plugin/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformComponentRegistrar.kt:38:1 Class 'SuspendTransformComponentRegistrar' is not abstract and does not implement abstract base class member:
val pluginId: String

看样子是打算对一些信息或日志之类的进行更明确更友好的提示了?当然应该也不止于此,我们来看看它的文档注释:

arduino 复制代码
/**
* Uniquely identifies the Kotlin compiler plugin. Must match the `pluginId` specified in [CommandLineProcessor].
* The ID can be used in combination with `-Xcompiler-plugin-order` to control execution order of compiler plugins.
*/
val pluginId: String

好吧,看来还是有些限制的,它的值要求跟 CommandLineProcessor.pluginId 一致,以此可以通过编译器参数来让用户指定编译器插件的执行顺序。

getContainingClassSymbol

接下来就是老生常谈的 API 消失和变化了。从错误日志中可以看到,扩展函数 org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol 消失了。 要找到它跑到哪里去了,就要先看看它之前是怎么用:

Kotlin 复制代码
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol

// ...

val overriddenAnnotation = firAnnotation(
    overriddenFunction, markAnnotation, overriddenFunction.getContainingClassSymbol()
) ?: return@processOverridden

根据我的经验,通常情况下这类扩展函数不会被真正的_移除_,大多数都是被挪了个地方、改了个名字之类的。修复起来也很简单:借助我们万能的IDE提示, 找到它新的位置:

Kotlin 复制代码
import org.jetbrains.kotlin.fir.resolve.getContainingClassSymbol

// ...

val overriddenAnnotation = firAnnotation(
    overriddenFunction, markAnnotation, overriddenFunction.getContainingClassSymbol()
) ?: return@processOverridden

不出所料,它只是换了个包。😊

symbols -> irBuiltIns

下一个变化就更加慈悲了:它没有一声不吭的离开,而是好心的标记了废弃,并给我留下了温柔的指引。

先来看看代码中是怎么使用的:

Kotlin 复制代码
val suspendLambda = context.createSuspendLambdaWithCoroutineScope(
    parent = originFunction.parent,
    // suspend () -> ?
    lambdaType = context.symbols.suspendFunctionN(0).typeWith(originFunction.returnType),
    originFunction = originFunction
).also { +it }

它会构建一个 suspend () -> ? 的Lambda类型,供编译器插件使用。那么这个时候, 我们会得到警告:

csharp 复制代码
'val symbols: Symbols' is deprecated. This API is deprecated. Use `irBuiltIns` instead.

很明显,context.symbols 有更好的替代品:irBuiltIns。事不宜迟,换上看看吧:

Kotlin 复制代码
val suspendLambda = context.createSuspendLambdaWithCoroutineScope(
    parent = originFunction.parent,
    // suspend () -> ?
    lambdaType = context.irBuiltIns.suspendFunctionN(0).typeWith(originFunction.returnType),
    originFunction = originFunction
).also { +it }

有趣的是,被废弃的类型 Symbols 其实也是对 IrBuiltIns 的一种包装和扩展。它的定义是:

Kotlin 复制代码
abstract class Symbols(irBuiltIns: IrBuiltIns) : PreSerializationSymbols.Impl(irBuiltIns) {
    // ...
}

在构造中,它也是需要一个 IrBuiltIns 的。以其中的 suspendFunctionN(0) 为例,它的实现也是直接使用的 irBuiltIns.suspendFunctionN。

总结

老实说,这次更新的变化不是非常大,几个API的变化都很好修复。不过我很喜欢,也希望未来的更新都能这么温柔。

相关推荐
誰能久伴不乏43 分钟前
桌面客户端的运行日志系统:SQLite 分块 + 独立写线程 + 文本降级
数据库·c++·qt·架构·sqlite
未来之窗软件服务7 小时前
终端优先同步架构终端场景下轻量化、高可用通信模型-东方仙盟
架构·东方仙盟·阿雪技术观·网络震荡·dns污染·数据中继器·边界网关
喵了几个咪8 小时前
GoWind CMS 拆解:在 Go 里给 TipTap 搭一套 Yjs 协同后端
开发语言·后端·golang
Flynt8 小时前
我把微信运动的排行榜和定点推送复刻了一遍:100万次步数更新只要4秒,坑在别处
redis·后端·性能优化
冬奇Lab8 小时前
一天一个开源项目(第248篇):CleanYourTV —— 让 AI 编程助手通过 Wi-Fi 给安卓电视去广告、换上 Apple TV 风格主屏
开源·资讯
wflynn9 小时前
GitHub 今日推荐|gpu-unlock-ada:Ada 显卡张量算力翻倍解锁
开源·github·c
_孤傲_10 小时前
快速掌握 MySQL 语法
数据库·后端·mysql
SL_staff11 小时前
JVS私有化文档系统上线避坑指南:5大运维与业务协同断点及检测加固实践
java·开源·全栈
IT_陈寒12 小时前
Java静态变量初始化坑得我头皮发麻
前端·人工智能·后端
步行cgn12 小时前
Thymeleaf 编辑表单详解:从字段回填到模拟 PUT 请求
后端