Is there a way to print out the call graph and get the data in the call graph?

212 views
Skip to first unread message

jff24grd

unread,
Jun 24, 2010, 3:40:58 PM6/24/10
to Closure Compiler Discuss
For example I have a js file:


function addEvent()
{
addDay();
}

function addDay()
{
addMin();
}


function addMin()
{
document.write("Hello World")
}

Can i get a tree showing addEvent->addDay->addMin

and then each node contains the code inside it?

thanks.

Bjorn Tipling

unread,
Jun 24, 2010, 3:46:50 PM6/24/10
to Closure Compiler Discuss
That might require solving the halting problem, unless I misunderstand
what you're trying to achieve. What would it show in case of a
recursive function?

jff24grd

unread,
Jun 24, 2010, 4:14:23 PM6/24/10
to Closure Compiler Discuss
I thought that the closure compiler parser can at least make a tree
for you with the function names and calls correct? that's where i
want to start off at least.

Nick Santos

unread,
Jun 24, 2010, 4:25:51 PM6/24/10
to closure-comp...@googlegroups.com
Alan can answer this question better than I can, but he is at a conference today. The short answer is that you can do this from the java api. Take a look at nameReferenceGraphPath in CompilerOptions.
http://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/javascript/jscomp/CompilerOptions.java

The graph can be serialized to DOT and fed to your favorite graph visualizer.

Your mileage my vary depending on how many type annotations you code has. (the graph will fallback on UNKNOWN edges if it can't figure out what you're doing).

Nick

jff24grd

unread,
Jun 25, 2010, 8:03:16 AM6/25/10
to Closure Compiler Discuss
The only thing i found here was printing out the path it takes in the
code. I can't figure out where it will print out text to graph of my
actual Javascript

On Jun 24, 4:25 pm, Nick Santos <nicksan...@google.com> wrote:
> Alan can answer this question better than I can, but he is at a conference
> today. The short answer is that you can do this from the java api. Take a
> look at nameReferenceGraphPath in CompilerOptions.http://code.google.com/p/closure-compiler/source/browse/trunk/src/com...

Bjorn Tipling

unread,
Jun 25, 2010, 3:28:30 PM6/25/10
to Closure Compiler Discuss
I don't believe what you want is possible. How would the compiler know
when to stop printing the tree? It's called the halting problem:

http://en.wikipedia.org/wiki/Halting_problem

It might seem obvious that the compiler would stop printing the tree
with a simple example such as the one you provided, but for the
compiler to be written in a way that it could do this for all possible
programs is not realistic.

I am not familiar with what is in the Java API, maybe there's some
herculean effort to achieve some kind of tree as you want, but I'm
sure I could come up with an input that would break this feature (or
reach its limits) if it does.

The only other output features I know of are those described in the
docs for the service api which give you warnings, errors and
statistics for "output_info". Would be interested to learn if I'm
wrong from someone more knowledgable about the compiler.

Good luck.

Alan Leung

unread,
Jun 25, 2010, 4:21:33 PM6/25/10
to closure-comp...@googlegroups.com
Jason:

I am not sure what you mean? Are you able to get the output from the compiler?

That text file is a DOT file. You need a program to display that graph graphically.


Bjorn:

You are right about the halting problem. Call graph construction probably falls in the same category as pointer analysis which is undecidable in general. That is true for almost everything we do in compiler optimizations where lots of problems are inherently undecidable. There are ways to get around it by lowering what we are trying to solve. If you are interested, I would like to point you to chapter 1.1 of


which gives a pretty good explanation what this.

-Alan

jff24grd

unread,
Jun 30, 2010, 4:16:49 PM6/30/10
to Closure Compiler Discuss
Alan,

I was able to get a graph, but it was not the graph of the file I gave
it as input. It was the call graph of the actual closure compiler. I'm
trying to get a directed graph of the actual input (the javascript
file) any help or pointers would be appreciated.



On Jun 25, 4:21 pm, Alan Leung <acle...@gmail.com> wrote:
> Jason:
>
> I am not sure what you mean? Are you able to get the output from the
> compiler?
>
> That text file is a DOT file. You need a program to display that graph
> graphically.
>
> See:http://www.graphviz.org/
>
> Bjorn:
>
> You are right about the halting problem. Call graph construction probably
> falls in the same category as pointer analysis which is undecidable in
> general. That is true for almost everything we do in compiler optimizations
> where lots of problems are inherently undecidable. There are ways to get
> around it by lowering what we are trying to solve. If you are interested, I
> would like to point you to chapter 1.1 of
>
> http://books.google.com/books?id=RLjt0xSj8DcC&lpg=PP1&dq=Principles%2...
>
> which gives a pretty good explanation what this.
>
> -Alan
>

Alan Leung

unread,
Jun 30, 2010, 5:40:02 PM6/30/10
to closure-comp...@googlegroups.com

I was able to get a graph, but it was not the graph of the file I gave
it as input. It was the call graph of the actual closure compiler.

Really? I am not sure if there are any facilities in Closure Compiler that can give a profiling callgraph of itself....

