是否有JavaScript的静态调用图和/或控制stream图API?

是否有JavaScript的Call-Graph和/或Control-Flow-Graph生成器?

呼叫图 – http://en.wikipedia.org/wiki/Call_graph

控制stream程图 – http://en.wikipedia.org/wiki/Control_flow_graph

编辑:我正在寻找一个静态工具,让我访问graphics使用一些API /代码

要做到这一点,你需要:

  • parsing,
  • 名称parsing(处理范围界定)
  • types分析(虽然JavaScript可以说是“dynamictypes”,但是这里有各种types的常量,包括函数常量)
  • 控制stream程分析(build立方法内控制stream程图的结构)
  • 数据stream分析(追踪哪些types被生成/使用)
  • 分析什么等于全局点(来跟踪在函数之间传递的函数常量,作为值到应用程序点)。

如何做到这一点在编译器文献中有很好的记载。 但是,为了实现这个相当大的问题,所以“你可以使用parsing器结果来得到你想要的”的forms的答案而不是错过了这一点。

如果你能应用所有这些机制,你会得到一个实际的结果是一个保守的答案,例如,“A可以调用B”。 无论如何,这是你所知道的,考虑一下

void A(int x,y) { if (x>y) foo.B(); } 

因为某个工具根本无法推理复杂的逻辑,所以即使应用程序devise者知道这是不可能的,也可能会得到“A可能调用B”

  void A(int x) // programmer asserts x<4 { if (x>5) foo.B(); } 

