GoPLS Viewer

Home|gopls/go/callgraph/static/static_test.go
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.
4
5package static_test
6
7import (
8    "fmt"
9    "go/parser"
10    "reflect"
11    "sort"
12    "testing"
13
14    "golang.org/x/tools/go/callgraph"
15    "golang.org/x/tools/go/callgraph/static"
16    "golang.org/x/tools/go/loader"
17    "golang.org/x/tools/go/ssa"
18    "golang.org/x/tools/go/ssa/ssautil"
19    "golang.org/x/tools/internal/typeparams"
20)
21
22const input = `package P
23
24type C int
25func (C) f()
26
27type I interface{f()}
28
29func f() {
30    p := func() {}
31    g()
32    p() // SSA constant propagation => static
33
34    if unknown {
35        p = h
36    }
37    p() // dynamic
38
39    C(0).f()
40}
41
42func g() {
43    var i I = C(0)
44    i.f()
45}
46
47func h()
48
49var unknown bool
50`
51
52const genericsInput = `package P
53
54type I interface {
55    F()
56}
57
58type A struct{}
59
60func (a A) F() {}
61
62type B struct{}
63
64func (b B) F() {}
65
66func instantiated[X I](x X) {
67    x.F()
68}
69
70func Bar() {}
71
72func f(h func(), a A, b B) {
73    h()
74
75    instantiated[A](a)
76    instantiated[B](b)
77}
78`
79
80func TestStatic(t *testing.T) {
81    for _e := range []struct {
82        input string
83        want  []string
84        // typeparams must be true if input uses type parameters
85        typeparams bool
86    }{
87        {input, []string{
88            "(*C).f -> (C).f",
89            "f -> (C).f",
90            "f -> f$1",
91            "f -> g",
92        }, false},
93        {genericsInput, []string{
94            "(*A).F -> (A).F",
95            "(*B).F -> (B).F",
96            "f -> instantiated[P.A]",
97            "f -> instantiated[P.B]",
98            "instantiated[P.A] -> (A).F",
99            "instantiated[P.B] -> (B).F",
100        }, true},
101    } {
102        if e.typeparams && !typeparams.Enabled {
103            // Skip tests with type parameters when the build
104            // environment is not supporting any.
105            continue
106        }
107
108        conf := loader.Config{ParserModeparser.ParseComments}
109        ferr := conf.ParseFile("P.go"e.input)
110        if err != nil {
111            t.Error(err)
112            continue
113        }
114
115        conf.CreateFromFiles("P"f)
116        iprogerr := conf.Load()
117        if err != nil {
118            t.Error(err)
119            continue
120        }
121
122        P := iprog.Created[0].Pkg
123
124        prog := ssautil.CreateProgram(iprogssa.InstantiateGenerics)
125        prog.Build()
126
127        cg := static.CallGraph(prog)
128
129        var edges []string
130        callgraph.GraphVisitEdges(cg, func(e *callgraph.Edgeerror {
131            edges = append(edgesfmt.Sprintf("%s -> %s",
132                e.Caller.Func.RelString(P),
133                e.Callee.Func.RelString(P)))
134            return nil
135        })
136        sort.Strings(edges)
137
138        if !reflect.DeepEqual(edgese.want) {
139            t.Errorf("Got edges %v, want %v"edgese.want)
140        }
141    }
142}
143
MembersX
parser
loader
typeparams
input
TestStatic.RangeStmt_1035.e
TestStatic.RangeStmt_1035.BlockStmt.err
TestStatic.RangeStmt_1035.BlockStmt.P
fmt
TestStatic.RangeStmt_1035.BlockStmt.edges
testing
TestStatic
reflect
TestStatic.RangeStmt_1035.BlockStmt.f
TestStatic.RangeStmt_1035.BlockStmt.iprog
TestStatic.RangeStmt_1035.BlockStmt.prog
static
genericsInput
TestStatic.t
TestStatic.RangeStmt_1035.BlockStmt.conf
TestStatic.RangeStmt_1035.BlockStmt.cg
sort
Members
X