2011-11-09 61 views
4

如何使用AST(抽象語法樹)分析器獲取程序的每個方法聲明中調用的方法的名稱?到目前爲止,我已經設法獲得了方法聲明的所有名稱和被調用方法的所有名稱,但是我想知道哪個方法調用哪些方法。例如,我想看看m1調用方法mAmB該方法,而方法調用m2方法mCmD從AST獲取方法調用信息

[編輯11/9/2011 IDB,抄錄新手的擴展評論回來的身體原來的問題。我希望我已經正確地轉錄了它。我希望作者回來,並根據需要修改]:

我的問題似乎是(Eclipse的)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()); } 

回答

2

如果你想知道哪個(都命名爲「MB」在整個龐大的類數組的)具體方法MB內存由M1調用,您需要的不僅僅是AST更多。您需要一個完整的符號表,它將每個符號使用綁定到與其匹配的可能定義。

計算這樣一個符號表的過程對很多語言來說都很困難,而且對於Java來說非常困難(但並不像C++那樣糟糕)。有人必須編碼如何在(本地)作用域,繼承,重載,隱式強制轉換等方面查找標識符的規則,而且Java參考手冊中的大部分內容試圖解釋這些規則。你不想自己做這個。

您真正需要的是一個完整的Java前端,它具有AST和相應的符號表,適用於您要檢查的每種方法。我認爲,您可以從接口到(Sun?)Java編譯器(我本人不知道如何執行此操作),從Jikes編譯器,Eclipse Java AST(?)模塊以及這類工具作爲我們的Java Front End。另一種方法是處理類文件,其中包含JVM形式的方法調用,其中JVM指令都是用符號表構建的。

如果要計算m1調用mA調用mQ調用.... mZ,則需要一個願意一次讀取整個源代碼庫的工具。編譯器不會爲你做,但你可以使用Eclipse或我們的前端來做到這一點。

+0

Spyros:您提供的作爲背景的附加信息應該真正添加到問題本身中。在將你的代碼塊分解爲註釋大小的部分之後,它應該是顯而易見的,它基本上是不可讀的。閱讀我的答案的其他人很可能會跳過這些評論,並會錯過額外的內容。你可以編輯你的問題;請參閱您的問題下的**編輯**「按鈕」。我冒昧將您的補充評論轉移到您的問題中(高級SO用戶可以這麼做)來幫助您。要完成此清理,*您*可以刪除這些註釋。 –

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()讓所有的使用ASTinvocationsForMethods.get(key)回報給作爲重點申報所有的方法調用的方法聲明。