如何使我自己的注释处理器增量?

How to make my own annotation processor incremental?

我创建了一个名为 EasyPrefs 的注释处理器,当我尝试在我的项目中使用它时,它显示了以下警告。

Incremental annotation processing requested, but support is disabled because the following processors are not incremental: net.androidcart.easyprefs.EasyPrefsProcessor (NON_INCREMENTAL).

我做了一些研究,但找不到任何关于如何使其增量的教程。是否需要Gradle配置,或者需要覆盖某些功能等

要使您的注解处理器增量,您必须在 incremental.annotation.processors 文件的 META-INF 中声明它:

your.fully.qualified.annotation.processor.name,category

有三类注释处理器可供选择:动态、隔离和聚合。

基本处于高水平:

  • 动态:当你的处理器只能在运行时决定它是否是增量的
  • isolating:当你的处理器将单独处理用你的注释注释的每种类型时(一个输入一个或多个输出)
  • 聚合:当您的处理器需要聚合多个输入(用您的注释注释的类型)以产生一个或多个输出时

但是,每个类别都有您必须考虑的限制:

动态限制

  • They must generate their files using the Filer API. Writing files any other way will result in silent failures later on, as these files won’t be cleaned up correctly. If your processor does this, it cannot be incremental.

  • They must not depend on compiler-specific APIs like com.sun.source.util.Trees. Gradle wraps the processing APIs, so attempts to cast to compiler-specific types will fail. If your processor does this, it cannot be incremental, unless you have some fallback mechanism.

  • If they use Filer#createResource, the location argument must be one of these values from StandardLocation: CLASS_OUTPUT, SOURCE_OUTPUT, or NATIVE_HEADER_OUTPUT. Any other argument will disable incremental processing.

隔离限制

  • They must make all decisions (code generation, validation messages) for an annotated type based on information reachable from its AST. This means you can analyze the types' super-class, method return types, annotations etc., even transitively. But you cannot make decisions based on unrelated elements in the RoundEnvironment. Doing so will result in silent failures because too few files will be recompiled later. If your processor needs to make decisions based on a combination of otherwise unrelated elements, mark it as "aggregating" instead.

  • They must provide exactly one originating element for each file generated with the Filer API. If zero or many originating elements are provided, Gradle will recompile all source files.

聚合限制

  • They can only read CLASS or RUNTIME retention annotations

  • They can only read parameter names if the user passes the -parameters compiler argument.

来自Gradle documentation

PS:对于动态,您还必须覆盖 getSupportedOptions() 方法来指定类别:隔离或聚合。有关详细信息,请参阅 Gradle documentation