2011-11-09 19 views
4

AST(抽象構文木)パーサーを使用してプログラムの各メソッド宣言で呼び出されるメソッドの名前を取得するにはどうすればよいですか?これまでは、メソッド宣言のすべての名前と呼び出されるメソッドの名前をすべて取得することができましたが、どちらのメソッドがどのメソッドを呼び出すかを知りたいと思います。この方法は、などの方法mCmDを呼び出しm2ながらたとえば、私は、メソッドmAmBを呼び出すm1その方法を見てみたいメソッド呼び出しAST

[EDIT 2011年11月9日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

あなたはM1によって呼び出される(クラスのあなたの広大な配列全体で「ヘクトパスカル」という名前のすべてのものの)具体的な方法ヘクトパスカル知りたい場合は、あなただけのAST以上のものを必要とします。完全なシンボルテーブルが必要です。これは、各シンボルの使用を、それに一致する可能な定義にバインドします。

このようなシンボルテーブルを計算するプロセスは、多くの言語では難しく、Javaでは非常に難しいです(ただし、C++ほど悪くはありません)。誰かが(ローカル)スコープ、継承、オーバーロード、暗黙のキャストなどで識別子をどのように参照するかのルールをエンコードする必要があります。Javaリファレンスマニュアルはその内容のかなりの部分を説明しようとしています。あなたはこれを自分で行う必要はありません。

本当に必要なのは、検査するメソッドごとに、ASTと対応するシンボルテーブルの両方を持つ完全なJavaフロントエンドです。これは、Jikesのコンパイラ、EclipseのJava AST(?)モジュール、およびそのようなツールから、(私は個人的にこれを行う方法は分かりませんが)私たちはJava Front Endです。もう1つの方法は、JVM形式のメソッド呼び出しを含むクラスファイルを、JVM命令がすべてシンボルテーブルの恩恵を得て構築したアドバンテージで処理することです。

m1コールmAを呼び出すには、mQ calls .... 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); 
      } 

     }); 

、1が使用ASTinvocationsForMethods.get(key)リターンキーとして与えられた宣言のすべてのメソッド呼び出しのためのすべてのメソッド宣言を取得するためにinvocationsForMethods.keySet()を求めることができます。

関連する問題