https://kotlinlang.org logo
#ksp
Title
# ksp
l

Lamberto Basti

01/17/2023, 4:52 PM
Hello again! how do you get a
KClass
out from an annotation argument? Given the annotation:
Copy code
@Retention(AnnotationRetention.SOURCE)
@Target(AnnotationTarget.PROPERTY)
annotation class Reference(val table: KClass<out Table>, val columnName: String)

// usage
@Reference(MyTable::class, "id")
I am trying to preocess it with:
Copy code
val reference = kSPropertyDeclaration.getAnnotationsByType(Reference::class).first()
But when i access
reference.table
it errors with:
Copy code
[ksp] com.google.devtools.ksp.KSTypeNotPresentException: java.lang.ClassNotFoundException: com.github.lamba92.ktor.restrepositories.tests.Cities
	at com.google.devtools.ksp.UtilsKt.asClass(utils.kt:509)
	at com.google.devtools.ksp.UtilsKt.createInvocationHandler$lambda$8(utils.kt:385)
	at jdk.proxy5/jdk.proxy5.$Proxy29.table(Unknown Source)
I believe the returned class has some kind of lazy behaviour because it errors only when accessing
table
, but it is kinda weird. Also,
com.github.lamba92.ktor.restrepositories.tests.Cities
is one of the source files.
It apperas to be this issue here
j

jw

01/17/2023, 5:06 PM
KSP is running on the JVM with the compiler classpath. You cannot load classes which are in the code that is being compiled.
Any type references in the code that is being compiled need to be held as symbolic references. If you try to load them in the current classloader it almost certainly will fail.
l

Lamberto Basti

01/17/2023, 5:09 PM
Uhm I see. And is there a way to just get the fqn of the class written in the annotation parameter?
j

jw

01/17/2023, 5:12 PM
I haven't used KSP but it looks like maybe KSType is what you want
if the
declaration
is a
KSClassDecalaration
it'll have
qualifiedName
l

Lamberto Basti

01/17/2023, 5:29 PM
Indeed, but there was some magic involved:
Copy code
propertyDeclaration.annotations
    .firstOrNull { 
        it.annotationType.resolve().toClassName() == Reference::class.asClassName()     
    }
    ?.arguments
    ?.first()
    ?.value // <-- this is type Any?
    ?.let { it as? KSType }
    ?.declaration
    ?.qualifiedName
    ?.asString()
So basically, somehow, automagically, the KSP runtime fills
value
with a
KSType
. I had to print out quite some stuff before figuring that out!
j

Jiaxiang

01/17/2023, 6:25 PM
yeah, when dealing with
KClass
as class literals, KSP will try to convert it to
KSType
, we should probably note it in documents.
134 Views