--- /dev/null
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package static_test
+
+import (
+ "fmt"
+ "go/parser"
+ "reflect"
+ "sort"
+ "testing"
+
+ "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/ssautil"
+)
+
+const input = `package P
+
+type C int
+func (C) f()
+
+type I interface{f()}
+
+func f() {
+ p := func() {}
+ g()
+ p() // SSA constant propagation => static
+
+ if unknown {
+ p = h
+ }
+ p() // dynamic
+
+ C(0).f()
+}
+
+func g() {
+ var i I = C(0)
+ i.f()
+}
+
+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)
+ }
+
+ conf.CreateFromFiles("P", f)
+ iprog, err := conf.Load()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ P := iprog.Created[0].Pkg
+
+ prog := ssautil.CreateProgram(iprog, 0)
+ 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)
+
+ 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)
+ }
+}