示例#1
0
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)
}
示例#2
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
}