I have a function named collectCustomizerFunctions
which should create a MutableList<KCallable<*>>
of all the functions of a specified class and its sub-classes which are annotated with CustomizerFunction
.
Recursively, customizerFuns
(the MutableList<KCallable<*>>
) should have all of the "cutomizer functions" added to it.
When I try to build my Gradle project, it fails with two exceptions:
e: collectCustomizerFuns.kt:14:33 Type inference failed. The value of the type parameter T should be mentioned in input types (argument types, receiver type or expected type). Try to specify it explicitly.
e: collectCustomizerFuns.kt:21:30 Type mismatch: inferred type is Any but CapturedType(*) was expected
Here is my code:
3 | import kotlin.reflect.KClass
4 | import kotlin.reflect.KCallable
5 | import kotlin.reflect.full.allSuperclasses
6 |
7 | @Utility
8 | public tailrec fun <T: Any> collectCustomizerFuns(
9 | specClass: KClass<T>,
10 | customizerFuns: MutableList<KCallable<*>>
11 | ): Unit {
12 | // add annotated functions of this class
13 | for (member in specClass.members) {
14 | if (CustomizerFunction::class in member.annotations) { <--- ERROR
15 | customizerFuns.add(member)
16 | } else {}
17 | }
18 |
19 | // add annotated functions of all super-classes
20 | for (superclass in specClass.allSuperclasses) {
21 | collectCustomizerFuns<Any>(superclass, customizerFuns) <--- ERROR
22 | }
23 | }
I have been trying to fix these bugs for a while now, and would appreciate any help!
Also, please provide any constructive criticism you want regarding this function, it would help a lot!
For the first error, member.annotations
returns List<Annotation>
. You have to fetch actual classes of these annotations.
For the second error, remove the type where you call collectCustomizerFuns
. Let kotlin infers the type by itself :).
So try this:
public tailrec fun <T: Any> collectCustomizerFuns(
specClass: KClass<T>,
customizerFuns: MutableList<KCallable<*>>
) {
// add annotated functions of this class
for (member in specClass.members) {
if (CustomizerFunction::class in member.annotations.map { it.annotationClass }) {
customizerFuns.add(member)
} else {
}
}
// add annotated functions of all super-classes
for (superclass in specClass.allSuperclasses ) {
collectCustomizerFuns(superclass, customizerFuns)
}
}
By the way, you can remove Unit
from the method signature.