diff --git a/README.md b/README.md index 271179b..4a70935 100644 --- a/README.md +++ b/README.md @@ -129,7 +129,7 @@ Usage of go-callvis: -tests Include test code. -algo string - Use specific algorithm for package analyzer: static, cha or rta (default "static") + Use specific algorithm for package analyzer: static, cha, rta or vta (default "static") -version Show version and exit. ``` diff --git a/analysis.go b/analysis.go index 86ad102..b582e33 100644 --- a/analysis.go +++ b/analysis.go @@ -16,6 +16,7 @@ import ( "golang.org/x/tools/go/callgraph" "golang.org/x/tools/go/callgraph/cha" "golang.org/x/tools/go/callgraph/rta" + "golang.org/x/tools/go/callgraph/vta" "golang.org/x/tools/go/callgraph/static" "golang.org/x/tools/go/packages" @@ -29,6 +30,7 @@ const ( CallGraphTypeStatic CallGraphType = "static" CallGraphTypeCha CallGraphType = "cha" CallGraphTypeRta CallGraphType = "rta" + CallGraphTypeVta CallGraphType = "vta" ) // ==[ type def/func: analysis ]=============================================== @@ -134,6 +136,8 @@ func (a *analysis) DoAnalysis( graph = static.CallGraph(prog) case CallGraphTypeCha: graph = cha.CallGraph(prog) + case CallGraphTypeVta: + fallthrough case CallGraphTypeRta: mains, err := mainPackages(prog.AllPackages()) if err != nil { @@ -152,8 +156,15 @@ func (a *analysis) DoAnalysis( for _, init := range inits { roots = append(roots, init) } - graph = rta.Analyze(roots, true).CallGraph + + if algo == CallGraphTypeVta { + funcs := make(map[*ssa.Function]bool) + for fun := range graph.Nodes { + funcs[fun] = true + } + graph = vta.CallGraph(funcs, graph) + } default: return fmt.Errorf("invalid call graph type: %s", a.opts.algo) } diff --git a/main.go b/main.go index 92fe911..4b0987f 100644 --- a/main.go +++ b/main.go @@ -43,8 +43,8 @@ var ( outputFile = flag.String("file", "", "output filename - omit to use server mode") outputFormat = flag.String("format", "svg", "output file format [svg | png | jpg | ...]") cacheDir = flag.String("cacheDir", "", "Enable caching to avoid unnecessary re-rendering, you can force rendering by adding 'refresh=true' to the URL query or emptying the cache directory") - callgraphAlgo = flag.String("algo", string(CallGraphTypeStatic), fmt.Sprintf("The algorithm used to construct the call graph. Possible values inlcude: %q, %q, %q", - CallGraphTypeStatic, CallGraphTypeCha, CallGraphTypeRta)) + callgraphAlgo = flag.String("algo", string(CallGraphTypeStatic), fmt.Sprintf("The algorithm used to construct the call graph. Possible values inlcude: %q, %q, %q, %q", + CallGraphTypeStatic, CallGraphTypeCha, CallGraphTypeRta, CallGraphTypeVta)) debugFlag = flag.Bool("debug", false, "Enable verbose log.") versionFlag = flag.Bool("version", false, "Show version and exit.")