func (r *callgraphResult) toSerial(res *serial.Result, fset *token.FileSet) { cg := make([]serial.CallGraph, len(r.nodes)) for _, n := range r.nodes { j := &cg[n.ID] fn := n.Func j.Name = fn.String() j.Pos = fset.Position(fn.Pos()).String() for callee := range callgraph.CalleesOf(n) { j.Children = append(j.Children, callee.ID) } sort.Ints(j.Children) } res.Callgraph = cg }
func (r *callgraphResult) display(printf printfFunc) { descr := "the entire program" if r.qpkg != nil { descr = fmt.Sprintf("package %s", r.qpkg.Path()) } printf(nil, ` Below is a call graph of %s. The numbered nodes form a spanning tree. Non-numbered nodes indicate back- or cross-edges to the node whose number follows in parentheses. `, descr) printed := make(map[*callgraph.Node]int) var print func(caller *callgraph.Node, indent int) print = func(caller *callgraph.Node, indent int) { if num, ok := printed[caller]; !ok { num = len(printed) printed[caller] = num // Sort the children into name order for deterministic* output. // (*mostly: anon funcs' names are not globally unique.) var funcs funcsByName for callee := range callgraph.CalleesOf(caller) { funcs = append(funcs, callee.Func) } sort.Sort(funcs) printf(caller.Func, "%d\t%*s%s", num, 4*indent, "", caller.Func.RelString(r.qpkg)) for _, callee := range funcs { print(r.nodes[callee], indent+1) } } else { printf(caller.Func, "\t%*s%s (%d)", 4*indent, "", caller.Func.RelString(r.qpkg), num) } } for _, root := range r.roots { print(root, 0) } }