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 // No testdata on Android.
23 "golang.org/x/tools/go/callgraph"
24 "golang.org/x/tools/go/callgraph/cha"
25 "golang.org/x/tools/go/loader"
26 "golang.org/x/tools/go/ssa/ssautil"
29 var inputs = []string{
33 "testdata/issue23925.go",
36 func expectation(f *ast.File) (string, token.Pos) {
37 for _, c := range f.Comments {
38 text := strings.TrimSpace(c.Text())
39 if t := strings.TrimPrefix(text, "WANT:\n"); t != text {
43 return "", token.NoPos
46 // TestCHA runs CHA on each file in inputs, prints the dynamic edges of
47 // the call graph, and compares it with the golden results embedded in
48 // the WANT comment at the end of the file.
50 func TestCHA(t *testing.T) {
51 for _, filename := range inputs {
52 content, err := ioutil.ReadFile(filename)
54 t.Errorf("couldn't read file '%s': %s", filename, err)
58 conf := loader.Config{
59 ParserMode: parser.ParseComments,
61 f, err := conf.ParseFile(filename, content)
67 want, pos := expectation(f)
68 if pos == token.NoPos {
69 t.Errorf("No WANT: comment in %s", filename)
73 conf.CreateFromFiles("main", f)
74 iprog, err := conf.Load()
80 prog := ssautil.CreateProgram(iprog, 0)
81 mainPkg := prog.Package(iprog.Created[0].Pkg)
84 cg := cha.CallGraph(prog)
86 if got := printGraph(cg, mainPkg.Pkg); got != want {
87 t.Errorf("%s: got:\n%s\nwant:\n%s",
88 prog.Fset.Position(pos), got, want)
93 func printGraph(cg *callgraph.Graph, from *types.Package) string {
95 callgraph.GraphVisitEdges(cg, func(e *callgraph.Edge) error {
96 if strings.Contains(e.Description(), "dynamic") {
97 edges = append(edges, fmt.Sprintf("%s --> %s",
98 e.Caller.Func.RelString(from),
99 e.Callee.Func.RelString(from)))
106 buf.WriteString("Dynamic calls\n")
107 for _, edge := range edges {
108 fmt.Fprintf(&buf, " %s\n", edge)
110 return strings.TrimSpace(buf.String())