跳到内容

KotlinPoet-metadata

interop:kotlin-metadata 是一个用于处理 Kotlin @Metadata 注解的 API。它的 API 基于 kotlin-metadata,为其类型和 JVM 元数据信息提供扩展。这可用于从 ClassTypeElement@Metadata 注解中读取 Kotlin 语言语义。

示例

data class Taco(val seasoning: String, val soft: Boolean) {
  fun prepare() {

  }
}

val kmClass = Taco::class.toKmClass()

// Now you can access misc information about Taco from a Kotlin lens
println(kmClass.name)
kmClass.properties.forEach { println(it.name) }
kmClass.functions.forEach { println(it.name) }

标志

Flags.kt 下,类型也有一些布尔标志可用。这些标志读取底层的 kotlin-metadata Flags 属性。

使用上面的 Taco 示例,我们可以获取某些信息

println("Is class? ${kmClass.isClass}")
println("Is data class? ${kmClass.isData}")

与 KotlinPoet 的互操作性

interop:kotlin-metadata 提供了一个 API,用于将核心 kotlin-metadata Km 类型转换为其 API 的 KotlinPoet 源代码表示。这包括完整的类型解析、签名、包含的元素以及底层 API 的通用存根源代码表示。

示例

data class Taco(val seasoning: String, val soft: Boolean) {
  fun prepare() {
  }
}

val typeSpec = Taco::class.toTypeSpec()

// Or FileSpec
val fileSpec = Taco::class.toFileSpec()

源代码表示

生成的表示是底层源代码的尽力而为的表示。这意味着合成元素将被排除在生成之外。像 lambda 或委托这样的 Kotlin 特定语言特性将被强制转换为它们的习惯源代码形式。

为了提供帮助,toTypeSpec()toFileSpec() 接受可选的 ClassInspector 实例,以协助解析/理解底层 JVM 代码。这对于注解、伴生对象、某些 JVM 修饰符、覆盖等很重要。虽然它是可选的,但如果没有这些信息,表示的源代码可能不完整。反射式和 javax Elements 的实现可在 com.squareup.kotlinpoet.metadata.classinspectors 包下找到。

生成的源代码仅是存根实现,这意味着函数、属性 getter 和委托属性等元素的实现细节仅通过 TODO() 占位符进行存根。

已知限制

  • 目前仅支持 KotlinClassMetadata.ClassKotlinClassMetadata.FileFacade。不支持 SyntheticClassMultiFileClassFacadeMultiFileClassPart
  • @JvmOverloads 注解仅支持 ElementsClassInspector,不支持反射。
  • 非 const 字面值仅支持 ElementsClassInspector,不支持反射。
  • 来自 synthetic 构造的 ClassInspector 数据仅支持 ReflectiveClassInspector,不支持 elements。这是因为 javax Elements API 不建模 synthetic 构造。这可能导致一些信息缺失,例如静态伴生对象属性或 property: 目标注解。
  • 使用 AnnotationRetention.SOURCE 注解的注解在反射和 javax elements 中都不可解析。