我想编写一个注释处理器,它根据已处理类型的JavaBeans属性集生成源代码。
这一般都有效,但如果有其他注释处理器,我正在努力做到这一点。具体来说,这样的其他处理器可以为我的处理器处理的类型生成超类,因此我也需要考虑该超类型的属性。在随后的回合中,可能会生成超类的超类等等。
这意味着我不能生成我的源代码,直到我感兴趣的类型的层次结构稳定,即在后续轮次中不会生成更多的超类型(或者在我的处理器运行后的同一轮中)由其他处理者。
我怎么能知道是否是这种情况?我知道RoundEnvironment#processingOver()
以及在最后一轮中生成我的代码的可能性,但我理解这是一个不好的做法(编译器会发出警告)。
答案 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%肯定,但它们可能值得一试。