1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 //lint:file-ignore SA1019 go/callgraph's test suite is built around the deprecated go/loader. We'll leave fixing that to upstream.
7 // No testdata on Android.
25 "honnef.co/go/tools/go/callgraph"
26 "honnef.co/go/tools/go/callgraph/cha"
27 "honnef.co/go/tools/go/ir/irutil"
29 "golang.org/x/tools/go/loader"
32 var inputs = []string{
38 func expectation(f *ast.File) (string, token.Pos) {
39 for _, c := range f.Comments {
40 text := strings.TrimSpace(c.Text())
41 if t := strings.TrimPrefix(text, "WANT:\n"); t != text {
45 return "", token.NoPos
48 // TestCHA runs CHA on each file in inputs, prints the dynamic edges of
49 // the call graph, and compares it with the golden results embedded in
50 // the WANT comment at the end of the file.
52 func TestCHA(t *testing.T) {
53 for _, filename := range inputs {
54 content, err := ioutil.ReadFile(filename)
56 t.Errorf("couldn't read file '%s': %s", filename, err)
60 conf := loader.Config{
61 ParserMode: parser.ParseComments,
63 f, err := conf.ParseFile(filename, content)
69 want, pos := expectation(f)
70 if pos == token.NoPos {
71 t.Errorf("No WANT: comment in %s", filename)
75 conf.CreateFromFiles("main", f)
76 iprog, err := conf.Load()
82 prog := irutil.CreateProgram(iprog, 0)
83 mainPkg := prog.Package(iprog.Created[0].Pkg)
86 cg := cha.CallGraph(prog)
88 if got := printGraph(cg, mainPkg.Pkg); got != want {
89 t.Errorf("%s: got:\n%s\nwant:\n%s",
90 prog.Fset.Position(pos), got, want)
95 func printGraph(cg *callgraph.Graph, from *types.Package) string {
97 callgraph.GraphVisitEdges(cg, func(e *callgraph.Edge) error {
98 if strings.Contains(e.Description(), "dynamic") {
99 edges = append(edges, fmt.Sprintf("%s --> %s",
100 e.Caller.Func.RelString(from),
101 e.Callee.Func.RelString(from)))
108 buf.WriteString("Dynamic calls\n")
109 for _, edge := range edges {
110 fmt.Fprintf(&buf, " %s\n", edge)
112 return strings.TrimSpace(buf.String())