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

时间:2023-02-02 20:23:12

Are there any Call-Graph and/or Control-Flow-Graph generators for JavaScript?

JavaScript有调用图和/或控制流图生成器吗?

Call Graph - http://en.wikipedia.org/wiki/Call_graph

调用图——http://en.wikipedia.org/wiki/Call_graph

Control Flow Graph - http://en.wikipedia.org/wiki/Control_flow_graph

控制流图- http://en.wikipedia.org/wiki/Control_flow_graph

EDIT: I am looking specifically for a static tool that let me access the graph using some API/code

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

8 个解决方案

#1


10  

To do this, you need:

为此,您需要:

  • parsing,
  • 解析、
  • name resolution (handling scoping)
  • 名称解析(处理范围)
  • type analysis (while JavaScript is arguably "dynamically typed", there are all kinds of typed constants including function constants that are of specific interest here)
  • 类型分析(尽管JavaScript可以说是“动态类型化”的,但这里有各种类型的常量,包括特定兴趣的函数常量)
  • control flow analysis (to build up the structure of the control flow graphs within methods)
  • 控制流分析(在方法中建立控制流图的结构)
  • data flow analysis (to track where those types are generated/used)
  • 数据流分析(跟踪生成/使用这些类型的位置)
  • what amounts to global points-to analysis (to track function constants passed between functions as values to a point of application).
  • 什么是全局点—分析(跟踪函数之间作为值传递到应用点的函数常量)。

How to do it is pretty well documented in the compiler literature. However, implementing this matter of considerable sweat, so answers of the form of "you can use a parser result to get what you want" rather miss the point.

如何做到这一点在编译器文献中有很好的说明。然而,要实现这一相当大的汗水,那么“您可以使用解析器结果来得到您想要的结果”的形式的答案就会忽略这一点。

If you could apply all this machinery, what you'll get as a practical result is a conservative answer, e.g., "A may call B". This is all you know anyway, consider

如果你能应用所有这些机制,你将得到的实际结果是一个保守的答案,例如,“a可以叫B”。这就是你所知道的,想想

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

Because a tool sometime simply can't reason about complex logic, you may get "A may call B" even when the application designer knows it isn't possible:

因为一个工具有时根本无法推理复杂的逻辑,你可能会得到“a可能会调用B”,即使应用程序设计者知道这是不可能的:

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

eval makes the problem worse, because you need to track string value results that arrive at eval commands and parse them to get some kind of clue as to what code is being evaled, and which functions that eval'd code might call. Things get really nasty if somebody passes "eval" in a string to eval :-{ You also likely need to model the program execution context; I suspect there are lots of browser APIs that include callbacks.

