编译器插件
如果你使用 Kotlin + Gradle 开发组件(这也是我们推荐的组合), 那么当你公开了一个挂起函数的 API、 或实现一个具有挂起函数的 simbot4 标准 API (例如 Bot、 事件 等) 时, 你极大概率(我们也强烈推荐)你需要使用到标准库在使用的编译器插件: kotlin-suspend-transform-compiler-plugin。
此编译器插件的目的是根据挂起函数生成对 Java 或其他特定平台友好的非挂起函数。
安装
安装编译器插件
添加插件 love.forte.plugin.suspend-transform。
安装 simbot 编译器插件辅助库
在你 Gradle 项目的 buildSrc/build.gradle(.kts) 中添加 simbot 提供的辅助模块: simbot-gradle-suspendtransforms。
也可以将它添加到 build-logic 等 included build 中,在构建逻辑中复用。
配置编译器插件
旧的 suspendTransform { ... }/addSimbotJvmTransformers() 配置入口已废弃, 应迁移到上面的 suspendTransformPlugin 与 addSimbotJvmTransforms()。
使用
响应式桥接
addSimbotJvmTransforms() 的配置包含响应式转换器, 为 @ST/@STP 生成返回 org.reactivestreams.Publisher 的桥接方法。 标准 API 生成的响应式方法使用 ExperimentalReactiveBridgingApi 标记, 调用示例见 响应式桥接。
标记注解
目前, 编译器插件的标记注解有两个:
@SuspendTrans@SuspendTransProperty
并且它们各自都有一个用于简写的 typealias:
@ST@STP
它们通常作用在类型上或挂起函数上。
举个例子,如下一个接口, 在编译后会产生几个新的非挂起桥接函数:
生成的桥接函数最终逻辑都仍然是被标记的那个挂起函数。
@STP 与 @ST 的区别在于,前者只能标记在没有参数的挂起函数上,并且生成的桥接"函数"实际上是属性类型。 还是上面的例子,我们稍作修改, 在编译后会产生几个新的非挂起桥接"属性":
这样在 Java 中,使用者便可以以 Getter API 的风格去使用它们了。
标记注解都存在一些参数,可以定制生成的API的函数/属性名。
实现挂起函数时
当你实现 Event、 Bot 等 simbot 标准库中具有挂起函数的类型时,它们基本上都已经通过此插件做了转化。
你需要观察:
Ⅰ: 如果继承的函数的返回值对于你来说 没有 进一步扩展
那么你可以直接将其标记 @JvmSynthetic:
Ⅱ: 继承的函数的返回值对于你来说 有进一步扩展
那么你需要标记一个与被继承函数相同的编译器插件标记注解。
举个例子:
假设你需要实现的:
假设你的实现:
在 simbot4 标准 API 中,大部分被标记的挂起函数都没有参数,因此注意它标记的注解即可, @ST 或 @STP 中的一个。 注解有可能会被标记在类上而不是方法上,可以注意观察。
但也并非没有具有特殊参数的API,目前,它们分布在如下地方:
GuildRelation.guild(...)GroupRelation.group(...)ContactRelation.contact(...)Organization.member(...)Guild.channel(...)Guild.chatChannel(...)
它们主要就是将参数里的各个 xxxBaseName 重新指定为了 Getter 风格的 getXxx, 例如 GuildRelation.guild(...):
之所以这么做,是因为这些API实际上都比较符合 Getter 的风格,但是因为它们都有参数,而不能直接使用 @STP, 所以便使用这种方式手动配置来生成 Java 中更为友好也更符合习惯的 API。