458 字
2 分钟
记录一下自己写第一个的Kotlin编译器插件
当你需要一个功能,虽然这个功能可以手写实现,但是谁不想偷个”懒“呢?
插件的作用
插件的作用就是给Kotlin的特性为Java做桥接 --- 拓展属性
拓展属性是Kotlin的核心特性之一,在Kotlin中是非常好用的功能,但是到了Java反而变的难用,
Kotlin编译后的字节码文件
在Kotlin/JVM平台中,拓展属性一般为顶层属性 --- topLevel,既然是顶层,那最终都会被放到一个静态类中这个静态类名
分为两部分一个: 前面的部分就是原文件的名称, 后面的部分加上Kt字符串例如: MyClass.kt会被编译为 MyClassKt.class,
在Java中访问需要调用这个静态类里面的静态方法或者属性, 就像下面这样
// MyClass.kt
val String.firstChar get() = this.first()System.out.println(MyClassKt.getFirstChar("Hello")); // H这里
MyClassKt#getFirstChar传入的就是receiver(接收器)
在Kotlin中可以像访问成员属性一样访问拓展属性,而在Java中必须通过”工具类”来访问, 显得有些不美观了, 所以我写了一个插件用于自动为receiver生成成员getter/setter
使用插件
提前配置好插件后直接在commonMain或jvmMain内写拓展属性
// Text.kt
import cn.rtast.interop.annotation.AutoGenGetter
class Text {}
@AutoGenGetter // 使用注解标记生成getter
val Text.text get() = "Hello"下面是将编译后的字节码反编译为Java代码的简化代码
import cn.rtast.interop.annotation.JavaOnly;
public final class Text {
@JavaOnly
public int getA() {
return TextKt.getA(this);
}
}
JavaOnly注解是一个RequiresOptIn的注解, 对Java使用者没有任何影响, 如果Kotlin 使用者使用这个API必须手动加上OptIn来抑制错误, 不手动加上则无法通过编译
插件地址
插件源代码已经开源在Github上, 地址: InteropShield