eval使问题变得更糟,因为您需要跟踪到达eval命令的字符串值结果,并对它们进行解析,以获得正在调用的代码以及eval代码可能调用的函数的某种线索。如果有人通过字符串“eval”来eval:-{您可能还需要对程序执行上下文建模;我怀疑有很多包含回调的浏览器api。

If somebody offers you tool that has all the necessary machinery completely configured to solve your problem out of the box, that would obviously be great. My suspicion is you won't get such an offer, because such a tool doesn't exist. The reason is all that infrastructure needed; its hard to build and hardly anybody can justify it for just one tool. Even an "optimizing JavaScript compiler" if you can find one likely won't have all this machinery, especially the global analysis, and what it does have is unlikely to be packaged in a form designed for easy consumption for your purpose.

如果有人为你提供了所有必要的机器设备,完全可以解决你的问题,那显然很好。我怀疑你不会得到这样的提议,因为这样的工具并不存在。原因在于所需的基础设施;它很难构建,而且几乎没有人能仅用一种工具来证明它。即使是“优化JavaScript编译器”(如果您能找到的话),也很可能不具备所有这些功能,尤其是全局分析,而且它所具备的功能也不太可能被打包成为便于您使用而设计的形式。

I've been beating my head on this problem since I started programming in 1969 (some of my programs back then were compilers and I wanted all this stuff). The only way to get this is to amortize the cost of all this machinery across lots of tools.

自从1969年开始编程以来,我就一直在这个问题上绞尽脑汁(当时我的一些程序是编译器,我想要所有这些东西)。得到这个的唯一方法是在很多工具上摊销所有这些机器的成本。

My company offers the DMS Software Reengineering Toolkit, a package of generic compiler analysis and transformation machinery, with a variety of industrial strength computer langauge front-ends (including C, C++, COBOL and yes, JavaScript). DMS offers APIs to enable custom tools to be constructed on its generic foundations.

我的公司提供DMS软件Reengineering Toolkit,一个通用编译器分析和转换机器的软件包,具有各种工业强度的计算机langauge前端(包括C、c++、COBOL和yes, JavaScript)。DMS提供了api来支持在通用基础上构建自定义工具。

The generic machinery listed at the top of the message is all present in DMS, including control flow graph and data flow analysis available through a clean documented API. That flow analysis has to be tied to specific language front ends. That takes some work too, and so we haven't done it for all languages yet. We have done this for C [tested on systems of 18,000 compilation units as a monolith, including computing the call graph for the 250,000 functions present, including indirect function calls!], COBOL and Java and we're working on C++.

在消息顶部列出的通用机制都在DMS中,包括控制流图和数据流分析,可以通过干净的文档化API进行分析。流分析必须绑定到特定的语言前端。这也需要一些工作,所以我们还没有对所有语言都做。我们已经为C做了这样的测试[在18000个编译单元的系统上测试为一个整体,包括计算呈现的250000个函数的调用图,包括间接函数调用!, COBOL和Java,我们正在开发c++。

DMS has the same "JavaScript" parser answer as other answers in this thread, and viewed from just that perspective DMS isn't any better than the other answers that say "build it on top of a parser". The distinction should be clear: the machinery is already present in DMS, so the work is not one of implement the machinery and tying to the parser; it is just tying it to the parser. This is still a bit of work, but a hell of a lot less than if you just start with a parser.

DMS与这个线程中的其他答案具有相同的“JavaScript”解析器答案,从这个角度来看,DMS并不比“在解析器之上构建它”的其他答案更好。区别应该很清楚:机制已经存在于DMS中,所以工作不是实现机制并与解析器绑定;它只是将它绑定到解析器。这仍然是一项工作,但是比从解析器开始时要少得多。

#2


5  

WALA is an open-source program analysis framework that can build static call graphs and control-flow graphs for JavaScript:

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

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

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

One caveat is that the call graphs may be missing some edges in the presence of eval, with, and other hard-to-analyze constructs. Also, we're still working on scalability; WALA can't yet analyze jquery in a reasonable amount of time, but some other frameworks can be analyzed. Also, our documentation for building JavaScript call graphs isn't great at the moment (improving it is on my TODO list).

需要注意的是,在eval、with和其他难以分析的构造中,调用图可能缺少一些边。此外,我们还在研究可扩展性;WALA还不能在合理的时间内分析jquery,但是可以分析其他一些框架。此外,我们构建JavaScript调用图的文档目前也不是很好(改进它在我的TODO列表中)。

We're actively working on this code, so if you try it and run into issues, you can email the WALA mailing list (https://lists.sourceforge.net/lists/listinfo/wala-wala) or contact me.

我们正在积极地处理这段代码,所以如果您尝试并遇到问题,您可以通过电子邮件发送WALA邮件列表(https://lists.sourceforge.net/lists/listinfo/wala)或与我联系。

#3


4  

In general it isn't possible to do this. The reason is that functions are first-class and dynamically typed, so for example:

一般来说,这是不可能的。原因是函数是一流的,并且是动态类型的,例如:

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

There are two unknowns. One is the version of 'map' that is called (since Javascript polymorphism can't be resolved statically in the general case), and the other is the value assigned to 'each', which also can't be statically resolved. The only static properties this code has are that some 'map' method is called on some function we got from 'another_function'.

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

If, however, that is enough information, there are two resources that might be helpful. One is a general-purpose Javascript parser, especially built using parser combinators (Chris Double's jsparse is a good one). This will let you annotate the parse tree as it is being constructed, and you can add a custom rule to invocation nodes to record graph edges.

但是,如果这已经是足够的信息,那么有两种资源可能是有用的。一种是通用的Javascript解析器,特别是使用解析器组合器构建的(Chris Double的jsparsever是一个很好的解析器)。这将使您可以在构建解析树时对其进行注释,并可以向调用节点添加自定义规则来记录图边。

The other tool that you might find useful (shameless plug) is a Javascript-to-Javascript compiler I wrote called Caterwaul. It lets you do pattern-matching against syntax trees and knows how to walk over them, which might be useful in your case. It could also help if you wanted to build a dynamic trace from short-term execution (probably your best bet if you want an accurate and detailed result).

另一个有用的工具(无耻的插件)是我编写的javascript编译器Caterwaul。它允许您对语法树进行模式匹配,并知道如何遍历它们,这在您的案例中可能是有用的。如果您希望从短期执行中构建动态跟踪(如果您希望得到准确和详细的结果,这可能是您的最佳选择),那么它也可能会有所帮助。

#4


2  

I think http://doctorjs.org/ may fit your needs. It has a nice JSON API, is available on github, backed up by mozilla. It's written in JS itself and generally does stuff pretty well (including dealing with polymorphism etc).

我认为http://doctorjs.org/可能符合你的需要。它有一个很好的JSON API,可以在github上使用,由mozilla支持。它是用JS编写的,并且通常做得很好(包括处理多态性等)。

#5


2  

Here are a few solutions I can see:

以下是我能看到的一些解决方案:

  1. Use Aptana Call Graph view
    Aptana is an IDE based on Eclipse that permit you edit and debugging Javascript code.

    Aptana是一个基于Eclipse的IDE,允许您编辑和调试Javascript代码。

  2. Use Dynatrace
    Dynatrace is a useful tool that let you live trace your code and see the call graph and hot spots.

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

  3. Use Firebug
    The famous developer addon on Firefox

    在Firefox上使用著名的开发插件Firebug

Most of the call graphs generated here will be dynamic, ie you'll see the call graph for a given set of actions. If you're looking for static call graphs check Aptana first. Static call graphs may not let you see dynamic calls (code running through eval()).

这里生成的大多数调用图都是动态的,即您将看到给定一组动作的调用图。如果您正在寻找静态调用图,首先检查Aptana。静态调用图可能不会让您看到动态调用(在eval()中运行的代码)。

#6


1  

For a js approach, check out arguments.callee.caller. It gives you the function that called the function you are in and you can recurse up the call stack. There is an example in this thread http://bytes.com/topic/javascript/answers/470251-recursive-functions-arguments-callee-caller.

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

Be aware that this may not work in all browsers and you may run in to some unexpected things when you get to the top of the "call stack" or native functions so use at your own risk.

请注意,这可能并不适用于所有浏览器,当您到达“调用堆栈”或本机函数的顶端时,您可能会遇到一些意想不到的问题,所以您可以自行使用。

My own example works in IE9 and Chrome 10 (didn't test any other browsers).

我自己的例子适用于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>

#7


0  

The closest thing you can get to a Call Graph is manipulating a full Javascript AST. This is possible with Rhino, take a look at this article: http://tagneto.blogspot.com/2010/03/requirejs-kicking-some-ast.html

最接近调用图的是操作一个完整的Javascript AST

Example from the 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());
}

In either Javascript or Java, you could walk the AST to build whatever type of call graph or dependency chain you'd like.

在Javascript或Java中,可以遍历AST来构建任何类型的调用图或依赖链。

#8


0  

Not related directly to NodeJS, but generally to JavaScript, SAP has released a Web IDE related to HANA (but also accessible freely from the HANA Cloud - see more details here http://scn.sap.com/community/developer-center/cloud-platform/blog/2014/04/15/sap-hana-web-ide-online-tutorial).

SAP并不直接与NodeJS相关,但通常与JavaScript有关,它发布了一个与HANA相关的Web IDE(但也可以从HANA云免费访问)。

In this Web IDE, there is a REST-based service that analyzes JavaScript content with primary focus (but not only) on creating a Call Graph. There are many consumers of that service, like Code Navigation.

在这个Web IDE中,有一个基于rest的服务,它以创建调用图为主要焦点(但不只是)分析JavaScript内容。该服务有许多使用者,如代码导航。

Some more information here (see the Function Flow part): http://scn.sap.com/community/developer-center/hana/blog/2014/12/02/sap-hana-sps-09-new-developer-features-sap-hana-web-based-development-workbench

这里有更多的信息(参见函数流部分):http://scn.sap.com/community/developer-center/ hana/bloga/blog/2014/12/02/sap-sps-09-new -developer-feature -sap-hana-web-base -development-workbench

Note: I am the main developer of this service.

注意:我是这个服务的主要开发人员。

#1


10  

To do this, you need:

为此,您需要:

  • parsing,
  • 解析、
  • name resolution (handling scoping)
  • 名称解析(处理范围)
  • type analysis (while JavaScript is arguably "dynamically typed", there are all kinds of typed constants including function constants that are of specific interest here)
  • 类型分析(尽管JavaScript可以说是“动态类型化”的,但这里有各种类型的常量,包括特定兴趣的函数常量)
  • control flow analysis (to build up the structure of the control flow graphs within methods)
  • 控制流分析(在方法中建立控制流图的结构)
  • data flow analysis (to track where those types are generated/used)
  • 数据流分析(跟踪生成/使用这些类型的位置)
  • what amounts to global points-to analysis (to track function constants passed between functions as values to a point of application).
  • 什么是全局点—分析(跟踪函数之间作为值传递到应用点的函数常量)。

How to do it is pretty well documented in the compiler literature. However, implementing this matter of considerable sweat, so answers of the form of "you can use a parser result to get what you want" rather miss the point.

如何做到这一点在编译器文献中有很好的说明。然而,要实现这一相当大的汗水,那么“您可以使用解析器结果来得到您想要的结果”的形式的答案就会忽略这一点。

If you could apply all this machinery, what you'll get as a practical result is a conservative answer, e.g., "A may call B". This is all you know anyway, consider

如果你能应用所有这些机制,你将得到的实际结果是一个保守的答案,例如,“a可以叫B”。这就是你所知道的,想想

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

Because a tool sometime simply can't reason about complex logic, you may get "A may call B" even when the application designer knows it isn't possible:

因为一个工具有时根本无法推理复杂的逻辑,你可能会得到“a可能会调用B”,即使应用程序设计者知道这是不可能的:

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

eval makes the problem worse, because you need to track string value results that arrive at eval commands and parse them to get some kind of clue as to what code is being evaled, and which functions that eval'd code might call. Things get really nasty if somebody passes "eval" in a string to eval :-{ You also likely need to model the program execution context; I suspect there are lots of browser APIs that include callbacks.

eval使问题变得更糟,因为您需要跟踪到达eval命令的字符串值结果,并对它们进行解析,以获得正在调用的代码以及eval代码可能调用的函数的某种线索。如果有人通过字符串“eval”来eval:-{您可能还需要对程序执行上下文建模;我怀疑有很多包含回调的浏览器api。

If somebody offers you tool that has all the necessary machinery completely configured to solve your problem out of the box, that would obviously be great. My suspicion is you won't get such an offer, because such a tool doesn't exist. The reason is all that infrastructure needed; its hard to build and hardly anybody can justify it for just one tool. Even an "optimizing JavaScript compiler" if you can find one likely won't have all this machinery, especially the global analysis, and what it does have is unlikely to be packaged in a form designed for easy consumption for your purpose.

如果有人为你提供了所有必要的机器设备,完全可以解决你的问题,那显然很好。我怀疑你不会得到这样的提议,因为这样的工具并不存在。原因在于所需的基础设施;它很难构建,而且几乎没有人能仅用一种工具来证明它。即使是“优化JavaScript编译器”(如果您能找到的话),也很可能不具备所有这些功能,尤其是全局分析,而且它所具备的功能也不太可能被打包成为便于您使用而设计的形式。

I've been beating my head on this problem since I started programming in 1969 (some of my programs back then were compilers and I wanted all this stuff). The only way to get this is to amortize the cost of all this machinery across lots of tools.

自从1969年开始编程以来,我就一直在这个问题上绞尽脑汁(当时我的一些程序是编译器,我想要所有这些东西)。得到这个的唯一方法是在很多工具上摊销所有这些机器的成本。

My company offers the DMS Software Reengineering Toolkit, a package of generic compiler analysis and transformation machinery, with a variety of industrial strength computer langauge front-ends (including C, C++, COBOL and yes, JavaScript). DMS offers APIs to enable custom tools to be constructed on its generic foundations.

我的公司提供DMS软件Reengineering Toolkit,一个通用编译器分析和转换机器的软件包,具有各种工业强度的计算机langauge前端(包括C、c++、COBOL和yes, JavaScript)。DMS提供了api来支持在通用基础上构建自定义工具。

The generic machinery listed at the top of the message is all present in DMS, including control flow graph and data flow analysis available through a clean documented API. That flow analysis has to be tied to specific language front ends. That takes some work too, and so we haven't done it for all languages yet. We have done this for C [tested on systems of 18,000 compilation units as a monolith, including computing the call graph for the 250,000 functions present, including indirect function calls!], COBOL and Java and we're working on C++.

在消息顶部列出的通用机制都在DMS中,包括控制流图和数据流分析,可以通过干净的文档化API进行分析。流分析必须绑定到特定的语言前端。这也需要一些工作,所以我们还没有对所有语言都做。我们已经为C做了这样的测试[在18000个编译单元的系统上测试为一个整体,包括计算呈现的250000个函数的调用图,包括间接函数调用!, COBOL和Java,我们正在开发c++。

DMS has the same "JavaScript" parser answer as other answers in this thread, and viewed from just that perspective DMS isn't any better than the other answers that say "build it on top of a parser". The distinction should be clear: the machinery is already present in DMS, so the work is not one of implement the machinery and tying to the parser; it is just tying it to the parser. This is still a bit of work, but a hell of a lot less than if you just start with a parser.

DMS与这个线程中的其他答案具有相同的“JavaScript”解析器答案,从这个角度来看,DMS并不比“在解析器之上构建它”的其他答案更好。区别应该很清楚:机制已经存在于DMS中,所以工作不是实现机制并与解析器绑定;它只是将它绑定到解析器。这仍然是一项工作,但是比从解析器开始时要少得多。

#2


5  

WALA is an open-source program analysis framework that can build static call graphs and control-flow graphs for JavaScript:

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

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

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

One caveat is that the call graphs may be missing some edges in the presence of eval, with, and other hard-to-analyze constructs. Also, we're still working on scalability; WALA can't yet analyze jquery in a reasonable amount of time, but some other frameworks can be analyzed. Also, our documentation for building JavaScript call graphs isn't great at the moment (improving it is on my TODO list).

需要注意的是,在eval、with和其他难以分析的构造中,调用图可能缺少一些边。此外,我们还在研究可扩展性;WALA还不能在合理的时间内分析jquery,但是可以分析其他一些框架。此外,我们构建JavaScript调用图的文档目前也不是很好(改进它在我的TODO列表中)。

We're actively working on this code, so if you try it and run into issues, you can email the WALA mailing list (https://lists.sourceforge.net/lists/listinfo/wala-wala) or contact me.

我们正在积极地处理这段代码,所以如果您尝试并遇到问题,您可以通过电子邮件发送WALA邮件列表(https://lists.sourceforge.net/lists/listinfo/wala)或与我联系。

#3


4  

In general it isn't possible to do this. The reason is that functions are first-class and dynamically typed, so for example:

一般来说,这是不可能的。原因是函数是一流的,并且是动态类型的,例如:

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

There are two unknowns. One is the version of 'map' that is called (since Javascript polymorphism can't be resolved statically in the general case), and the other is the value assigned to 'each', which also can't be statically resolved. The only static properties this code has are that some 'map' method is called on some function we got from 'another_function'.

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

If, however, that is enough information, there are two resources that might be helpful. One is a general-purpose Javascript parser, especially built using parser combinators (Chris Double's jsparse is a good one). This will let you annotate the parse tree as it is being constructed, and you can add a custom rule to invocation nodes to record graph edges.

但是,如果这已经是足够的信息,那么有两种资源可能是有用的。一种是通用的Javascript解析器,特别是使用解析器组合器构建的(Chris Double的jsparsever是一个很好的解析器)。这将使您可以在构建解析树时对其进行注释,并可以向调用节点添加自定义规则来记录图边。

The other tool that you might find useful (shameless plug) is a Javascript-to-Javascript compiler I wrote called Caterwaul. It lets you do pattern-matching against syntax trees and knows how to walk over them, which might be useful in your case. It could also help if you wanted to build a dynamic trace from short-term execution (probably your best bet if you want an accurate and detailed result).

另一个有用的工具(无耻的插件)是我编写的javascript编译器Caterwaul。它允许您对语法树进行模式匹配,并知道如何遍历它们,这在您的案例中可能是有用的。如果您希望从短期执行中构建动态跟踪(如果您希望得到准确和详细的结果,这可能是您的最佳选择),那么它也可能会有所帮助。

#4


2  

I think http://doctorjs.org/ may fit your needs. It has a nice JSON API, is available on github, backed up by mozilla. It's written in JS itself and generally does stuff pretty well (including dealing with polymorphism etc).

我认为http://doctorjs.org/可能符合你的需要。它有一个很好的JSON API,可以在github上使用,由mozilla支持。它是用JS编写的,并且通常做得很好(包括处理多态性等)。

#5


2  

Here are a few solutions I can see:

以下是我能看到的一些解决方案:

  1. Use Aptana Call Graph view
    Aptana is an IDE based on Eclipse that permit you edit and debugging Javascript code.

    Aptana是一个基于Eclipse的IDE,允许您编辑和调试Javascript代码。

  2. Use Dynatrace
    Dynatrace is a useful tool that let you live trace your code and see the call graph and hot spots.

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

  3. Use Firebug
    The famous developer addon on Firefox

    在Firefox上使用著名的开发插件Firebug

Most of the call graphs generated here will be dynamic, ie you'll see the call graph for a given set of actions. If you're looking for static call graphs check Aptana first. Static call graphs may not let you see dynamic calls (code running through eval()).

这里生成的大多数调用图都是动态的,即您将看到给定一组动作的调用图。如果您正在寻找静态调用图,首先检查Aptana。静态调用图可能不会让您看到动态调用(在eval()中运行的代码)。

#6


1  

For a js approach, check out arguments.callee.caller. It gives you the function that called the function you are in and you can recurse up the call stack. There is an example in this thread http://bytes.com/topic/javascript/answers/470251-recursive-functions-arguments-callee-caller.

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

Be aware that this may not work in all browsers and you may run in to some unexpected things when you get to the top of the "call stack" or native functions so use at your own risk.

请注意,这可能并不适用于所有浏览器,当您到达“调用堆栈”或本机函数的顶端时,您可能会遇到一些意想不到的问题,所以您可以自行使用。

My own example works in IE9 and Chrome 10 (didn't test any other browsers).

我自己的例子适用于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>

#7


0  

The closest thing you can get to a Call Graph is manipulating a full Javascript AST. This is possible with Rhino, take a look at this article: http://tagneto.blogspot.com/2010/03/requirejs-kicking-some-ast.html

最接近调用图的是操作一个完整的Javascript AST

Example from the 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());
}

In either Javascript or Java, you could walk the AST to build whatever type of call graph or dependency chain you'd like.

在Javascript或Java中,可以遍历AST来构建任何类型的调用图或依赖链。

#8


0  

Not related directly to NodeJS, but generally to JavaScript, SAP has released a Web IDE related to HANA (but also accessible freely from the HANA Cloud - see more details here http://scn.sap.com/community/developer-center/cloud-platform/blog/2014/04/15/sap-hana-web-ide-online-tutorial).

SAP并不直接与NodeJS相关,但通常与JavaScript有关,它发布了一个与HANA相关的Web IDE(但也可以从HANA云免费访问)。

In this Web IDE, there is a REST-based service that analyzes JavaScript content with primary focus (but not only) on creating a Call Graph. There are many consumers of that service, like Code Navigation.

在这个Web IDE中,有一个基于rest的服务,它以创建调用图为主要焦点(但不只是)分析JavaScript内容。该服务有许多使用者,如代码导航。

Some more information here (see the Function Flow part): http://scn.sap.com/community/developer-center/hana/blog/2014/12/02/sap-hana-sps-09-new-developer-features-sap-hana-web-based-development-workbench

这里有更多的信息(参见函数流部分):http://scn.sap.com/community/developer-center/ hana/bloga/blog/2014/12/02/sap-sps-09-new -developer-feature -sap-hana-web-base -development-workbench

Note: I am the main developer of this service.

注意:我是这个服务的主要开发人员。