github.com/golangci/go-tools@v0.0.0-20190318060251-af6baa5dc196/callgraph/static/static.go (about)

     1  // Package static computes the call graph of a Go program containing
     2  // only static call edges.
     3  package static // import "github.com/golangci/go-tools/callgraph/static"
     4  
     5  import (
     6  	"github.com/golangci/go-tools/callgraph"
     7  	"github.com/golangci/go-tools/ssa"
     8  	"github.com/golangci/go-tools/ssa/ssautil"
     9  )
    10  
    11  // CallGraph computes the call graph of the specified program
    12  // considering only static calls.
    13  //
    14  func CallGraph(prog *ssa.Program) *callgraph.Graph {
    15  	cg := callgraph.New(nil) // TODO(adonovan) eliminate concept of rooted callgraph
    16  
    17  	// TODO(adonovan): opt: use only a single pass over the ssa.Program.
    18  	// TODO(adonovan): opt: this is slower than RTA (perhaps because
    19  	// the lower precision means so many edges are allocated)!
    20  	for f := range ssautil.AllFunctions(prog) {
    21  		fnode := cg.CreateNode(f)
    22  		for _, b := range f.Blocks {
    23  			for _, instr := range b.Instrs {
    24  				if site, ok := instr.(ssa.CallInstruction); ok {
    25  					if g := site.Common().StaticCallee(); g != nil {
    26  						gnode := cg.CreateNode(g)
    27  						callgraph.AddEdge(fnode, site, gnode)
    28  					}
    29  				}
    30  			}
    31  		}
    32  	}
    33  
    34  	return cg
    35  }