可自定义的静态Java调用图生成器? [英] Customizable Static Java Call-Graph generator?

查看:169
本文介绍了可自定义的静态Java调用图生成器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须重构和维护一堆看起来相似的可怕Java类。许多人具有以下实现模式

I have to refactor and maintain a bunch of horrible similar looking Java classes. Many have the following implementation pattern

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;
    }
}

然后我要生成一个图形(带有Graphviz和 dot )-有点像静态调用图,但不完全是这样。

And from this I'd like to generate a graph (with Graphviz and dot) -- sort of a "static call graph", but not exactly.

I这是一个游戏,除了我自己使用Perl或Python解析Java代码外,我该如何自动做到这一点。

I am game here how I can do this automatically, besides using Perl or Python parsing the Java code myself.

我真正想做的是拥有一个抽象语法树(AST)或类似的类,我可以在其中导航并在打印代码时进行导航。

What I'd really like to to is to have an Abstract Syntax Tree (AST) or something similar of the class I could navigate through and while doing that printing the dot-code.


  • 如何在此处生成可遍历的AST?我猜遍历将在Java中完成,但是如果输出是任何文本表示就可以了(在这里想到 gprof )。

  • 还有其他方法,不使用AST?也许我只是盲目的,有一种更好,更简单的方法。

  • How can I produce a traversable AST here? I guess the traversing would be done in Java then, but if the output is any text representation it would be ok (gprof comes to mind here).
  • Any other approach, not using AST? Maybe I am just blind and there is a better, simpler way to do it.

推荐答案

周围会有各种各样的Java解析器产生AST:

There are a variety of Java parsers around that will produce ASTs:

  • Eclipse JDT
  • ANTLR
  • (Our) DMS Software Reengineering Toolkit

但是在处理真正的计算机语言时,AST远远不够。例如,要确定呼叫站点可以调用哪些方法,您需要全名和类型解析,以便可以准确确定数千个 foo中的哪个 foo 位于源文件中的可能会被调用。由于Java的查找规则复杂,因此计算起来并不容易。有关此主题的更多详细信息,请参阅我关于解析后的生命的文章。除非您不在乎答案的准确性,否则您不可能仅通过使用Python或Perl进行黑客攻击就可以轻松地复制此类功能。 Eclipse JDT可能具有名称解析;我不确定。 ANTLR Java解析器不支持;他们只是解析。

But ASTs are hardly ever enough when processing a real computer language. For instance, to determine what methods a call site may invoke, you need full name and type resolution so that you can accurately determining which foo of the thousands of foos lying around in your source files might be called. This isn't easy to compute for Java because of its complicated lookup rules. For more details on this topic, see my essay on Life After Parsing. You are not likely to duplicate such features easily by just hacking in Python or Perl, unless you don't care about the accuracy of your answer. Eclipse JDT probably has name resolution; I'm not sure. The ANTLR Java parsers do not; they just parse.

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

DMS's Java Front End has full name and type resolution for Java. To determine your call graph statically, you need essentially a points-to analysis; each field that contains an object of any kind is essentially a pointer, and you want to know for each pointer, specifically which objects it might select, and then you need to construct a (global) call graph to get the basic information you want. DMS's provides support for computing various kinds of control and data flow analysis; the Java Front End provides basic flow facts and it will compute local data flow analysis. To get a points-to analysis, you must assemble these facts with DMS's help, and then construct that call graph. We don't do this with DMS yet for Java, but we have for C on enormous scale (26 million lines in one system), and an analog for Java would be pretty similar and use most of the same DMS mechanisms; the call graph construction is fairly easy once you have points-to analysis. We've exported such graphs as DOT-graphs; you need to filter them to get a subgraph that DOT can actually afford to render.

您也许能够从类二进制分析文件(例如 Wala 。您仍将面临构建指向分析和全局调用图的问题。我记得Wala在这里有一些帮助,但是我不记得是什么。

You might be able to collect flow analysis facts from class binary analysis files such as Wala. You'll still face the problem of construction of points-to analysis and the global call graph. I recall that Wala has some kind of help here, but I don't recall what.

您也许可以使用分析器工具。除非您在性能分析过程中认真行使所有系统功能,否则这样的调用图可能很不完整。

You could perhaps collect a dynamically-constructed call graph using a profiler tool. Such a call graph is likely to be pretty incomplete unless you carefully exercise all your system functionality during the profiling process; that's pretty hard to do.

最终,您可能想要更改代码。也许您想内嵌 stepN 函数。也许您想手工完成,但是如果您的代码中充满了这些东西,也许您想要自动化。这里的DMS之类的工具提供了从源到源的转换,从而实现了自动代码更改。瓦拉在这里不会帮您。

Eventually, you'll probably want to change your code. Maybe you want to inline your stepN functions. Maybe you want to do it by hand, but if your code is full of such things, maybe you want automation. Here a tool like DMS provide source-to-source transformations, enabling such automated code changes. Wala won't help you here.

这篇关于可自定义的静态Java调用图生成器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