2009-11-05 70 views
5

我正在寻找一个大学课程的静态分析器。为了给工具提供更多的权力,我希望能够查找调用层次结构(如在Eclipse中按Ctrl + Alt + H)。这也必须是一个快速操作,所以查找可能不得不针对索引而不是字节码扫描来完成。是否可以分离Eclipse的代码索引功能?

但是,编写一个Eclipse插件将是我期望的雄心太大。相反,我宁愿将创建代码索引的Eclipse部分解耦,然后使用库进行查找。用户的界面将在命令行中,以简化实现。

我读过Eclipse使用Lucene执行索引[1],但是,由于Eclipse允许的功能,必须在Lucene上做大量的工作。

问题是,是否有可能将Eclipse的索引功能解耦以重用?如果没有,还有其他可用的库,可以做我讨论过的那种处理吗?

[1]的Lucene在行动(IIRC)


编辑

我认为其中有一些误解。我不想检查班级层次结构,我想检查调用层次结构。这就是为什么搜索和索引(某种方式,但也许这不是正确的术语)进入讨论的原因。检查类层次结构可能比检查调用层次结构要便宜很多。

至于编写一个Eclipse插件,是的,我很喜欢,但鉴于这个任务是在一个很短的时间尺度上,它可能不太可能我会管理它。但是,有些人认为这并不像我想的那样艰难。

也许我已经把太多的重点放在了Eclipse上,我发现我真的在寻找任何提供用于检查通过字节码的调用图的API的工具。

感谢您的回答!

+0

- 了解Eclipse如何执行如此之快的一个重要事情是,它会创建一次总索引,然后在类更改时单独更新。所以我想,这个Eclipse功能很少能够解耦。我看不出如何避免初始的全字节代码分析,它将构建调用层次结构的索引表(可以保存以避免必须扫描搜索调用层次结构的每种类型)。 说实话,除了在一个非常庞大的代码库上,全面扫描对于ASM来说真的很快,你花时间写一个“delta indexer”的时间不值得我们付出努力。 – Olivier 2009-11-05 19:56:27

+0

初始的前期扫描很好。我更关心的是找到一个API,因为它已经超出了我的课程范围。如果最初的全面扫描是使用ASM,那很好,我只是想避免写这个位;-) – Grundlefleck 2009-11-05 22:44:36

回答

1

你正在寻找的操作是不完全的索引。编制索引以提供全文搜索。查找给定类的超类很难进行文本搜索。

你想写一个使用JDT的Eclipse插件(相当简单,可能只是几个类)。您需要编写一个AST(抽象语法树)访问器,用于分析您的代码。然后,您将能够使用JDT工具解析类型并轻松遍历类层次结构。

结账my answer to this question

+0

请看我的编辑。我不想要解析超类,而是为特定的方法调用图。干杯。 – Grundlefleck 2009-11-05 18:10:18

+0

假设您正在检查foo的方法,您是在寻找foo调用的所有方法还是调用foo?有很大的不同。 – zvikico 2009-11-05 19:26:57

+0

调用foo。具体调用构造函数。 – Grundlefleck 2009-11-05 19:51:00

0

Eclipse插件确实不那么难;他们需要一点习惯,但不会太长。

考虑添加你想要的任何功能到Eclipse IDE。您可以利用其他插件功能(例如JDT,其中包含您正在查找的搜索功能)。

然后,您可以提供所有eclipse用户使用的插件,而不是开发另一个独立工具。

1

我会去寻求一个基于ASM的解决方案,它会努力工作,解决层次结构问题。 下面是一个简单的分析,即调用println定类的调用层次:

public class Analyzer { 
    public static void main(String[] args) throws IOException { 
     ClassReader classReader; 
     ClassNode classNode; 
     String fullyQualifiedClassName = args[0]; 
     String callHierarchy = ""; 
     while (null != fullyQualifiedClassName) { 
      callHierarchy = " > " + fullyQualifiedClassName + callHierarchy; 
      classReader = new ClassReader(fullyQualifiedClassName); 
      classNode = new ClassNode(); 
      classReader.accept(classNode, 0); 
      if (null != classNode.superName) { 
       fullyQualifiedClassName = classNode.superName.replace('/', '.'); 
      } else { 
       fullyQualifiedClassName = null; 
      } 
     } 
     System.out.println(callHierarchy); 
    } 
} 

鉴于java.util.TreeMap中作为参数,它打印

> java.lang.Object > java.util.AbstractMap > java.util.TreeMap 

我知道这是字节码分析,但说实话,ASM闪电般快速,如果您只需要Call Hierarchy,扫描将不会花费太多时间(没有什么值得注意的imo)。

希望得到这个帮助:)

+0

您的示例演示了“类型层次结构”,我正在查找“调用层次结构”。如方法A调用方法B,并且查找B的调用层次结构,它将显示方法A.这比类型层次结构更复杂,我认为需要扫描整个代码库。这就是我寻找索引解决方案的原因。除非我误解了某些东西...... – Grundlefleck 2009-11-05 17:56:47

4

走字节码并不难,也不慢。我们以交互式的速度对大型Java代码项目进行了静态分析。既然你的时间不多,我会建议你在eclipse中修改一些像call graph plugin [1]这样的东西。另外,Eclipse代码很难理解,您最好编写自己的插件,尽可能多地使用Eclipse的未公开API。

[1] http://www.eclipseplugincentral.com/Web_Links-index-req-viewlink-cid-1326.html

+0

+1该链接提供了一些有趣的探索内容。 – Grundlefleck 2009-11-05 18:11:49

+1

我喜欢这个建议:“尽可能多地使用Eclipse的无证API”。你是认真的吗? – 2009-11-07 05:26:08

+0

我做到了。这是费时的,但是坚持不懈,你可以做到。 – mansu 2010-01-22 02:07:26

1

看一看IBM的WALA框架。除此之外,您可以为您的代码库生成Call Graph(CG)。事实上,WALA中的所有内容都始于构建CG。 您可以修改它们的示例并用您自己的替换测试数据。

1

我会完全忽略Eclipse:它只会分散您的注意力。

如果你正在执行静态分析,你几乎肯定会想要分析字节码。要查找呼叫层次结构,请查找invokeinstanceinvokestaticinvokespecial字节码(请参阅JVM spec)。这些引用了完全限定的类/方法名称,并且可以使用Map<FuncRef,Set<FuncRef>>构建呼叫层次结构,其中FuncRef是您定义的用于保存方法调用信息的类。

BCEL可以帮助你进行字节码扫描。

但是,您将不得不做更多的工作,尤其是invokeinstance,因为您不知道实际实例可能是什么。有时候你可以在代码中向后看,以找到一个任务,但更有可能你会猜测 - 这是静态分析的致命弱点。

0

我怀疑你会发现它更容易编写插件 - 针对Eclipse的设计和记录 - 而不是提取的意思是内部和建立别的东西了他们的位。

相关问题