KSP can't find my annotated class, and when I ask ...
# ksp
v
KSP can't find my annotated class, and when I ask it to list all files, it says there are no annotations on any of the files. I'm stumped! Given:
Copy code
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.SOURCE)
annotation class APISchema

~~~
@Serializable
@APISchema
class DummyClass(val name: String, val age: Int)
Then my processor fails to find
DummyClass
, and it says that there are no annotations:
Copy code
override fun process(resolver: Resolver): List<KSAnnotated> {
        val schemaClasses = resolver.getSymbolsWithAnnotation(APISchema::class.qualifiedName!!, false)
            .filterIsInstance<APISchema>()
        if (!schemaClasses.iterator().hasNext()) {
            logger.warn("No classes found with @APISchema annotation")
        }
        resolver.getAllFiles().forEach { file ->
            logger.warn("Found file: ${file.fileName}")
            if(file.fileName == "DummyClass.kt") {
                logger.warn("Found DummyClass.kt")
                logger.warn(file.toString())
                file.annotations.forEach { annotation ->
                    logger.warn("Found annotation: ${annotation.shortName}")
                }
            }
        }
}
The logs show:
Copy code
w: [ksp] No classes found with @APISchema annotation
...
w: [ksp] Found file: DummyClass.kt
w: [ksp] Found DummyClass.kt
w: [ksp] File: DummyClass.kt      <-- I'd expect the file.annotations.forEach {} to list "@APISchema" and "Serializable" here!
w: [ksp] Found file: Authorizer.kt
...
d
The symbols you get from
Copy code
resolver.getSymbolsWithAnnotation(APISchema::class.qualifiedName!!, false)
will never be of type
ApiSchema
. So the
filterIsInstance
call in the code sample will always ensure the sequence is empty. I think what you are looking for is something like:
filterIsInstance<KSClassDeclaration>()
This KSP-eye view of things takes a while to get used to and it's worth setting breakpoints and using the debugger to see what's going on
👍 2
v
Morning! Yes, I now see that I was calling
getSymbolsWithAnnotation
incorrectly. And it seems my
resolver.getAllFiles().forEach {}
was not going to be useful either. Now I just need to write the information I get from the KClassDeclaration into a plain text file, ideally into /src/main/resources...
Slightly afraid of what I've done, some horrid alchemy of KSP and gradle... But I can now scan module A for classes with an annotation, build a yaml file describing these, copy that file into the resources of module B, which reads the yaml file at runtime. Compile-time reflection across modules to get class definitions at runtime...