2013-04-25 2 views
2

Я пытаюсь выполнить код rfc metric (Response for Class), он подсчитывает объявления метода + вызовы методов.Объявление методов подсчета + Методы Вызовы в классе с использованием JavaParser

Объявление метода отлично работает, но у меня возникла проблема при вызове метода подсчета с использованием API JavaParser.

Вот мой код:

public class MethodPrinter { 

    public static void main(String[] args) throws Exception { 
     // creates an input stream for the file to be parsed 
     FileInputStream in = new FileInputStream("D://test.java"); 
     CompilationUnit cu; 
     try { 
      // parse the file 
      cu = JavaParser.parse(in); 
     } finally { 
      in.close(); 
     } 
     // visit and print the methods names 
     MethodVisitor MV =new MethodVisitor(); 

     cu.accept(new VoidVisitorAdapter<Void>(){ 
      @Override 
      public void visit(final MethodCallExpr n, final Void arg){ 
       System.out.println("method call :"+n); 
       super.visit(n, arg); 

      } 
     }, null); 
    } 
} 

test.java

package test; 
import java.util.*; 

public class ClassA 
{ 
    private int test; 
    private ClassB classB = new ClassB(); 
    public void doSomething(int t){ 

    System.out.println (toString()); 
    int i= doSomethingBasedOnClassBBV(classB.toString()); 
    } 
    protected void doSomethingBasedOnClassB(){ 
    System.out.println (classB.toString()); 
    } 
} 

public class ClassB 
{ 
    private ClassA classA = new ClassA(); 
    public void doSomethingBasedOneClassA(){ 
    System.out.println (classA.toString()); 
    } 

    private String toString(){ 
    return "classB"; 
    } 
    private String toString(){ 
    return "classB"; 
    } 
    public void doSomethingBasedOneClassA(){ 
    System.out.println (classA.toString()); 
    } 
    protected void doSomethingBasedOnClassB(){ 
    System.out.println (classB.toString()); 
    } 
} 

результат этого кода:

*method call :System.out.println(toString()) 

method call :toString() 

method call :doSomethingBasedOnClassBBV(classB.toString()) 

method call :classB.toString() 

method call :System.out.println(classB.toString()) 

method call :classB.toString() 

method call :System.out.println(classA.toString()) 

method call :classA.toString() 

method call :System.out.println(classA.toString()) 

method call :classA.toString() 

method call :System.out.println(classB.toString()) 

method call :classB.toString()* 

действительно, этот код проверяет вызовы методов, но в моем Я не хочу, чтобы он учитывал вызовы методов библиотеки, такие как System.out.println (toString()), я хочу, чтобы он t только toString().

Если у вас есть лучший код или другой API для использования ... любая помощь приветствуется, заблаговременно.

ответ

0

Вы не можете легко решить проблему, используя исключительно синтаксический анализатор, поскольку вам необходимо разрешить вызов метода и выяснить, является ли это вызовом части метода стандартной библиотеки.

Вы можете легко сделать это с помощью JavaSymbolSolver, который является библиотекой, созданной для дополнения JavaParser. На практике вы звоните:

JavaParserFacade.solveMethodAsUsage(myMethodCallExpr)

И вы получите обратно MethodDeclaration, который говорит вам также тип, на котором был определен этот метод. После того, как у вас есть тип, вы можете посмотреть на пакет и проверить, начинается ли оно с java или javax и исключить его.

+0

Это классический пример того, почему Life After Parsing имеет важное значение при создании любых инструментов статического анализа. См. Http://www.semdesigns.com/Products/DMS/LifeAfterParsing.html. –

Смежные вопросы