1

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

我正在使用 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();
    }
}
4

1 回答 1

3

你可以得到不同的方法:

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

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

例如:

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

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

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

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

于 2016-11-27T19:58:11.630 回答