如何使用AST(抽象语法树)解析器获取程序的每个方法声明中调用的方法的名称?到目前为止,我已经设法得到所有方法的名称'声明和被调用的方法的所有名称,但我想知道哪个方法调用哪些方法。例如,我希望方法m1
调用方法mA
和mB
,而方法m2
调用方法mC
和mD
等
[编辑2011年11月9日IDB,在原始问题的正文中抄写新手的延伸评论。我希望我已经正确地转录了它。我希望作者回来并在必要时进行修改]:
我的问题似乎是(Eclipse' s)MethodDeclaration api没有要调用的GetInvokedMethodName函数。这是我的代码:
public class MethodVisitor extends ASTVisitor {
List<MethodDeclaration> methods = new ArrayList<MethodDeclaration>();
@Override public boolean visit(MethodDeclaration node) {
methods.add(node);
return super.visit(node); }
public List<MethodDeclaration> getMethods()
{ return methods; }
List<MethodInvocation> methods1 = new ArrayList<MethodInvocation>();
@Override public boolean visit(MethodInvocation node)
{ methods1.add(node);
return super.visit(node); }
public List<MethodInvocation> getMethods1()
{ return methods1; }
}
...
for (MethodDeclaration method : visitor .getMethods())
{ System.out.println("Method name: " + method.getName()
+ " Return type: " + method.getReturnType2()
+ " Is constructor: " + method.isConstructor()
+ " Method invoked: " + ASTNode.METHOD_INVOCATION );
); }
for (MethodInvocation method1 : visitor .getMethods1())
{ System.out.println("Method name invoked: " + method1.getName() ); }
答案 0 :(得分:3)
我遇到了同样的问题。这是我的解决方案:
final HashMap<MethodDeclaration, ArrayList<MethodInvocation>> invocationsForMethods =
new HashMap<MethodDeclaration, ArrayList<MethodInvocation>>();
CompilationUnit cu = (CompilationUnit) ap.createAST(null);
cu.accept(new ASTVisitor() {
private MethodDeclaration activeMethod;
@Override
public boolean visit(MethodDeclaration node) {
activeMethod = node;
return super.visit(node);
}
@Override
public boolean visit(MethodInvocation node) {
if (invocationsForMethods.get(activeMethod) == null) {
invocationsForMethods.put(activeMethod, new ArrayList<MethodInvocation>());
}
invocationsForMethods.get(activeMethod).add(node);
return super.visit(node);
}
});
现在,可以要求invocationsForMethods.keySet()
获取所使用的AST
的所有方法声明,并且invocationsForMethods.get(key)
返回作为键给出的声明的所有方法调用。
答案 1 :(得分:2)
如果你想知道m1调用哪个特定方法mB(在你的大量类中所有名为“mB”的方法),你需要的不仅仅是AST。您需要一个完整的符号表,它将每个符号用法绑定到与其匹配的可能定义。
计算这样一个符号表的过程对于许多语言来说都很困难,对Java来说很难(但不像C ++那么糟糕)。有人必须编码在(本地)范围,继承,重载,隐含强制转换等方面如何查找标识符的规则,Java参考手册将其内容的很大一部分用于解释。你不想自己做这件事。
您真正需要的是一个完整的Java前端,它具有AST和相应的符号表,用于您要检查的每个方法。我认为,你可以从接口到(Sun?)Java编译器(我个人不知道如何做),Jikes编译器,Eclipse Java AST(?)模块以及工具等作为我们的Java Front End。另一种方法是处理类文件,其中包含JVM形式的方法调用,以及JVM指令都是利用符号表构建的advavntage。
如果你想计算m1调用mA调用mQ调用.... mZ,你需要一个愿意一次读取整个源代码库的工具。编译器不会为您执行此操作,但您可以使用Eclipse或我们的前端来执行此操作。