func (r *callgraphResult) display(printf printfFunc) { printf(nil, ` Below is a call graph of the entire program. The numbered nodes form a spanning tree. Non-numbered nodes indicate back- or cross-edges to the node whose number follows in parentheses. Some nodes may appear multiple times due to context-sensitive treatment of some calls. `) seen := make(map[call.GraphNode]int) var print func(cgn call.GraphNode, indent int) print = func(cgn call.GraphNode, indent int) { fn := cgn.Func() if num, ok := seen[cgn]; !ok { num = len(seen) seen[cgn] = num printf(fn, "%d\t%s%s", num, strings.Repeat(" ", indent), fn) // Don't use Edges(), which distinguishes callees by call site. for callee := range call.CalleesOf(cgn) { print(callee, indent+1) } } else { printf(fn, "\t%s%s (%d)", strings.Repeat(" ", indent), fn, num) } } print(r.callgraph.Root(), 0) }
func (r *callgraphResult) toSerial(res *serial.Result, fset *token.FileSet) { nodes := r.callgraph.Nodes() numbering := make(map[call.GraphNode]int) for i, n := range nodes { numbering[n] = i } cg := make([]serial.CallGraph, len(nodes)) for i, n := range nodes { j := &cg[i] fn := n.Func() j.Name = fn.String() j.Pos = fset.Position(fn.Pos()).String() for callee := range call.CalleesOf(n) { j.Children = append(j.Children, numbering[callee]) } } res.Callgraph = cg }