识别 Statement/Line 中使用的变量

Identify Variables used in a Statement/Line

给定一个方法,我想识别未使用的变量。 我目前正在查看的格式保证每个方法的最后一行都有一个 assert 语句。

我正在使用 JavaParser 来解析每个方法,列出语句并列出该方法中使用的所有变量。

如何检索最后一条语句中使用的所有变量?

private static class MethodVisitor extends VoidVisitorAdapter<Object> {

    @Override
    public void visit(MethodDeclaration n, Object arg) {
        System.out.println("Method: " + n.getName());

        BlockStmt body = n.getBody();
        List<Statement> statements = body.getStmts();

        new VariableVisitor().visit(n, null);

        Statement lastStmt = statements.get(statements.size() - 1);

        for (Statement st : statements) {
            System.out.println("Statement: " + st.toString());
        }
        System.out.println("\n\n");
    }
}

private static class VariableVisitor extends VoidVisitorAdapter<Object> {
    @Override
    public void visit(VariableDeclarationExpr n, Object arg) {
        List<VariableDeclarator> myVars = n.getVars();
        for (VariableDeclarator vars : myVars) {
            System.out.println("Variable Name: " + vars.getId().getName());
        }
        System.out.println();
    }
}

您可以获得不同的方法:

  1. 您只需获取方法的主体并递归地让所有子项找到所有 NameExpr,然后检查名称是否对应于某些变量并将其标记为已使用
  2. 您使用 JavaSymbolSolver 为您找到指向
  3. 的 NameExpr

现在,第一个 1 的问题是它并不总是给你正确的答案。为什么?因为你可以将其他东西命名为你的变量并且你没有区分这种情况的逻辑

例如:

void foo(int i) {
   int i;
   {
      int i;
      {
          int j = i;
      }
   }
}

这里我有不同的东西命名为 "i"。所以如果你想得到一个精确的答案,你需要在你的逻辑中考虑这一点。 JavaParser 不知道哪些名称指的是什么,因为它会生成一个抽象语法树。名称解析是稍后发生的事情,它不是 JavaParser 的一部分。

不过,名称解析是 JavaSymbolSolver 的一部分。您可以考虑使用 JavaParser 的这个扩展来计算类型和解析符号。这意味着多了一个依赖,所以你需要考虑它是否是你想要的。

免责声明:我是 JavaParser 贡献者和 JavaSymbolSolver 的维护者