Kotlin函数注解处理器无法识别注解函数的问题求助
我看了你贴的代码,马上发现几个关键问题导致处理器识别不到注解的函数,一个个给你拆解:
1. 元素筛选API完全用错了
你现在用ElementFilter.typesIn(annotatedElements)来筛选元素,但typesIn是专门找**类/接口这类TypeElement**的,而你的注解是打在函数(METHOD)上的,函数对应的元素类型是ExecutableElement,这一步直接把所有注解的函数都过滤掉了,自然得到空列表。
应该改成用ElementFilter.methodsIn(annotatedElements)来筛选方法元素,而且不需要强行转成TypeElement,直接处理ExecutableElement就行。
2. 变量名笔误导致逻辑异常
你代码里写的是:
val types = mutableListOf<TypeElement>().apply { addAll(ElementFilter.typesIn(annotatedElement)) }
这里的annotatedElement是笔误,应该是annotatedElements(多了个s),这个笔误也会直接导致你拿到的元素列表为空。
3. 类型判断的方法参数完全错误
你的isValidFunction方法接收的是TypeElement,但TypeElement代表的是类、接口这类类型元素,永远不可能是方法类型。你在方法里判断elem.kind != ElementKind.METHOD,这个条件永远为真,会一直输出错误日志并返回false。
应该把方法参数改成ExecutableElement(或者更通用的Element),因为函数对应的元素就是ExecutableElement。
4. 拼写错误的低级问题
isValidFunction的返回类型你写成了Bolean,正确的是Boolean,这个拼写错误会导致处理器编译失败,不过你说能运行到打印日志,可能是贴代码时的笔误,但还是要注意。
修正后的核心代码参考
把process方法和isValidFunction改成这样就能正常识别了:
class Processor: AbstractProcessor() { override fun getSupportedAnnotationTypes() = mutableSetOf(NavigationDestination::class.java.canonicalName) override fun process(p0: MutableSet<out TypeElement>?, p1: RoundEnvironment): Boolean { println("Starting the processor") val annotatedElements = p1.getElementsAnnotatedWith(NavigationDestination::class.java) // 筛选出所有被注解的方法元素 val annotatedMethods = ElementFilter.methodsIn(annotatedElements) println("How many elements are there? ${annotatedMethods.size}") val itemsToProcess = mutableListOf<ExecutableElement>().apply { addAll(annotatedMethods.filter { isValidFunction(it) }) } println("itemsToProcess.size: ${itemsToProcess.size}") if(itemsToProcess.isNotEmpty()) { // 现在可以正常进入这里做代码生成了 } return true } private fun isValidFunction(elem: ExecutableElement): Boolean { // 其实已经用ElementFilter.methodsIn筛选过了,这里可以做更细的校验(比如函数参数、返回值等) if(elem.kind != ElementKind.METHOD) { processingEnv.messager.printMessage(Diagnostic.Kind.Error, "Only functions allowed") return false } return true } }
额外小建议
用processingEnv.messager打印日志比println更靠谱,因为println的输出在kapt构建中可能被吞掉,比如换成:
processingEnv.messager.printMessage(Diagnostic.Kind.NOTE, "Starting the processor")
这样能在Build窗口稳定看到日志输出。
内容来源于stack exchange

