使用 ANTLR 在 Java 源代码中查找变量 usage/reference?

Use ANTLR to find Variable usage/reference in Java source-code?

变量的使用基本上是变量声明后在同一范围内的每次出现,其中可能对其应用了一些操作。某些 IDE 甚至支持变量用法突出显示,例如 IntelliJEclipse.

我想知道是否有办法使用 ANTLR 查找变量用法?我已经通过 [=] 生成了 LexerParserBaseListener classes 39=] Java8.g4 上的 ANTLR。我可以找到变量声明,但无法在给定的 Java 源代码中找到变量用法。我该怎么做?

示例:

int i;    // Variable declaration
i++;      // Variable usage
i = 2;    // Variable usage
foo(i);   // Variable 'i' usage

我可以使用 Listener class 捕获声明但不能捕获用法。我在这里解析 Java 源代码。

我假设您只考虑 local 变量。

你需要 scopesresolving 才能做到这一点。

Scope 将代表 Java 的变量范围。它将保存有关在给定范围内声明了哪些变量的信息。您必须在进入 Java 作用域(块开始、方法等)时创建它,并在离开作用域时将其删除。您将保留一堆作用域来表示嵌套块/作用域(Java 不允许在嵌套作用域中隐藏局部变量,但您仍然需要跟踪变量何时超出作用域嵌套范围)。

然后您需要解析 您在解析输入中遇到的每个名称 - 确定名称是否指代变量(使用范围)。基本上,它指的是一个局部变量,只要它是名称的第一部分(在任何.之前),后面没有(并且匹配局部变量的名称。

解析器无法为您执行此操作,因为名称是否引用变量取决于可用变量:

private static class A {
    B out = new B();
}

private static class B {
    void println(String foo) {
        System.out.println("ha");
    }
}

public static void main(String[] args) {
    {
        A System = new A();
        System.out.println("a");
    }
    System.out.println("b");
}

ha
b


如果您还考虑实例和静态字段而不仅仅是局部变量,解析部分会变得更加复杂,因为您需要考虑当前 class 中的所有 classes ]' 层次结构、它们的实例和静态字段、可见性等,以确定给定名称的变量是否存在和可见。