当前位置: 首页 > 知识库问答 >
问题:

当处理器依赖于注释值中的类时,选择Gradle增量注释处理器类别

乜建柏
2023-03-14

我有一个简单的注释处理器,应用如下:

@DiffElement(diffReceiver = Renderer.class)
class ViewState {
  String getHello();
  int getWorld();
}

class Renderer {
  void renderHello(String hello);
  void renderWorld(int world);
}

要使此处理器工作,get-函数的名称和渲染器-接口函数参数必须匹配。它检查此并使用注释的参数来查看提供的类并在此基础上进行一些代码生成。

它生成一个文件。

我已经阅读了关于增量注释处理的文档,但是我不能决定将哪一个类别应用到这个处理器上。以下是我的考虑:

    < li >它不能是< code>isolating,因为它并不从带注释的元素的AST中派生所有内容,因为它也从注释参数中检查类 < li >它不能是< code > aggregate ,因为它在< code>Renderer类上没有任何注释,所以根据上面的文档,每当< code>Renderer类更改时都不会调用processor,因为processor尚未注册来处理该文件,所以这将导致生成的结果出错。

问题:

  • 我对留档的理解正确吗?或者某些类别仍然可以应用于此处理器
  • 如果它不属于任何一类,我怎么能告诉Gradle它不是增量,所以像“kotlin kapt”这样的工具不会向用户抱怨我的处理器不是增量

共有2个答案

厍光霁
2023-03-14

它不能聚合,因为它在 Renderer 类上没有任何注释,因此根据上面的文档,每当 Renderer 类更改时,都不会调用处理器,因为处理器尚未注册以处理此文件,因此这将导致生成结果中的错误。

这并不是一个直接的答案,但我认为它仍然可以回答你的问题:根据我的理解,这句话是你问题的真正根源。在这里,任何轻微的增量系统都会让您失望,而不仅仅是Gradle的“聚合”模式(例如,尝试在简单的Eclipse项目中使用您的处理器,甚至可能是IntelliJ,尽管我在那里得到了混合结果)。

如果您确实希望强制执行对未注释类型的更改将导致注释处理器再次运行,则不得将注释处理器限制为该注释,但必须从getSupportedAnnotationTypes()返回神奇的“*”,指示任何更改的类都必须触发处理器重新运行。从该方法的Javadoc:

最后,“*”本身代表所有注释类型的集合,包括空集。请注意,处理器不应声明“*”,除非它实际上正在处理所有文件;声明不必要的注释可能会导致某些环境中的性能下降。

理想情况下,您只需进行第二个(或第三个等)注释来提供此提示,但这并不总是可行的,这就是为什么您可以使用此通配符选项的原因

闻人志
2023-03-14

我是否正确理解文档?或者某些类别仍可应用于此处理器

在我看来,关于处理器类别的文档确实很短,而且缺少例子。我花了很多时间来理解这些文件,为实验建立一些简单的项目。所以,据我所知,一个类别是可以应用的,如果我最后确实把它们搞对了:)

你说

它不能是隔离的,因为它不会从带注释元素的AST派生所有内容,因为它还会从注释参数检查类

这不完全正确,我将解释原因。如留档中所述,隔离处理器

必须根据可从AST访问的信息为带注释的类型做出所有决策(html" target="_blank">代码生成、验证消息)。这意味着您可以分析类型的超类、方法返回类型、注释等,甚至是瞬态的。

“甚至传递性”短语在这里非常重要-这意味着,您不仅可以分析带注释类型的AST,还可以分析一些方法的返回类型AST,然后,比如说,该类型的超类。。。

据我所知,您可以通过AST遍历从带注释的元素中发现的每种类型都是带注释的类型(或一般的元素)的依赖项。如果一个依赖关系改变了,那么依赖类型需要重新编译。因此,当< code>Renderer类发生更改时,< code>ViewState将被重新编译并重新处理,因为它引用< code>Renderer作为其批注参数。超类型、超接口、方法的返回类型、方法参数的类型、注释类参数,...-所有这些都被视为依赖类型。

因此,注释处理器实际上可以隔离。

附言:如果隔离不起作用,请确保注释保留率为 CLASS 或更高,无论出于何种原因。

P、 附言:我发现注释处理中的增量是一个非常阴暗的话题,充满了惊喜和水下岩石。我自己发现的经验法则是,几乎每一个处理器只要稍加调整就可以隔离,除非它真的需要基于许多输入生成一个实体。而且,重要的是,只有这些输入在引用方面完全不相关,甚至在不同的库中。

 类似资料:
  • 我正在使用gradle/querydsl和JPA 2.1。 我想使用APT(qenties)生成querydsl元数据。 为此,我使用了gradle apt插件和gradle 4.7 在我的项目中,我使用以下配置了compileJava选项:

  • 我正在使用注释处理器来处理方法参数的注释。 用于参数的注释类型有一个注释@参数 现在,当注释处理器运行时,我想检查参数注释()是否有参数注释。我通过执行以下代码来实现这一点。 由于某种原因,arg始终为空。是否有注释未返回的原因?

  • 我有下面的课程。两个注释(AnnotA和AnnotB),一个类的子类。java'(带@AnnotA)及其“父”基。java'(带有@AnnotB)。 编译子对象时。java,我的注释处理器报告AnnotA,但它不报告在Base中找到的注释(AnnotB)。JAVA 安诺塔。JAVA 阿诺特。JAVA 基础JAVA 小孩JAVA MyProc。JAVA 这是编译过程及其输出,正如您所看到的,没有关于

  • 需要注释处理器的帮助。我创建了一个简单的注释处理器,它使用@autoservice注释来检查注释的字段是否为最终字段。但它没有显示任何编译时错误。这是我的配置 注释: 注释处理器: pom文件: 测试文件:

  • null 我的git和Gradle技能是初学者水平。我将非常感谢对这项任务的任何帮助。谢谢你。

  • 我在编译使用我的注释处理器的代码时收到以下错误: 关于如何调试这个有什么提示吗?错误输出根本没有用处。有没有办法得到更详细的错误?