eval使问题变得更糟,因为您需要跟踪到达eval命令的string值结果,并parsing它们以获取某种线索,以了解哪些代码正在被撤销,以及代码可能调用哪些函数。 如果有人把string中的“eval”传递给eval,情况会变得非常糟糕: – {你也可能需要为程序执行上下文build模; 我怀疑有很多浏览器API包括callback。

如果有人为您提供具有完全configuration的所有必要机器的工具来解决您的问题,那显然是很好的。 我的怀疑是你不会得到这样的报价,因为这样的工具不存在。 原因就是基础设施所需要的一切; 它很难build立,几乎没有人可以certificate它只是一个工具。 即使是一个“优化的JavaScript编译器”,如果你可以find一个可能不会有所有这些机器,特别是全球分析,它不会被包装在一个为您的目的而devise的容易消费的forms。

自从我在1969年开始编程以来,我一直在为这个问题而头痛(当时我的一些程序是编译器,我想要所有这些东西)。 获得这个的唯一方法是通过大量工具来分摊所有这些机器的成本。

我公司提供DMS Software Reengineering Toolkit ,一个通用的编译器分析和转换机器包,以及各种工业强度的计算机语言前端(包括C,C ++,COBOL和yes,JavaScript)。 DMS提供API以使自定义工具能够在其通用基础上构build。

消息顶部列出的通用机器全部出现在DMS中,包括通过清晰logging的API提供的控制stream图和数据stream分析 。 stream程分析必须与特定的语言前端相关联。 这也需要一些工作,所以我们还没有完成所有的语言。 我们已经完成了C语言的testing[在18,000个编译单元的系统上进行testing,包括计算250,000函数的调用图,包括间接函数调用!],COBOL和Java,我们正在研究C ++。

DMS和这个线程中的其他答案一样,具有相同的“JavaScript”parsing器答案,从这个angular度来看,DMS并不比其他答案的“在parsing器上构build它”更好。 区别应该是清楚的: 机器已经存在于DMS中,所以工作不是实现机器和绑定到parsing器的工作; 它只是绑定到parsing器。 这仍然是一个工作,但是如果你刚开始使用一个parsing器,那么这个工作就会less得多。

WALA是一个开源的程序分析框架,可以为JavaScript构build静态调用图和控制stream图:

http://wala.sourceforge.net/wiki/index.php/Main_Page

一个警告是,调用图可能会在evalwith和其他难以分析的结构存在的情况下丢失一些边缘。 另外,我们还在研究可扩展性。 WALA还不能在合理的时间内分析jquery,但是可以分析一些其他的框架。 另外,我们用于构buildJavaScript调用图的文档目前还不是很好(改进了我的TODO列表)。

我们正在积极研究这个代码,所以如果你尝试并遇到问题,你可以发邮件给WALA邮件列表( https://lists.sourceforge.net/lists/listinfo/wala-wala )或者联系我。

一般来说,这是不可能的。 原因是函数是一stream的,dynamictypes的,例如:

 var xs = some_function(); var each = another_function(); xs.map(each); 

有两个未知数。 一个是被称为“map”的版本(因为Javascript多态性在一般情况下不能被静态parsing),另一个是赋给“each”的值,也不能被静态parsing。 这个代码唯一的静态属性是在'another_function'得到的一些函数上调用了一些'map'方法。

但是,如果这是足够的信息,则有两个资源可能会有所帮助。 一个是通用的Javascriptparsing器,特别是使用parsing器组合器(Chris Double的jsparse是一个很好的parsing器)。 这将使您可以在构build时parsing树,并可以将自定义规则添加到调用节点以logging图边。

另一个你可能会觉得有用的工具(无耻的插件)是我写的名为Caterwaul的Javascript-to-Javascript编译器。 它可以让你对语法树进行模式匹配,并且知道如何遍历它们,这对你的情况可能是有用的。 如果你想从短期执行中build立一个dynamic的跟踪(如果你想得到一个准确和详细的结果,可能是你最好的select)。

我认为http://doctorjs.org/可能适合您的需求&#x3002; 它有一个不错的JSON API,在github上可用,由mozilla备份。 它是用JS自己写的,通常做得很好(包括处理多态性等)。

以下是我可以看到的一些解决scheme:

  1. 使用Aptana Call Graph视图
    Aptana是基于Eclipse的IDE,允许您编辑和debuggingJavascript代码。

  2. 使用Dynatrace
    Dynatrace是一个有用的工具,可以让您跟踪代码并查看调用图和热点。

  3. 使用Firebug
    着名的Firefox开发者插件

这里生成的大部分调用图都是dynamic的 ,即您将看到给定一组操作的调用图。 如果您正在查找静态调用图,请首先检查Aptana。 静态调用图可能不会让您看到dynamic调用(通过eval()运行的代码)。

对于js方法,请查看arguments.callee.caller 。 它提供了调用你所在函数的函数,你可以调出堆栈。 有一个例子在这个线程http://bytes.com/topic/javascript/answers/470251-recursive-functions-arguments-callee-caller

请注意,这可能不适用于所有的浏览器,当您到达“调用堆栈”或本机函数的顶部时,您可能会遇到一些意想不到的事情,所以请自担风险。

我自己的例子在IE9和Chrome 10中工作(没有testing任何其他浏览器)。

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

你可以得到一个Call Graph最接近的东西是操纵一个完整的Javascript AST。 这可能与犀牛,看看这篇文章: http : //tagneto.blogspot.com/2010/03/requirejs-kicking-some-ast.html

来自post的例子:

 //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来构build任何types的调用图或依赖链。

与NodeJS不直接相关,但一般与JavaScript相关,SAP已经发布了一个与HANA相关的Web IDE(也可以从HANA Cloud免费获得 – 详情请见http://scn.sap.com/community/developer-center/ cloud-platform / blog / 2014/04/15 / sap-hana-web-ide-online-tutorial )。

在这个Web IDE中,有一个基于REST的服务,它主要分析JavaScript内容(但不仅仅是创build一个Call Graph)。 该服务的许多消费者,如代码导航。

这里有更多的信息(见functionstream程部分): http : //scn.sap.com/community/developer-center/hana/blog/2014/12/02/sap-hana-sps-09-new-developer-function- SAP-花-基于Web的开发,工作台

注意:我是这项服务的主要开发者。

Interesting Posts