2011-11-09 2 views
4

AST (추상 구문 트리) 구문 분석기를 사용하여 프로그램의 각 메서드 선언에서 호출되는 메서드의 이름을 어떻게 얻을 수 있습니까? 지금까지 메서드의 선언의 모든 이름과 호출되는 메서드의 모든 이름을 가져 왔지만 어떤 메서드가 어떤 메서드를 호출하는지 알고 싶습니다. 방법 등 방법 mCmD를 호출 m2 예를 들어, 나는 방법 mAmB를 호출 m1 그 방법을보고 싶어방법 불러 오기 AST

[편집 2011년 11월 9일 IDB,의 몸에 다시 초보자의 확장 된 의견을 전사 원래 질문. 내가 올바르게 바꿔줬으면 좋겠다. 나는 저자가 돌아와서 필요에 따라 수정하기를 바란다.] :

내 이슈는 (Eclipse의) MethodDeclaration API에 GetInvokedMethodName 함수가 호출되지 않는 것 같다. 여기에 내 코드입니다 : 당신이 (클래스의 당신의 광대 한 배열을 통해 "MB의"라는 모든 사람의) 구체적인 방법 메가 바이트가 (M1)에 의해 호출되는 알고 싶다면

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

, 당신은 단지 AST보다 더 필요합니다. 전체 기호 테이블이 필요합니다.이 기호 테이블은 각 기호 사용을 해당 기호 정의와 일치하는 가능한 정의에 바인드합니다.

이러한 기호 표를 계산하는 프로세스는 많은 언어에서 어렵고 Java에서는 매우 어렵습니다 (C++만큼 나쁘지는 않습니다). 누군가는 (로컬) 스코프, 상속, 과부하, 묵시적 캐스트 등에서 식별자를 찾는 방법에 대한 규칙을 인코딩해야하며 Java 참조 설명서는 내용을 설명하기 위해 많은 부분을 다뤘습니다. 당신 스스로 이것을 할 필요가 없다.

정말로 필요한 것은 검사 할 각 메소드에 대해 AST와 해당 기호 테이블이 모두있는 전체 Java 프론트 엔드입니다. 인터페이스 (Sun?) Java 컴파일러 (개인적으로이 작업을 수행하는 방법을 알지 못함), Jikes 컴파일러, Eclipse Java AST (?) 모듈 및 이와 유사한 도구에서 얻을 수 있습니다. 우리의 Java Front End. 또 다른 접근법은 JVM 형식에서 메소드 호출을 포함하는 클래스 파일을 처리하는 것입니다. JVM 명령어가 모두 심볼 테이블의 이점으로 빌드 한 이점이 있습니다.

m1 호출 mA mA mx calls .... mZ를 계산하려면 한 번에 전체 소스 코드 기반에서 읽을 도구가 필요합니다. 컴파일러는 그렇게하지 않을 것이지만 Eclipse 또는 프론트 엔드를 사용하여 컴파일 할 수 있습니다.

+0

Spyros : 질문의 배경으로 제공 한 추가 정보는 실제로 질문 자체에 추가되어야합니다. 코드 블록을 주석 크기로 나누어서 기본적으로 읽을 수 없도록해야합니다. 내 대답을 읽는 다른 사람들이 이러한 의견을 건너 뛰고 추가 답변을 놓칠 수 있습니다. 질문을 수정할 수 있습니다. 당신의 질문 아래에 ** 편집 ** "버튼"을 참조하십시오. 나는 당신의 질문에 당신의 추가 된 코멘트를 옮길 자유를 취하고있다. (높은 순위의 SO 사용자가 그렇게 할 수있다.) 당신을 도울 것이다. 이 정리를 완료하려면 * you *가 해당 주석을 삭제할 수 있습니다. –

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

     }); 

, 하나는 사용 ASTinvocationsForMethods.get(key) 반환 키로 주어진 선언에 대한 모든 메소드 호출에 대한 모든 메소드 선언을 얻기 위해 invocationsForMethods.keySet()을 요청할 수 있습니다.