aboutsummaryrefslogtreecommitdiff
path: root/go/callgraph/static/static_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'go/callgraph/static/static_test.go')
-rw-r--r--go/callgraph/static/static_test.go116
1 files changed, 85 insertions, 31 deletions
diff --git a/go/callgraph/static/static_test.go b/go/callgraph/static/static_test.go
index e1bfcd707..0a108d3d2 100644
--- a/go/callgraph/static/static_test.go
+++ b/go/callgraph/static/static_test.go
@@ -14,7 +14,9 @@ import (
"golang.org/x/tools/go/callgraph"
"golang.org/x/tools/go/callgraph/static"
"golang.org/x/tools/go/loader"
+ "golang.org/x/tools/go/ssa"
"golang.org/x/tools/go/ssa/ssautil"
+ "golang.org/x/tools/internal/typeparams"
)
const input = `package P
@@ -47,42 +49,94 @@ func h()
var unknown bool
`
-func TestStatic(t *testing.T) {
- conf := loader.Config{ParserMode: parser.ParseComments}
- f, err := conf.ParseFile("P.go", input)
- if err != nil {
- t.Fatal(err)
- }
+const genericsInput = `package P
- conf.CreateFromFiles("P", f)
- iprog, err := conf.Load()
- if err != nil {
- t.Fatal(err)
- }
+type I interface {
+ F()
+}
- P := iprog.Created[0].Pkg
+type A struct{}
- prog := ssautil.CreateProgram(iprog, 0)
- prog.Build()
+func (a A) F() {}
- cg := static.CallGraph(prog)
+type B struct{}
- var edges []string
- callgraph.GraphVisitEdges(cg, func(e *callgraph.Edge) error {
- edges = append(edges, fmt.Sprintf("%s -> %s",
- e.Caller.Func.RelString(P),
- e.Callee.Func.RelString(P)))
- return nil
- })
- sort.Strings(edges)
+func (b B) F() {}
- want := []string{
- "(*C).f -> (C).f",
- "f -> (C).f",
- "f -> f$1",
- "f -> g",
- }
- if !reflect.DeepEqual(edges, want) {
- t.Errorf("Got edges %v, want %v", edges, want)
+func instantiated[X I](x X) {
+ x.F()
+}
+
+func Bar() {}
+
+func f(h func(), a A, b B) {
+ h()
+
+ instantiated[A](a)
+ instantiated[B](b)
+}
+`
+
+func TestStatic(t *testing.T) {
+ for _, e := range []struct {
+ input string
+ want []string
+ // typeparams must be true if input uses type parameters
+ typeparams bool
+ }{
+ {input, []string{
+ "(*C).f -> (C).f",
+ "f -> (C).f",
+ "f -> f$1",
+ "f -> g",
+ }, false},
+ {genericsInput, []string{
+ "(*A).F -> (A).F",
+ "(*B).F -> (B).F",
+ "f -> instantiated[P.A]",
+ "f -> instantiated[P.B]",
+ "instantiated[P.A] -> (A).F",
+ "instantiated[P.B] -> (B).F",
+ }, true},
+ } {
+ if e.typeparams && !typeparams.Enabled {
+ // Skip tests with type parameters when the build
+ // environment is not supporting any.
+ continue
+ }
+
+ conf := loader.Config{ParserMode: parser.ParseComments}
+ f, err := conf.ParseFile("P.go", e.input)
+ if err != nil {
+ t.Error(err)
+ continue
+ }
+
+ conf.CreateFromFiles("P", f)
+ iprog, err := conf.Load()
+ if err != nil {
+ t.Error(err)
+ continue
+ }
+
+ P := iprog.Created[0].Pkg
+
+ prog := ssautil.CreateProgram(iprog, ssa.InstantiateGenerics)
+ prog.Build()
+
+ cg := static.CallGraph(prog)
+
+ var edges []string
+ callgraph.GraphVisitEdges(cg, func(e *callgraph.Edge) error {
+ edges = append(edges, fmt.Sprintf("%s -> %s",
+ e.Caller.Func.RelString(P),
+ e.Callee.Func.RelString(P)))
+ return nil
+ })
+ sort.Strings(edges)
+
+ if !reflect.DeepEqual(edges, e.want) {
+ t.Errorf("Got edges %v, want %v", edges, e.want)
+ }
}
}