Jakub Syty
03/28/2023, 1:57 PMannotation class MyAnnotation(val list: Array<OtherKnownAnnotation>)
. There is a interface called Annotation
that is Base interface implicitly implemented by all annotation interfaces.
. So i tried to do annotation class MyAnnotation(val list: Array<Annotation>)
. This unfortunately gives me an error Invalid type of annotation member
. Can i work around this? Anybody had a usecase like this?@MyAnnotation(list = [Single(binds = [UserType::class])])
. Is that even possible? 🙂Nicklas Jensen
03/28/2023, 3:31 PM@MyAnnotation
@Single(binds = [UserType::class])
Jakub Syty
03/28/2023, 3:35 PM@Single
works only on classes and not interfaces ;/@Single
to classes that cannot be create (so doing abstract class instead of interface results in an error from koin that it cannot create an instance of abstract class. So it's more like i need to defer the processing of the original annotation to the next step - after my implementation is generatedNicklas Jensen
03/28/2023, 6:36 PM@Single
and @Factory
from Koin?Jakub Syty
03/28/2023, 8:24 PMNicklas Jensen
03/29/2023, 4:54 AMJakub Syty
03/29/2023, 7:30 AMAnnotation
is the implicit interface of all annotations ;/Nicklas Jensen
03/29/2023, 8:01 AMMyAnnotation
annotation class MyAnnotation
You can introduce another annotation @Annotate
like this:
@Repeatable
annotation class Annotate(
val annotation: KClass<*>,
val members: Array<Member> = [],
)
And a third annotation e.g. Member
like this:
annotation class Member(
val name: String,
val value: String,
val types: Array<KClass<*>> = []
)
You can use it like this:
@MyAnnotation
@Annotate(
annotation = Single::class,
members = [
Member("binds", "[%T]", [UserType::class]),
]
)
interface FooBar
Then in your symbol processor you can find all types with your annotation @MyAnnotation
and find all that type's @Annotate
annotations, then, using KotlinPoet you can create an AnnotationSpec
like so:
fun Annotate.toAnnotationSpec(): AnnotationSpec {
val type = annotation.asClassName()
val builder = AnnotationSpec.builder(type)
members.forEach { builder.addMember("${it.name} = ${it.value}", *it.types) }
return builder.build()
}
By doing this you're asking your users to declare annotations in a way that's friendly to KSP and KotlinPoet, but it will definitely work 🙂Jakub Syty
03/29/2023, 8:21 AMNicklas Jensen
03/29/2023, 9:06 AM