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 "golang.org/x/tools/go/loader"
26 "honnef.co/go/tools/callgraph"
27 "honnef.co/go/tools/callgraph/cha"
28 "honnef.co/go/tools/ir/irutil"
31 var inputs = []string{
37 func expectation(f *ast.File) (string, token.Pos) {
38 for _, c := range f.Comments {
39 text := strings.TrimSpace(c.Text())
40 if t := strings.TrimPrefix(text, "WANT:\n"); t != text {
44 return "", token.NoPos
47 // TestCHA runs CHA on each file in inputs, prints the dynamic edges of
48 // the call graph, and compares it with the golden results embedded in
49 // the WANT comment at the end of the file.
51 func TestCHA(t *testing.T) {
52 for _, filename := range inputs {
53 content, err := ioutil.ReadFile(filename)
55 t.Errorf("couldn't read file '%s': %s", filename, err)
59 conf := loader.Config{
60 ParserMode: parser.ParseComments,
62 f, err := conf.ParseFile(filename, content)
68 want, pos := expectation(f)
69 if pos == token.NoPos {
70 t.Errorf("No WANT: comment in %s", filename)
74 conf.CreateFromFiles("main", f)
75 iprog, err := conf.Load()
81 prog := irutil.CreateProgram(iprog, 0)
82 mainPkg := prog.Package(iprog.Created[0].Pkg)
85 cg := cha.CallGraph(prog)
87 if got := printGraph(cg, mainPkg.Pkg); got != want {
88 t.Errorf("%s: got:\n%s\nwant:\n%s",
89 prog.Fset.Position(pos), got, want)
94 func printGraph(cg *callgraph.Graph, from *types.Package) string {
96 callgraph.GraphVisitEdges(cg, func(e *callgraph.Edge) error {
97 if strings.Contains(e.Description(), "dynamic") {
98 edges = append(edges, fmt.Sprintf("%s --> %s",
99 e.Caller.Func.RelString(from),
100 e.Callee.Func.RelString(from)))
107 buf.WriteString("Dynamic calls\n")
108 for _, edge := range edges {
109 fmt.Fprintf(&buf, " %s\n", edge)
111 return strings.TrimSpace(buf.String())