我正在为大学班写一个静态分析器。为了给工具提供更多的功能,我希望能够查找调用层次结构(如Eclipse中的Ctrl + Alt + H)。这也必须是一个快速操作,因此可能必须对索引而不是字节码扫描进行查找。
然而,编写一个Eclipse插件对我来说太雄心勃勃了。相反,我宁愿解耦创建代码索引的Eclipse部分,并使用库来执行查找。用户界面将位于命令行上,以简化实施。
我读到Eclipse使用Lucene来进行索引[1],但是,Lucene必须在Eclipse允许的功能上有大量的工作。
问题是,是否可以将Eclipse的索引功能解耦以便重用?如果没有,是否有其他可用的库可以进行我讨论过的那种处理?
[1] Lucene In Action(IIRC)
修改
我认为存在一些误解。我不打算检查类层次结构,我想检查调用层次结构。这就是为什么搜索和索引(某种类型,尽管可能不是正确的术语)进入讨论的原因。检查类层次结构可能比检查调用层次结构要便宜得多。
至于编写一个Eclipse插件,是的,我很乐意,但考虑到这个任务的时间很短,我可能不会管理它。但是有些人认为这并不像我想的那么艰难,这是有用的信息。
也许我过分强调Eclipse,我想到了我真的在寻找能够通过字节码检查调用图的API的任何工具。
到目前为止,感谢您的回答!
答案 0 :(得分:4)
走字节码并不难,也不慢。我们以交互的速度对大型Java代码项目进行了静态分析。因为,你的时间很短,我建议你修改一下像eclipse中的调用图查看器插件[1]。此外,Eclipse代码很难理解,您最好编写自己的插件,尽可能多地使用Eclipse的未记录的API。
[1] http://www.eclipseplugincentral.com/Web_Links-index-req-viewlink-cid-1326.html
答案 1 :(得分:1)
您正在寻找的操作并不完全是索引。进行索引以提供全文搜索。找到给定类的超类几乎不是文本搜索。
你想编写一个使用JDT的Eclipse插件(相当简单,可能只是几个类)。您将需要编写一个AST(抽象语法树)访问者,它将用于分析您的代码。然后,您将能够使用JDT工具解析类型并轻松遍历类层次结构。
答案 2 :(得分:1)
我会寻求基于ASM的解决方案,它会做出艰苦的工作,解决层次结构问题。 这是一个简单的分析器,它打印出Class给出的调用层次结构:
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快速闪电,如果您只需要调用层次结构,扫描就不会花费太多时间(没有什么值得注意的)。
希望这有帮助:)
答案 3 :(得分:1)
查看IBM的WALA框架。除此之外,您还可以为您的代码库生成调用图(CG)。事实上,WALA中的几乎所有内容都始于构建CG。 您可以修改他们的示例并用您自己的替换测试数据。
答案 4 :(得分:1)
我会完全忽略Eclipse:它会分散你的注意力。
如果您正在执行静态分析,您几乎肯定会想要分析字节码。要查找调用层次结构,请查找 invokeinstance , invokestatic 和 invokespecial 字节码(请参阅JVM spec)。这些引用了一个完全限定的类/方法名,您可以使用Map<FuncRef,Set<FuncRef>>
构建调用层次结构,其中FuncRef
是您定义的类,用于保存方法调用信息。
BCEL可以帮助您进行字节码扫描。
但是,您将不得不做更多的工作,特别是使用 invokeinstance ,因为您不知道实际实例可能是什么。有时你可以在代码中向后看以找到一个任务,但更有可能你会猜测 - 这是静态分析的致命弱点。
答案 5 :(得分:1)
这是Eclipse的GUI插件,它提供了调用层次结构的可视化表示。它不是一个列表,但它是一个帮助。
答案 6 :(得分:0)
或者你可以使用eclipse的JDT部分:http://www.eclipse.org/jdt/core/index.php
答案 7 :(得分:0)
Eclipse插件真的不那么难;他们需要一点点习惯,但不会太久。
考虑将所需的任何功能添加到eclipse IDE中。您可以利用其他插件功能(例如JDT,其中包括您正在寻找的搜索功能)。
然后,您可以为所有eclipse用户提供插件,而不是开发另一个独立工具。
答案 8 :(得分:0)
我怀疑你会发现编写插件更容易 - Eclipse的设计和记录 - 而不是提取内部的内容并从中构建其他东西。