起因
因为在开发的 grails swagger 插件需要能自动从注释中读取信息,作为字段的描述信息来使用,所以需要能读取到 Groovy、Java 类的注释。
过程
通过研究 Groovy 的编译阶段,用 GroovyConsole 查看各个阶段生成的数据,发现 Groovy 2 的 AST 中没有“注释”。
于是在 Groovy 的user邮件列表中询问了一下,等待高手指点。
Groovy3 的解析器Parrat是由孙岚主导开发的一款 Groovy 语法解析器,功能强大,且文档说 Node Tree 中包含了注释信息,但是可惜的是 Grails 必须使用 Groovy2.5 。没有试过 Grails4 + Groovy3 是否能正常工作。
另外还发现了一个 SO 提到了如何解析 Groovy 代码,以及其中的注释,值得研究一下。
SimpleGroovyClassDocAssembler 的 getJavaDocCommentsBeforeNode() 方法思路是 “从两个代码 node 之间的文本获取注释信息”
所以看看能不能重用这些代码来实现这个功能。
继续看代码,可以用 org.codehaus.groovy.antlr.SourceBuffer#getSnippet() 来读取指定位置区域的内容,这个比较接近了,只要能从 AST Transformer 的 SourceUnit 中获取到这个对象就能用。
最终实现
成功实现了抽取 Groovy/Java 注解内容,思路如下:
1、对于 Groovy2.5,用 FieldNode 的 lineNumber、columnNumber、lastLineNumber、lastColumnNumber 属性定位注解的开始位置,然后定位上一个 FieldNode 或者 MethodNode,这之间的内容抽取出来后,解析
/** */
注解块,或者 "// "注解行。
如果本 FieldNode 前面没有其他 FieldNode 或者 MethodNode 了则用规则查找
/* 或者 */
如果遇到 { } 符号则结束读取注解的过程。
2、对于 Groovy 3 可以从 Groovy AST 的 node 中的 meta 属性获取注释信息,但没尝试,不知道具体情况。