为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕妹3146593 2023-07-19 15:33:39
我有一个简单的注释处理器,其应用如下:@DiffElement(diffReceiver = Renderer.class)class ViewState {  String getHello();  int getWorld();}class Renderer {  void renderHello(String hello);  void renderWorld(int world);}为了使该处理器工作,get-functions 和Renderer-interface 函数参数的名称必须匹配。它检查这一点并使用注释的参数来查看提供的类并基于该类进行一些代码生成。它生成一个文件。我已阅读有关增量注释处理的文档,但我无法决定应用于该处理器的类别。以下是我的考虑:它不可能isolating,因为它不会从带注释的元素的 AST 派生所有内容,因为它还从注释参数检查类不可能aggregating,因为它在类上没有任何注释Renderer,所以根据上面的文档,每当类发生变化时,处理器都不会被调用Renderer,因为处理器还没有注册来处理这个文件,所以这会导致生成结果中的错误。问题:我正确理解文档吗?或者某些类别是否仍适用于该处理器如果它不属于任一类别,我如何告诉 Gradle 它不是增量的,因此像“kotlin kapt”这样的工具不会向用户抱怨我的处理器不是增量的
查看完整描述

2 回答

?
慕容森

TA贡献1853条经验 获得超18个赞

我正确理解文档吗?或者某些类别是否仍适用于该处理器

关于处理器类别的文档非常简短,而且在我看来,缺乏示例。我花了很多时间来弄清楚这些文档,构建一些简单的实验项目。所以,据我所知,如果我最终正确地弄清楚了它们,就可以应用一个类别:)

你这么说

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

这并不完全正确,我将解释原因。正如文档中提到的,隔离处理器

必须根据可从其 AST 获取的信息为带注释的类型做出所有决策(代码生成、验证消息)。这意味着您可以分析类型的超类、方法返回类型、注释等,甚至是传递性的。

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

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

因此,您的注释处理器实际上可以隔离.


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

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


查看完整回答
反对 回复 2023-07-19
?
DIEA

TA贡献1820条经验 获得超2个赞

它不能聚合,因为它在 Renderer 类上没有任何注释,所以根据上面的文档,每当 Renderer 类发生变化时,处理器都不会被调用,因为处理器还没有注册来处理这个文件,所以这个将导致生成的结果出现错误。

这不会是一个直接的答案,但我认为它仍然可以回答您的问题:据我所知,这个陈述是您问题的实际根源。任何温和的增量系统都会让你失败,而不仅仅是 Gradle 的“聚合”模式(例如,尝试在一个简单的 Eclipse 项目中使用你的处理器,甚至可能是 IntelliJ,尽管我在那里得到了好坏参半的结果)。

如果您实际上想要强制对未注释类型的更改将导致注释处理器再次运行,则不得将注释处理器限制为该注释,但必须返回来自 的魔术值,指示任何更改的类都"*"必须getSupportedAnnotationTypes()触发处理器重新运行。来自此方法的 Javadoc:

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

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


查看完整回答
反对 回复 2023-07-19
  • 2 回答
  • 0 关注
  • 95 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信