为了使您的注释处理器具有增量功能,您必须在 META-INF 中声明它,在
incremental.annotation.processors
文件中:
your.fully.qualified.annotation.processor.name,category
有三种选择注解处理器的类别:动态、隔离和聚合。
基本上在高层次上:
- 动态:当您的处理器只能在运行时决定是否增量
- 隔离:当您的处理器将与每个带有您注释的类型隔离地工作(一个输入对应一个或多个输出)
- 聚合:当您的处理器需要聚合几个输入(带有您的注释的类型)以生成一个或多个输出时
但是,每个类别都有您必须考虑的限制:
动态限制
他们必须使用Filer API生成文件。以其他方式编写文件将导致后续的静默失败,因为这些文件不会被正确清除。如果您的处理器这样做,则无法进行增量处理。
他们不能依赖于特定于编译器的API,例如com.sun.source.util.Trees。Gradle包装处理API,因此尝试转换为特定于编译器的类型将失败。如果您的处理器这样做,则无法进行增量处理,除非您有某种回退机制。
如果他们使用Filer#createResource,则location参数必须是StandardLocation中的以下值之一:CLASS_OUTPUT、SOURCE_OUTPUT或NATIVE_HEADER_OUTPUT。任何其他参数都将禁用增量处理。
他们必须基于从其AST可达的信息来做出所有决策(代码生成、验证消息)来注释类型。这意味着您可以分析类型的超类、方法返回类型、注释等,甚至是传递的。但是,您不能基于RoundEnvironment中的不相关元素做出决策。这样做会导致静默失败,因为稍后将重新编译太少的文件。如果处理器需要根据否则不相关的元素组合做出决策,请将其标记为“聚合”。
他们必须为使用Filer API生成的每个文件提供一个确切的起始元素。如果提供了零个或多个起始元素,则Gradle将重新编译所有源文件。
聚合限制
他们只能读取CLASS
或RUNTIME
保留注释
只有在用户传递-parameters
编译器参数时,才能读取参数名称。
摘自Gradle documentation
PS:对于动态内容,您还需要重写 getSupportedOptions()
方法来指定类别:隔离或聚合。有关更多详细信息,请参见 Gradle 文档。