使用 ANTLR4 解析 java 文件时,如何保存方法名称和在该方法中调用的所有方法的名称?

How to save a method name and names of all methods called inside that method when parsing a java file with ANTLR4?

我正在开发一个程序,该程序使用来自 ANTLR github 的 Java9 词法分析器和语法来解析 Java 文件。解析文件时,我想将每个方法名称和在该方法中调用的所有方法的名称保存在 HashMap<String, Set<String>>.

我使用侦听器模式,其中我使用方法 exitMethodDeclaration 获取方法名称,使用 exitMethodInvocation 获取方法调用。问题在于这两个方法是在解析树的不同节点上调用的,因此它们将不同的上下文作为参数。因此,据我所知,我无法调用该方法来获取 exitMethodDeclaration 中的调用。我试图构建自己的递归,这样我就可以通过将 methodDeclarationContext 作为参数传递给 exitMethodInvocation 来解决类型问题。不过这会非常复杂,我想使用 ANTLR 的功能。

使用下面的代码,每个方法的 hashSet 包含 整个 文件的所有方法调用,而不仅仅是特定方法。

private HashMap<String, HashSet<String>> methodCalls = new HashMap<>();
private HashSet<String> methodCallNames = new HashSet<>();

public void exitMethodDeclaration(Java9Parser.MethodDeclarationContext ctx) {
        String methodName = ctx.methodHeader().methodDeclarator().identifier().getText();
        methodCalls.put(methodName, methodCallNames);
    }

public void exitMethodInvocation(Java9Parser.MethodInvocationContext ctx) {
    try {
        String m = ctx.methodName().identifier().getText();
        methodCallNames.add(m);
    } catch (Exception e) {
    }
}

非常欢迎任何关于如何在同一方法内收集不同上下文类型的节点、访问 listener/visitor 方法内的子树或其他想法的想法!

您可以创建一个 ArrayList 堆栈。

每次,您 enterMethodDeclaration,将一个新的空 ArrayList 推入您的堆栈。

每次 enterMethodInvocation(或 exit...,如果您愿意),您可以将 methodName 添加到您在 stack.peek() 上的 ArrayList。

每当您 exitMethodDeclartation stack.pop() ArrayList 时,它都会列出您在该方法调用中直接遇到的所有方法名称。而且,方法名称就在 exitMethodDeclaration

的 Context 参数中