#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";
}
}
}