Marked
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class Marked()
Model
class Model() {
@Marked
protected val content: String
get() {
return ""
}
}
Reflection
internal fun <T, R> KProperty1<T, R>.getValue(from: Any, forced: Boolean = false): Any? {
if (forced)
isAccessible = true
javaField?.let { return it.get(from) }
javaGetter?.let { return it.invoke(from) }
return null
}
internal fun getAllMarked(from: Any): Map<String, Any?> {
val map = mutableMapOf<String, Any?>()
from::class.memberProperties.forEach {
val annotation = it.findAnnotation<Marked>() ?: return@forEach
val name = it.name
it.getValue(from, true).let {
map.put(name, it)
}
}
return map
}
Log
kotlin.KotlinNullPointerException
at kotlin.reflect.jvm.internal.KPropertyImplKt.computeCallerForAccessor(KPropertyImpl.kt:243)
at kotlin.reflect.jvm.internal.KPropertyImplKt.access$computeCallerForAccessor(KPropertyImpl.kt:1)
at kotlin.reflect.jvm.internal.KPropertyImpl$Getter$caller$2.invoke(KPropertyImpl.kt:157)
at kotlin.reflect.jvm.internal.KPropertyImpl$Getter$caller$2.invoke(KPropertyImpl.kt:148)
at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:93)
at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32)
at kotlin.reflect.jvm.internal.KPropertyImpl$Getter.getCaller(KPropertyImpl.kt)
at kotlin.reflect.jvm.ReflectJvmMapping.getJavaMethod(ReflectJvmMapping.kt:62)
at kotlin.reflect.jvm.ReflectJvmMapping.getJavaGetter(ReflectJvmMapping.kt:47)
at kotlin.reflect.jvm.KCallablesJvm.setAccessible(KCallablesJvm.kt:70)
at io.joshuaavalon.dashboard.util.KPropertyExtensionKt.getValue(KPropertyExtension.kt:10)
It works fine if it is a normal value like val a = 1
. However, reflection does not seems to account for getter without delegate field.