Как узнать, что переменная прочитана или изменена с помощью JavaParser

#java #javaparser

#java #javaparser

Вопрос:

Я использую JavaParser для анализа приложений Java. Мне нужна функция для возврата количества случаев, когда переменная в теле метода считывается или изменяется. В качестве примера функция должна определить, что переменная x в приведенном ниже коде считывается два раза и один раз изменяется.

 private int foo(){
  int x;
  System.out.println(x); //Read
  x = 10; //modify
  bar(x); //read
}
  

до сих пор я писал этот код.

 for (ClassOrInterfaceDeclaration cd : cu.findAll(ClassOrInterfaceDeclaration.class)) {
                
    for (MethodDeclaration method : cd.getMethods()) {
                    
        method.getBody().ifPresent(blockStatement -> {
                    
            for( VariableDeclarator variable : blockStatement.findAll(VariableDeclarator.class)) {

                for (NameExpr nameExp : blockStatement.findAll(NameExpr.class)) {
                            
                    if (nameExp.getNameAsString().equals(variable.getNameAsString())) {
                        System.out.println(nameExp.getNameAsString());
                    }
                }
            }
        });
    }
}
  

Используя этот код, я могу узнать, что переменная x используется три раза в теле метода, но я не могу отличить чтение от записи. Дайте мне знать, какой наилучший способ сделать это с помощью JavaParser.

Комментарии:

1. Вы смотрите внутрь VariableDeclarator . Если вы вызываете getName() это и сравниваете с переменной, разве это не должно быть assingment (запись)?

2. Как я должен знать, что это назначение? не могли бы вы опубликовать пример кода. isAssignExpr() метод не работает NameExpr .

Ответ №1:

Я смог решить вопрос, используя приведенный ниже код:

 for (NameExpr nameExpr : callingMethod.findAll(NameExpr.class)) {

    ResolvedValueDeclaration calledVariable = nameExpr.resolve();

    String variableName = calledVariable.getName();
    String variableType = calledVariable.getType().describe();
                
    String type = "Read";

    Node parentNode = nameExpr.getParentNode().get();
    if (parentNode instanceof AssignExpr) {
                    
        Expression target = ((AssignExpr)parentNode).getTarget();
                    
        //Note that arrayAccessExp is not covered in this code
        if (target.isNameExpr()) {
            if (target.asNameExpr().getNameAsString().equals(variableName)) 
                    type = "Write";
        }
    }
}