JavaScript 用の Call-Graph や Control-Flow-Graph ジェネレーターはありますか?
コール グラフ - http://en.wikipedia.org/wiki/Call_graph
制御フロー グラフ - http://en.wikipedia.org/wiki/Control_flow_graph
編集: API/コードを使用してグラフにアクセスできる静的ツールを特に探しています
JavaScript 用の Call-Graph や Control-Flow-Graph ジェネレーターはありますか?
コール グラフ - http://en.wikipedia.org/wiki/Call_graph
制御フロー グラフ - http://en.wikipedia.org/wiki/Control_flow_graph
編集: API/コードを使用してグラフにアクセスできる静的ツールを特に探しています
これを行うには、次のものが必要です。
その方法は、コンパイラの文献にかなり詳しく記載されています。ただし、この問題を実装するにはかなりの労力がかかるため、「パーサーの結果を使用して必要なものを取得できます」という形式の回答は、むしろポイントを逃します。
この仕組みをすべて適用できれば、実際の結果として得られるのは保守的な答え、たとえば「A は B を呼び出す可能性がある」です。とにかくこれがあなたが知っているすべてです、考えてください
void A(int x,y) { if (x>y) foo.B(); }
ツールは複雑なロジックを推論できない場合があるため、アプリケーションの設計者がそれが不可能であることを知っていても、「A は B を呼び出す可能性があります」というメッセージが表示されることがあります。
void A(int x) // programmer asserts x<4
{ if (x>5) foo.B(); }
evalコマンドに到着する文字列値の結果を追跡し、それらを解析して、どのコードが評価されているか、および eval されたコードがどの関数を呼び出す可能性があるかについて何らかの手がかりを得る必要があるため、eval は問題を悪化させます。誰かが文字列で「eval」を eval に渡すと、事態は非常に厄介になります :-{ また、プログラム実行コンテキストをモデル化する必要がある可能性があります。コールバックを含むブラウザー API はたくさんあると思います。
問題をすぐに解決するために必要なすべての機構が完全に構成されたツールを誰かが提供してくれたら、それは明らかに素晴らしいことです。そのようなツールは存在しないため、そのようなオファーは得られないのではないかと思います。その理由は、必要なすべてのインフラストラクチャです。構築するのは難しく、たった 1 つのツールでそれを正当化できる人はほとんどいません。「JavaScript コンパイラーの最適化」でさえ、この機構、特にグローバル分析をすべて備えているとは限りません。また、目的に合わせて簡単に使用できるように設計された形式でパッケージ化されている可能性は低いです。
1969 年にプログラミングを始めて以来、私はこの問題に頭を悩ませてきました (当時の私のプログラムのいくつかはコンパイラーであり、これらすべてが必要でした)。これを実現する唯一の方法は、このすべての機械のコストを多くのツールで償却することです。
私の会社は、DMS Software Reengineering Toolkitを提供しています。これは、一般的なコンパイラ分析および変換機構のパッケージであり、さまざまな産業用強度のコンピューター言語フロントエンド (C、C++、COBOL、および JavaScript を含む) を備えています。DMS は、汎用基盤上にカスタム ツールを構築できるようにする API を提供します。
メッセージの上部にリストされている一般的な機構はすべて DMS に存在します。これには、明確に文書化された API を介して利用可能な制御フロー グラフやデータ フロー分析が含まれます。そのフロー分析は、特定の言語のフロント エンドに関連付ける必要があります。これにも多少の作業が必要なため、まだすべての言語で行っているわけではありません。これは C [モノリスとして 18,000 のコンパイル ユニットのシステムでテスト済みで、存在する 250,000 個の関数のコール グラフの計算、間接関数呼び出しを含む!]、COBOL、および Java でこれを行い、C++ に取り組んでいます。
DMSには、このスレッドの他の回答と同じ「JavaScript」パーサーの回答があり、その観点から見ると、DMSは「パーサーの上に構築する」という他の回答よりも優れているわけではありません. 違いは明確です。機械は DMS に既に存在するため、作業は機械の実装やパーサーへの関連付けではありません。パーサーに結び付けているだけです。これはまだ少し手間がかかりますが、パーサーから始める場合よりもはるかに少ない作業です。
一般に、これを行うことはできません。その理由は、関数がファーストクラスで動的に型付けされるためです。たとえば、次のようになります。
var xs = some_function();
var each = another_function();
xs.map(each);
不明な点が 2 つあります。1 つは呼び出される 'map' のバージョンであり (Javascript ポリモーフィズムは通常、静的に解決できないため)、もう 1 つは 'each' に割り当てられた値であり、これも静的に解決できません。このコードが持つ唯一の静的プロパティは、「another_function」から取得した関数で「map」メソッドが呼び出されることです。
ただし、それで十分な情報である場合は、役立つリソースが 2 つあります。1 つは汎用の Javascript パーサーで、特にパーサー コンビネーターを使用して構築されています (Chris Double の jsparse は良いパーサーです)。これにより、構築中の解析ツリーに注釈を付けることができ、呼び出しノードにカスタム ルールを追加して、グラフ エッジを記録できます。
もう 1 つの便利なツール (恥知らずなプラグイン) は、私が作成した Caterwaul という Javascript-to-Javascript コンパイラです。構文ツリーに対してパターン マッチングを行うことができ、構文ツリーをたどる方法を知っています。これは、あなたの場合に役立つかもしれません。また、短期間の実行から動的なトレースを構築したい場合にも役立ちます (正確で詳細な結果が必要な場合は、おそらく最善の策です)。
WALA は、JavaScript の静的呼び出しグラフと制御フロー グラフを作成できるオープンソースのプログラム分析フレームワークです。
http://wala.sourceforge.net/wiki/index.php/Main_Page
eval
1 つの注意点は、 、with
、およびその他の分析が困難な構造が存在する場合、コール グラフの一部のエッジが失われる可能性があることです。また、スケーラビリティにも取り組んでいます。WALA は妥当な時間内に jquery を分析することはまだできませんが、他のいくつかのフレームワークは分析できます。また、JavaScript コール グラフを作成するためのドキュメントは、現時点ではあまり良くありません (改善は私の TODO リストにあります)。
私たちはこのコードに積極的に取り組んでいるので、試してみて問題が発生した場合は、WALA メーリング リスト ( https://lists.sourceforge.net/lists/listinfo/wala-wala ) にメールを送信するか、私に連絡してください。
ここに私が見ることができるいくつかの解決策があります:
Aptana Call Graph ビューを使用する
Aptana は、Javascript コードの編集とデバッグを可能にする Eclipse ベースの IDE です。
Dynatrace の使用Dynatrace
は、コードをライブ トレースし、コール グラフとホット スポットを確認できる便利なツールです。
Firebugを使用する
Firefox で有名な開発者向けアドオン
ここで生成されるコール グラフのほとんどは動的です。つまり、特定のアクション セットのコール グラフが表示されます。静的コール グラフを探している場合は、最初に Aptana を確認してください。静的呼び出しグラフでは、動的呼び出し (eval() を介して実行されるコード) を確認できない場合があります。
http://doctorjs.org/があなたのニーズに合っていると思います。これには素晴らしい JSON API があり、mozilla によってバックアップされ、github で利用できます。それはJS自体で書かれており、一般的にはかなりうまく機能します(ポリモーフィズムなどの処理を含む)。
js のアプローチについては、 をご覧くださいarguments.callee.caller
。現在の関数を呼び出した関数を提供し、コールスタックを再帰できます。このスレッドhttp://bytes.com/topic/javascript/answers/470251-recursive-functions-arguments-callee-callerに例があります。
これはすべてのブラウザーで機能するとは限らず、「コール スタック」またはネイティブ関数の先頭に到達したときに予期しない事態に遭遇する可能性があることに注意してください。自己責任で使用してください。
私の例は IE9 と Chrome 10 で動作します (他のブラウザーはテストしていません)。
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body onload="Function1()">
<form id="form1" runat="server">
<div>
</div>
</form>
</body>
<script type="text/javascript">
function Function1()
{
Function2();
}
function Function2()
{
Function3();
}
function Function3()
{
Function4();
}
function Function4()
{
var caller = arguments.callee.caller;
var stack = [];
while (caller != null)
{
stack.push(caller);//this is the text of the function. You can probably write some code to parse out the name and parameters.
var args = caller.arguments; //this is the arguments for that function. You can get the actual values here and do something with them if you want.
caller = caller.caller;
}
alert(stack);
}
</script>
</html>
コール グラフに最も近いのは、完全な Javascript AST を操作することです。これは Rhino で可能です。次の記事をご覧ください: http://tagneto.blogspot.com/2010/03/requirejs-kicking-some-ast.html
投稿の例:
//Set up shortcut to long Java package name,
//and create a Compiler instance.
var jscomp = Packages.com.google.javascript.jscomp,
compiler = new jscomp.Compiler(),
//The parse method returns an AST.
//astRoot is a kind of Node for the AST.
//Comments are not present as nodes in the AST.
astRoot = compiler.parse(jsSourceFile),
node = astRoot.getChildAtIndex(0);
//Use Node methods to get child nodes, and their types.
if (node.getChildAtIndex(1).getFirstChild().getType() === CALL) {
//Convert this call node and its children to JS source.
//This generated source does not have comments and
//may not be space-formatted exactly the same as the input
//source
var codeBuilder = new jscomp.Compiler.CodeBuilder();
compiler.toSource(codeBuilder, 1, node);
//Return the JavaScript source.
//Need to use String() to convert the Java String
//to a JavaScript String.
return String(codeBuilder.toString());
}
Javascript または Java のいずれかで、AST をたどって、任意のタイプのコール グラフまたは依存関係チェーンを構築できます。
NodeJS とは直接関係ありませんが、一般的には JavaScript と関係があります。SAP は HANA に関連する Web IDE をリリースしました (ただし、HANA クラウドからも自由にアクセスできます。詳細については、http: //scn.sap.com/community/developer-center/ を参照してください)。 cloud-platform/blog/2014/04/15/sap-hana-web-ide-online-tutorial )。
この Web IDE には、コール グラフの作成に主眼を置いて (それだけではなく) JavaScript コンテンツを分析する REST ベースのサービスがあります。Code Navigation のように、そのサービスの多くの利用者がいます。
詳細については、こちら (関数フローの部分を参照): http://scn.sap.com/community/developer-center/hana/blog/2014/12/02/sap-hana-sps-09-new-developer- features-sap-hana-web ベースの開発ワークベンチ
注: 私はこのサービスの主な開発者です。