1

Учитывая метод, я хотел бы идентифицировать неиспользуемые переменные. Формат, который я просматриваю в настоящее время, гарантирует, что утверждение 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(); 
    } 
} 
+2

что я интересно: почему вы хотите, чтобы заново изобретать колесо? Есть инструменты, которые делают такую ​​проверку для вас. Черт, вы можете даже настроить javac, чтобы дать вам предупреждение о неиспользуемых переменных. Итак, зачем создавать собственное решение, которое всегда будет сопряжено с риском быть неполным? – GhostCat

ответ

3

Вы можете получить различные подходы по этому вопросу:

  1. Вы просто взять тело метода и рекурсивен получить все ребенок найти все NameExpr, а затем проверить, если имя соответствует некоторым переменным и пометить его как используется
  2. используется JavaSymbolSolver, который выясняет, для вас NameExpr к тому, что относится к

Теперь проблема с первым 1 I что он не всегда дает правильный ответ. Зачем? Потому что вы могли бы иметь другие вещи, названные в качестве переменной и не имеют логики различать такие случаи

Например:

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

Здесь у меня есть разные вещи, названные «я». Поэтому вам нужно будет учитывать это в своей логике, если вы хотите получить точный ответ. JavaParser не знает, какие имена относятся к тому, потому что он создает абстрактное синтаксическое дерево. Разрешение имен - это то, что происходит позже, и оно не является частью JavaParser.

Разрешение имен, однако, является частью JavaSymbolSolver. Вы можете использовать это расширение JavaParser, которое вычисляет типы и разрешает символы. Это означает наличие еще одной зависимости, поэтому вам нужно подумать над тем, что вы хотите в своем случае.

Отказ от ответственности: Я вкладчик JavaParser и из JavaSymbolSolver обслуживать этот