LoginSignup
0
0

More than 1 year has passed since last update.

【kotlinx-metadata】引数/型引数のnullabilityを取得する

Last updated at Posted at 2021-05-04

やること

以下のクラスのコンストラクタの引数について、それぞれの型/型引数のnullabilityを取得します。

data class Foo(val nonNullList: List<Any>, val nullableList: List<Any?>, val starList: List<*>?)

やり方

ソースコード全体は以下の通りです。
細かい部分はコメントに記述してあります。

import kotlinx.metadata.Flag
import kotlinx.metadata.KmClass
import kotlinx.metadata.KmConstructor
import kotlinx.metadata.KmType
import kotlinx.metadata.jvm.KotlinClassHeader
import kotlinx.metadata.jvm.KotlinClassMetadata

data class Foo(val nonNullList: List<Any>, val nullableList: List<Any?>, val starList: List<*>?)

fun Metadata.toKotlinClassHeader() = KotlinClassHeader(
    this.kind,
    this.metadataVersion,
    this.data1,
    this.data2,
    this.extraString,
    this.packageName,
    this.extraInt
)

val KmType.isNullable: Boolean get() = Flag.Type.IS_NULLABLE(flags)

fun main() {
    // メタデータ取得 -> クラス情報に変換 -> 対象となるコンストラクタを取得
    val metadata: KotlinClassMetadata.Class = (Foo::class.java.annotations.first { it is Metadata } as Metadata)
        .toKotlinClassHeader()
        .let { KotlinClassMetadata.read(it) as KotlinClassMetadata.Class }
    val kmClass: KmClass = metadata.toKmClass()
    val constructor: KmConstructor = kmClass.constructors.single()

    // コンストラクタの引数の型情報、typeプロパティは引数がvarargだった場合nullになる
    val parameterTypes: List<KmType?> = constructor.valueParameters.map { it.type }
    // 引数のnullability確認(今回はvararg引数が無いため強制アンラップ)
    println(parameterTypes.map { it!!.isNullable }) // -> [false, false, true]
    // 型引数情報、argumentsは型引数一覧で、今回の処理対象はListで型引数は1つなためsingle()している
    val typeParameters: List<KmType?> = parameterTypes.map { it!!.arguments.single().type }
    // 型引数のnullability確認、指定がスタープロジェクションだった場合nullになる
    println(typeParameters.map { it?.isNullable }) // -> [false, true, null]
}

参考にさせて頂いた内容

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0