2

私はリファクタリングして、似たような見た目のひどい 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;
    }
}

そして、これからグラフを生成したいと思います(Graphvizとを使用dot)-「静的呼び出しグラフ」のようなものですが、正確ではありません。

Perl や Python を使って自分で Java コードを解析する以外に、これを自動的に行う方法を考えています。

私が本当にしたいのは、Abstract Syntax Tree (AST) か、ナビゲートできるクラスに似たものを用意し、その間にdot-code を出力することです。

  • ここでトラバース可能な AST を生成するにはどうすればよいですか? その場合、トラバースはJavaで行われると思いますが、出力がテキスト表現であれば問題ありません(gprofここで思い浮かびます)。
  • ASTを使用しない他のアプローチはありますか? 多分私は目が見えないだけで、より良い、より簡単な方法があります。
4

1 に答える 1

6

AST を生成するさまざまな Java パーサーがあります。

しかし、実際のコンピューター言語を処理する場合、AST だけでは十分ではありません。たとえば、呼び出しサイトが呼び出す可能性のあるメソッドを決定するには、ソース ファイルにある何千もの foo のうち、どのfoo が呼び出される可能性があるかを正確に決定できるように、完全な名前と型の解決が必要です。複雑なルックアップ ルールがあるため、これを Java で計算するのは簡単ではありません。このトピックの詳細については、Life After Parsingに関する私のエッセイを参照してください。答えの正確さを気にしない限り、Python や Perl をハッキングするだけでは、そのような機能を簡単に複製することはできません。Eclipse JDT にはおそらく名前解決があります。わからない。ANTLR Java パーサーにはありません。解析するだけです。

DMS の Java フロント エンドには、Java の完全な名前と型の解決があります。呼び出しグラフを静的に決定するには、本質的にポイントツー分析が必要です。あらゆる種類のオブジェクトを含む各フィールドは本質的にポインターであり、各ポインターについて、具体的にはどのオブジェクトを選択するかを知りたい場合は、必要な基本情報を取得するために (グローバル) コール グラフを作成する必要があります。DMS は、さまざまな種類の制御およびデータ フロー解析の計算をサポートします。; Java フロント エンドは基本的なフロー ファクトを提供し、ローカル データ フロー分析を計算します。ポイント分析を行うには、DMS の助けを借りてこれらの事実を集め、その呼び出しグラフを作成する必要があります。Java ではまだ DMS でこれを行っていませんが、C では大規模 (1 つのシステムで 2,600 万行) でこれを行います。Java のアナログはかなり似ており、同じ DMS メカニズムのほとんどを使用します。分析ポイントがあれば、コール グラフの作成は非常に簡単です。このようなグラフを DOT グラフとしてエクスポートしました。DOT が実際にレンダリングできるサブグラフを取得するには、それらをフィルタリングする必要があります。

Walaなどのクラス バイナリ解析ファイルからフロー解析ファクトを収集できる場合があります。ポイントツー分析とグローバル コール グラフの構築の問題に直面することになります。ワラがここで何らかの助けを借りたことを思い出しますが、何を思い出せません。

おそらく、プロファイラー ツールを使用して、動的に構築されたコール グラフを収集できます。このようなコール グラフは、プロファイリング プロセス中にすべてのシステム機能を注意深く実行しない限り、かなり不完全なものになる可能性があります。それはかなり難しいです。

最終的には、おそらくコードを変更したくなるでしょう。stepN関数をインライン化する必要があるかもしれません。手作業でやりたいかもしれませんが、コードがそのようなものでいっぱいの場合は、自動化が必要になるかもしれません。ここでは、DMS のようなツールがソースからソースへの変換を提供し、そのような自動化されたコード変更を可能にします。ワラはここではあなたを助けません。

于 2012-06-12T11:52:30.497 に答える