如何使用JavaParser知道一个变量是被读取还是被修改。

huangapple go评论67阅读模式
英文:

How know a variable is read or modified using JavaParser

问题

我正在使用JavaParser来解析Java应用程序。我需要一个函数来返回方法体中的变量被读取或修改的次数。例如,对于下面的代码,该函数应该确定下面代码中的变量x被读取了两次并且被修改了一次。

private int foo(){
  int x;
  System.out.println(x); //读取
  x = 10; //修改
  bar(x); //读取
}

到目前为止,我编写了以下代码。

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时最好地实现这一点。

英文:

I am using JavaParser to parse Java applications. I need a function to return the number of cases that a variable in a method body is read or modified. As an example, the function should determines variable x in the below code is read two times and one time is modified.

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

so far I wrote this code.

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());
					}
				}
			}
		});
	}
}

Using this code I can know the variable x is used three times in the method body, but I can not distinguish between read and write. Let me know what is the best way to do this using JavaParser.

答案1

得分: 0

我能够使用下面的代码解决这个问题:

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();
					
		//注意,此代码未涵盖arrayAccessExp
		if (target.isNameExpr()) {
			if (target.asNameExpr().getNameAsString().equals(variableName)) 
					type = "Write";
		}
	}
}
英文:

I was able to solve the question using the code below:

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

huangapple
  • 本文由 发表于 2020年9月1日 21:14:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/63688429.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定