我正在编写一个简短的程序,它扫描 Java 源文件并使用 ANTLR4
查找其中的所有方法。对于每个方法,我想检查它是否是测试方法,并且我想通过检查该方法是否具有 @Test
注释来做到这一点。
如何获取我正在访问的每个方法的注释列表?这是到目前为止我的源代码:
public static void main(String... args) throws IOException {
lexer = new JavaLexer(new ANTLRFileStream(sourceFile, "UTF-8"));
parser = new JavaParser(new CommonTokenStream(lexer));
ParseTree tree = parser.compilationUnit();
ParseTreeWalker walker = new ParseTreeWalker();
MyListener listener = new MyListener(printToFile);
walker.walk(listener, tree);
}
public static class MyListener extends JavaBaseListener {
@Override
public void enterMethodDeclaration(JavaParser.MethodDeclarationContext ctx) {
// Mark the method's boundaries and extract the method text
int begin_offset = ctx.start.getStartIndex();
int end_offset = ctx.stop.getStopIndex();
Interval interval = new Interval(begin_offset, end_offset);
String methodText = ctx.start.getInputStream().getText(interval);
// Get the list of annotations - how?
}
}
最佳答案
我将使用this Java grammar for antlr 。我正在研究内存,因为没有工具来测试我手头正在做的事情。阅读语法您可以快速了解到:
- 注释与规则注释相对应(哇),因此您可以在生成的树的 AnnotationContext 中找到它们。
- 注释链接到 classBodyDeclaration 规则中的类成员(例如方法)(修饰符可以是 classOrInterfaceModifier,也可以是注释)
在这种情况下,如果我们只有 MethodDeclarationContext,我们就无法获取注释。我们需要访问整棵树来找到对应的ClassBodyDeclarationContext。
现在我对听众并不熟悉。据我了解(而且不是很多),如果您需要在解析时工作,您应该使用它们。我宁愿只访问解析器生成的树。 ANTLR 应该为您创建一个名为 <your grammar name>ParserBaseVisitor
的访问者。您所要做的就是扩展此类并重写感兴趣节点的访问方法。
- 访问 ClassBodyDeclarationContext。为此,您必须覆盖
visitClassBodyDeclaration(ClassBodyDeclarationContext ctx)
. - 检查它是否是
ctx.memberDeclaration().methodDeclaration()
的方法。如果不是方法声明,则应为 null。否则它应该是一个 MethodDeclarationContext。 - 如果不是,您可能需要访问子节点(如果它是类声明)。如果您扩展由antlr生成的ParserBaseVisitor,请调用super,因为它正是它的作用。
- 如果它是一个方法,检索注释列表并用它做任何你想做的事情:-)
您应该能够像这样检索注释:
Set<AnnotationContext> annotations = new HashSet<AnnotationContext>();
for(ClassOrInterfaceModifier modifier: ctx.modifier()) {
if (modifier.classOrInterfaceModifier().annotation()) {
annotations.add(modifier.classOrInterfaceModifier().annotation());
}
}
关于java - 使用ANTLR4获取方法的注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32089350/