jeudi 30 novembre 2023

Kotlin reflection application to parsing, an example

I am experimenting with Kotlin's reflection mechanism. However, things go wrong when I try to apply the function recursively. I have been learning Kotlin for less than a month now and I am completely out of my depth here. Please guide me?

import kotlin.reflect.KClass
import kotlin.reflect.KMutableProperty
import kotlin.reflect.full.findAnnotation

annotation class CsByte
annotation class CsStruct

class Struct1 {
    @CsByte
    var x: Int = 0
    @CsStruct
    var inner1: Inner = Inner()
}

class Inner {
    @CsByte
    var y: Int = 0
}

fun <T : Any> parseStructRecursively (type:KClass<T>): T {
    val obj = type.constructors.find { it.parameters.isEmpty() }?.call()!!
    for (field in type.members) {
        if (field.findAnnotation<CsByte>() != null)
            (field as KMutableProperty<*>).setter.call(obj, 9)
        if (field.findAnnotation<CsStruct>() != null)
            (field as KMutableProperty<*>).setter.call(obj, parseStructRecursively(field::class))
            //                                                                     ^^^^^^^^^^^^ wrong?
            // Inner::class works OK,  field::class fails because it does not have argumentless constructor.
    }
    return obj
}

inline fun <reified T : Any> parseReified (): T {
    return parseStructRecursively(T::class)
}

fun main() {
    var s1 = parseReified<Struct1>()
    println(s1.x == 9)
    println(s1.inner1.y == 9)
}




Aucun commentaire:

Enregistrer un commentaire