可自定义的静态Java调用图生成器?

tow*_*owi 2 java profile graphviz dfa call-graph

我必须重构并维护一堆看起来很糟糕的Java类.许多人具有以下实施模式

class Machine {
    public int advance(int state) {
        switch(state) {
        case 7:  return step_7();
        case 13: return step_13();
        case 4:  return step_4();
        }
    }
    private int step_7() {
        if(something) return 13; else return 4;
    }
    private int step_13() {
        ...
        return 4;
    }
    private int step_4() {
        if(miep) return 7;
        ...
        return 13;
    }
}
Run Code Online (Sandbox Code Playgroud)

从这里我想生成一个图形(与Graphviz和dot) - 一种"静态调用图",但不完全.

我在这里游戏如何自动执行此操作,除了使用Perl或Python自己解析Java代码.

我真正喜欢的是有一个抽象语法树(AST)或类似我可以浏览的类,同时打印dot-code.

  • 如何在这里生成可遍历的AST?我猜测遍历将在Java中完成,但如果输出是任何文本表示,那就没问题(gprof想到这里).
  • 还有其他方法,不使用AST吗?也许我只是盲目的,有一种更好,更简单的方法.

Ira*_*ter 6

有各种各样的Java解析器会生成AST:

但是在处理真正的计算机语言时,AST几乎还不够.例如,以确定哪些方法调用的网站可以调用,您需要的全名和类型解析,让您可以准确地确定 FOO的数千在你的源文件躺在附近可能会被调用.由于其复杂的查找规则,这对于Java来说并不容易计算.有关此主题的更多详细信息,请参阅我的解析后的生活文章.除非您不关心答案的准确性,否则您不太可能通过黑客入侵Python或Perl来轻松复制此类功能.Eclipse JDT可能具有名称解析; 我不确定.ANTLR Java解析器没有; 他们只是解析.

DMS的Java前端具有Java的全名和类型解析.要静态确定您的调用图,您基本上需要一个点到分析; 包含任何类型对象的每个字段本质上都是一个指针,并且您想知道每个指针,特别是它可能选择哪些对象,然后您需要构建一个(全局)调用图来获取所需的基本信息.DMS为计算各种控制和数据流分析提供支持; Java前端提供基本的流程事实,它将计算本地数据流分析.要获得分数分析,您必须使用DMS的帮助汇总这些事实,然后构建该调用图.对于Java,我们不会使用DMS,但是我们已经大规模地使用C(一个系统中有2600万行),而Java的模拟将非常相似并且使用大多数相同的DMS机制; 一旦进行了点分析,调用图构造就相当容易了.我们已经导出了像DOT图这样的图形; 你需要过滤它们以获得DOT实际上可以渲染的子图.

您可以从类二进制分析文件(如Wala)中收集流分析事实.您仍将面临构建点分析和全局调用图的问题.我记得Wala在这里有一些帮助,但我不记得是什么.

您也许可以使用分析器工具收集动态构造的调用图.除非您在分析过程中仔细运用所有系统功能,否则这样的调用图可能非常不完整; 这很难做到.

最终,您可能想要更改代码.也许你想内联你的stepN函数.也许你想手工完成它,但如果你的代码充满了这些东西,也许你想要自动化.像DMS这样的工具提供了源到源的转换,实现了这种自动代码更改.Wala在这里不会帮助你.