我使用ANTLR 4.2来解析Java源文件。
我的目标是在类中定位具有特定注释的方法。
我面临的问题是Java.g4语法不包含annotation
规则作为methodDeclaration
规则的一部分(这是有意义的),这意味着它不能直接用于当我覆盖enterMethodDeclaration
的{{1}}时,我来自上下文对象:
JavaBaseListener
到目前为止,我唯一的想法是获取令牌流并尝试从方法声明上下文的位置向后遍历它。问题在于它非常麻烦(方法的注释可能在修饰符之前,在修饰符之后,即如果修饰符实际存在)并且我觉得它缺少了侦听器/访问者方法的点。 / p>
是否有一种干净的方法来获取方法的注释?
答案 0 :(得分:2)
不要试图遍历 up 解析树,而是考虑下去。您可以从classBodyDeclaration
制作开始,检查是否可以进入memberDeclaration
并从那里进入methodDeclaration
。如果是这样,你知道你现在正在使用某种方法。然后,只需遍历modifier
中的classBodyDeclaration
列表即可找到注释。
快速演示:
public class Main {
public static void main(String[] args) throws Exception {
String input = "@Annotation(\"class\")\n" +
"class Mu {\n" +
"\n" +
" @Annotation(\"field\")\n" +
" int x;\n" +
" \n" +
" @Annotation(\"method\")\n" +
" void withAnnotation(){}\n" +
" \n" +
" void withoutAnnotation(){}\n" +
"}";
JavaLexer lexer = new JavaLexer(new ANTLRInputStream(input));
JavaParser parser = new JavaParser(new CommonTokenStream(lexer));
// classBodyDeclaration
// : ...
// | modifier* memberDeclaration
// ;
//
// memberDeclaration
// : methodDeclaration
// | ...
// ;
//
// methodDeclaration
// : (type|'void') Identifier formalParameters ...
// ;
//
// modifier
// : classOrInterfaceModifier
// | ...
// ;
//
// classOrInterfaceModifier
// : annotation
// | ...
// ;
ParseTreeWalker.DEFAULT.walk(new JavaBaseListener(){
@Override
public void enterClassBodyDeclaration(@NotNull JavaParser.ClassBodyDeclarationContext ctx) {
if (!(ctx.memberDeclaration() != null && ctx.memberDeclaration().methodDeclaration() != null)) {
// No method declaration.
return;
}
String methodName = ctx.memberDeclaration().methodDeclaration().Identifier().getText();
for (JavaParser.ModifierContext mctx : ctx.modifier()) {
if (mctx.classOrInterfaceModifier() != null && mctx.classOrInterfaceModifier().annotation() != null) {
System.out.println(methodName + " -> " + mctx.classOrInterfaceModifier().annotation().getText());
}
}
}
}, parser.compilationUnit());
}
}
打印:
withAnnotation -> @Annotation("method")