0

如果有人使用 SPOON API,你能给我一些线索如何创建调用图以及我需要做什么吗?

我认为我需要像这样创建一些处理器:

public class InvocationProcessor extends AbstractProcessor<CtInvocation> {
    @Override
    public void process(CtInvocation element) {
        System.out.println(element.getActualTypeArguments());
    }
}

然后使用 Launcher 进行运行分析

public void getCallers(){

    final Launcher launcher = new Launcher();
    launcher.setArgs("-i D:\\IntelliJ_projects\\ComprehensionTool\\ -p comprehensionTool.analyse.processor.InvocationProcessor".split(" "));
    launcher.run();
}

但我不确定......我想问一下我是否需要一些特殊的依赖项才能使用 Launcher?

我认为我错了,因为当我执行它时会抛出这个错误:

Exception in thread "main" java.lang.NoSuchMethodError: org.eclipse.jdt.internal.compiler.batch.Main.<init>(Ljava/io/PrintWriter;Ljava/io/PrintWriter;ZLjava/util/Map;Lorg/eclipse/jdt/core/compiler/CompilationProgress;)V
    at spoon.support.compiler.jdt.JDTBatchCompiler.<init>(JDTBatchCompiler.java:58)
    at spoon.support.compiler.jdt.JDTBatchCompiler.<init>(JDTBatchCompiler.java:54)
    at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.createBatchCompiler(JDTBasedSpoonCompiler.java:352)
    at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.createBatchCompiler(JDTBasedSpoonCompiler.java:356)
    at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.buildUnits(JDTBasedSpoonCompiler.java:388)
    at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.buildUnitsAndModel(JDTBasedSpoonCompiler.java:372)
    at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.buildSources(JDTBasedSpoonCompiler.java:348)
    at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.build(JDTBasedSpoonCompiler.java:119)
    at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.build(JDTBasedSpoonCompiler.java:102)
    at spoon.Launcher.buildModel(Launcher.java:700)
    at spoon.Launcher.run(Launcher.java:651)
4

2 回答 2

2

你需要一个 Eclipse JDT 的依赖项,我们正在使用这个:

<dependency>
  <groupId>org.eclipse.tycho</groupId>
  <artifactId>org.eclipse.jdt.core</artifactId>
  <version>3.12.0.v20160516-2131</version>
</dependency>

您启动 Spoon 的方式似乎不错,但是您的处理器将遍历整个模型并打印调用类型:它不遵循调用。创建调用图并不容易:您必须首先获取起点(例如方法),然后跟踪调用。

获取起点很容易:查看Spoon 文档,但随后您需要手动遍历调用图来构建它。

于 2017-01-30T14:36:44.270 回答
1

我使用递归并从 CtInvocation 开始。

  1. 查找封闭的 CtMethod。
  2. 查找 CtMethod 的 N 个 CtInvocations。
  3. 对于 N 中的每个 CtInvocation 递归到步骤 1。

无论好坏,我在循环中使用 GetParent() 来查找 CtInvocation 的 CtMethod,似乎它会先找到 CtBody,然后是 CtMethod,但我认为对于 CtInvocation 在其他情况下需要这个块(if 语句)、while 循环等。

于 2018-11-19T19:53:25.673 回答