确定Java注释处理器中类型的稳定性

时间:2015-12-14 09:33:58

标签: java annotations annotation-processing

我想编写一个注释处理器,它根据已处理类型的JavaBeans属性集生成源代码。

这一般都有效,但如果有其他注释处理器,我正在努力做到这一点。具体来说,这样的其他处理器可以为我的处理器处理的类型生成超类,因此我也需要考虑该超类型的属性。在随后的回合中,可能会生成超类的超类等等。

这意味着我不能生成我的源代码,直到我感兴趣的类型的层次结构稳定,即在后续轮次中不会生成更多的超类型(或者在我的处理器运行后的同一轮中)由其他处理者。

我怎么能知道是否是这种情况?我知道RoundEnvironment#processingOver()以及在最后一轮中生成我的代码的可能性,但我理解这是一个不好的做法(编译器会发出警告)。

2 个答案:

答案 0 :(得分:3)

回答我自己的问题:

如果注释类型的所有超类型都是非错误的,则可以认为它是稳定的或完整的。一个例子:

@GenClass("Base")
class MyAnnotatedType extends Base {}

假设@GenBase有一个注释处理器A,在这种情况下生成指定的类Base。并且另一个处理器B对MyAnnotatedType的层次结构感兴趣,例如,它希望为所有MyAnnotatedType方法生成某种描述符,包括继承的方法。

如果B在A之前运行,则Base类将不存在,因此当B检查MyAnnotatedType的层次结构时,超类类型镜像将具有类型ERROR。 B可以将此作为指示将MyAnnotatedType的处理推迟到后一轮。

当A运行时,它将生成Base类,从而导致另一轮处理。

如果现在B第二次运行,它可以处理从上一轮延期的所有类型。现在Base存在,它将不再具有类型ERROR。为此,我注意到(使用javac)重要的是获得表示类型的新Element并且不保留第一轮中仍然包含对错误超类型的引用的那个。

如果Base本身没有错误的超类型,则MyAnnotatedType的层次结构已完成,B可以继续处理它。否则,将再次延迟处理,直到层次结构最终完成。如果永远不会生成超类型,那么编译最终会出现错误,对于B,在这种情况下也应该没有生成代码。

答案 1 :(得分:-1)

当您说要基于JavaBeans属性集触发源生成时,我假设您指的是getter / setter对,无论如何这不是您的问题的主题。

通常不会制作JSR 269规范,以便可以协调多个注释处理器。这是设计使然,所有处理器都应该是幂等的(意思是相同的条目 - >相同的输出)。

所以像"我不能生成我的源代码,直到类型的层次结构稳定" 在没有黑客法律程序的情况下无法实现。检测稳定性是javac的责任。

禁止在最后一轮生成代码,因为最后一轮的唯一目的是让处理器释放未发布的资源。如果其他处理器做同样的事情,你就有危险!这对我来说是不行的。

我能想到的唯一可行解决方案是声明您的处理器正在处理所有注释(可以通过指定" *" 来处理注解)。我不确定这是否会阻止必须验证的其他处理器。但如果可行,则每次生成新文件时都会调用处理器。然后你会正常处理它们,并且javac会正常检测到收敛事物。

我对这些解决方案并不是100%肯定,但它们可能值得一试。