Can you post your result somewhere? 
 
I'm
trying to get a directed graph of the actual input (the javascript
file) any help or pointers would be appreciated.


-Alan

jff24grd

unread,
Jul 1, 2010, 7:19:39 PM7/1/10
to Closure Compiler Discuss
I was refering to the option --print_pass_graph, which just prints the
program execution tree?

0 error(s), 1 warning(s)
digraph LinkedGraph {
node [color=lightblue2, style=filled];
LDN100 [label="renameCssNames" color="white"];
LDN101 [label="replaceMessages" color="white"];
LDN102 [label="processDefines" color="white"];
LDN103 [label="beforeStandardOptimizations" color="white"];
LDN104 [label="optimizeArgumentsArray" color="white"];
LDN105 [label="removeAbstractMethods" color="white"];
LDN106 [label="beforeMainOptimizations" color="white"];
LDN107 [label="inlineVariables" color="white"];
LDN108 [label="removeConstantExpressions" color="white"];
LDN109 [label="minimizeExitPoints" color="white"];
LDN110 [label="foldConstants" color="white"];
LDN111 [label="peepholeOptimizations" color="white"];
LDN112 [label="removeUnreachableCode" color="white"];
LDN113 [label="inlineFunctions" color="white"];
LDN114 [label="deadAssignmentsElimination" color="white"];
LDN115 [label="removeUnusedVars" color="white"];
LDN116 [label="beforeModuleMotion" color="white"];
LDN117 [label="afterModuleMotion" color="white"];
LDN118 [label="coalesceVariableNames" color="white"];
LDN119 [label="convertToDottedProperties" color="white"];
LDN120 [label="collapseVariableDeclarations" color="white"];
LDN121 [label="denormalize" color="white"];
LDN122 [label="invertNames" color="white"];
LDN123 [label="renameVars" color="white"];
LDN124 [label="renameLabels" color="white"];
LDN94 [label="processGoogScopeAliases" color="white"];
LDN95 [label="suspiciousCode" color="white"];
LDN96 [label="checkControlStructures" color="white"];
LDN97 [label="processProvidesAndRequires" color="white"];
LDN98 [label="checkVars" color="white"];
LDN99 [label="checkControlFlow" color="white"];
LDN100 -> LDN101;
LDN101 -> LDN102;
LDN102 -> LDN103;
LDN103 -> LDN104;
LDN104 -> LDN105;
LDN105 -> LDN106;
LDN106 -> LDN107;
LDN107 -> LDN108;
LDN108 -> LDN109;
LDN109 -> LDN110;
LDN110 -> LDN111;
LDN111 -> LDN112;
LDN112 -> LDN113;
LDN113 -> LDN114;
LDN114 -> LDN115;
LDN115 -> LDN107;
LDN115 -> LDN116;
LDN116 -> LDN117;
LDN117 -> LDN118;
LDN118 -> LDN119;
LDN119 -> LDN120;
LDN120 -> LDN121;
LDN121 -> LDN122;
LDN122 -> LDN123;
LDN123 -> LDN124;
LDN94 -> LDN95;
LDN95 -> LDN96;
LDN96 -> LDN97;
LDN97 -> LDN98;
LDN98 -> LDN99;
LDN99 -> LDN100;

John Lenz

unread,
Jul 1, 2010, 7:58:07 PM7/1/10
to closure-comp...@googlegroups.com
Did you see Nick's response?

The short answer is that you can do this from the java api. Take a look at nameReferenceGraphPath in CompilerOptions.

The graph can be serialized to DOT and fed to your favorite graph visualizer.

The call graph report is not exposed on the command-line.
Message has been deleted

jff24grd

unread,
Jul 2, 2010, 10:55:39 AM7/2/10
to Closure Compiler Discuss
On Jul 1, 7:58 pm, John Lenz <concavel...@gmail.com> wrote:
> Did you see Nick's response?

Ok great, but nameReferenceGraphPath is not set anywhere except in the
constructor to null.

So nothing is setting that string anywhere in the code. I did a
search on the trunk.

Any new thoughts?




>
> The short answer is that you can do this from the java api. Take a look at
> nameReferenceGraphPath in CompilerOptions.http://code.google.com/p/closure-compiler/source/browse/trunk/src/com...
>
> The graph can be serialized to DOT and fed to your favorite graph
> visualizer.
>
> The call graph report is not exposed on the command-line.
>

John Lenz

unread,
Jul 2, 2010, 11:28:22 AM7/2/10
to closure-comp...@googlegroups.com
Hmmm.  Looks like a bit of code didn't make it into the public release, I'll get that rectified.  For now you will need to add a new pass to DefaultPassConfig and add a reference to it:

    private final PassFactory printNameReferenceGraph =
        new PassFactory("printNameReferenceGraph", true) {
      @Override
      protected CompilerPass createInternal(final AbstractCompiler compiler) {
        return new CompilerPass() {
          @Override
          public void process(Node externs, Node jsRoot) {
            NameReferenceGraphConstruction gc =
                new NameReferenceGraphConstruction(compiler);
            gc.process(externs, jsRoot);
            String graphFileName = options.nameReferenceGraphPath;
            try {
              Files.write(DotFormatter.toDot(gc.getNameReferenceGraph()),
                  new File(graphFileName),
                  Charsets.UTF_8);
            } catch (IOException e) {
              logger.severe(
                  "Error writing compiler report to " + graphFileName);
            }
          }
        };
      }
    };

On Fri, Jul 2, 2010 at 7:52 AM, jff24grd <jason.w...@gmail.com> wrote:
Ok great, but nameReferenceGraphPath is not set anywhere except in the
constructor to null.

So nothing is setting that string anywhere in the code.  I did a
search on the trunk.

Any new thoughts?


If I make the options
CompilerOptions options = new CompilerOptions();


On Jul 1, 7:58 pm, John Lenz <concavel...@gmail.com> wrote:
> Did you see Nick's response?
>
> The short answer is that you can do this from the java api. Take a look at

>
> The graph can be serialized to DOT and fed to your favorite graph
> visualizer.
>
> The call graph report is not exposed on the command-line.
>

jff24grd

unread,
Jul 2, 2010, 1:37:24 PM7/2/10
to Closure Compiler Discuss
Thanks.


I checked out a copy of the source instead of just using the jar. I
imported it into exclipse, added the code and wrote a test class
(AaaaTest).

I'm getting an exception

Exception in thread "main" java.util.MissingResourceException: Can't
find bundle for base name
rhino_ast.java.com.google.javascript.rhino.Messages, locale en_US
at java.util.ResourceBundle.throwMissingResourceException(Unknown
Source)
at java.util.ResourceBundle.getBundleImpl(Unknown Source)
at java.util.ResourceBundle.getBundle(Unknown Source)
at
com.google.javascript.rhino.ScriptRuntime.getMessage(ScriptRuntime.java:
466)
at
com.google.javascript.rhino.ScriptRuntime.getMessage0(ScriptRuntime.java:
423)
at
com.google.javascript.jscomp.RhinoErrorReporter.<init>(RhinoErrorReporter.java:
76)
at
com.google.javascript.jscomp.RhinoErrorReporter.<init>(RhinoErrorReporter.java:
70)
at com.google.javascript.jscomp.RhinoErrorReporter
$OldRhinoErrorReporter.<init>(RhinoErrorReporter.java:137)
at com.google.javascript.jscomp.RhinoErrorReporter
$OldRhinoErrorReporter.<init>(RhinoErrorReporter.java:136)
at
com.google.javascript.jscomp.RhinoErrorReporter.forOldRhino(RhinoErrorReporter.java:
102)
at com.google.javascript.jscomp.Compiler.<init>(Compiler.java:138)
at com.google.javascript.jscomp.Compiler.<init>(Compiler.java:169)
at com.google.javascript.jscomp.AaaaTest.runCompiler(AaaaTest.java:
56)
at com.google.javascript.jscomp.AaaaTest.main(AaaaTest.java:99)


I'm sure I am doing something wrong that is easy to figure out, so I
thought I would post it. I'm no Java expert.

On Jul 2, 11:28 am, John Lenz <concavel...@gmail.com> wrote:
> Hmmm.  Looks like a bit of code didn't make it into the public release, I'll
> get that rectified.  For now you will need to add a new pass to
> DefaultPassConfig and add a reference to it:
>
>     private final PassFactory printNameReferenceGraph =        new
> PassFactory("printNameReferenceGraph", true) {      @Override
> protected CompilerPass createInternal(final AbstractCompiler compiler)
> {        return new CompilerPass() {          @Override
> public void process(Node externs, Node jsRoot) {
> NameReferenceGraphConstruction gc =                new
> NameReferenceGraphConstruction(compiler);
> gc.process(externs, jsRoot);            String graphFileName =
> options.nameReferenceGraphPath;            try {
> Files.write(DotFormatter.toDot(gc.getNameReferenceGraph()),
>       new File(graphFileName),                  Charsets.UTF_8);
>      } catch (IOException e) {              logger.severe(
>      "Error writing compiler report to " + graphFileName);
>
> }          }        };      }    };

John Lenz

unread,
Jul 2, 2010, 3:05:30 PM7/2/10
to closure-comp...@googlegroups.com
Can you build it using Ant from the command line?

jff24grd

unread,
Jul 2, 2010, 6:25:41 PM7/2/10
to Closure Compiler Discuss
if I build it from ant and try and run it it says

Invalid or corrupt jarfile

jff24grd

unread,
Jul 6, 2010, 9:07:18 AM7/6/10
to Closure Compiler Discuss
Finally got it to compile using ant, but I still need a pointer or to
on how to reference it so it will run.

Thanks for all the help.

John Lenz

unread,
Jul 13, 2010, 8:47:10 PM7/13/10
to closure-comp...@googlegroups.com
The reports themselves have been open sourced as of:

Reply all
Reply to author
Forward
0 new messages