GoPLS Viewer

Home|gopls/go/pointer/testdata/funcreflect.go
1//go:build ignore
2// +build ignore
3
4package main
5
6import "reflect"
7
8var zeroab int
9var false2 bool
10
11func f(p *intq hasF) *int {
12    print(p)      // @pointsto command-line-arguments.a
13    print(q)      // @types *T
14    print(q.(*T)) // @pointsto new@newT1:22
15    return &b
16}
17
18func g(p *bool) (*int, *boolhasF) {
19    return &bpnew(T// @line newT2
20}
21
22func reflectValueCall() {
23    rvf := reflect.ValueOf(f)
24    res := rvf.Call([]reflect.Value{
25        // argument order is not significant:
26        reflect.ValueOf(new(T)), // @line newT1
27        reflect.ValueOf(&a),
28    })
29    print(res[0].Interface())        // @types *int
30    print(res[0].Interface().(*int)) // @pointsto command-line-arguments.b
31}
32
33// @calls command-line-arguments.reflectValueCall -> command-line-arguments.f
34
35func reflectValueCallIndirect() {
36    rvf := reflect.ValueOf(g)
37    call := rvf.Call // kids, don't try this at home
38
39    // Indirect call uses shared contour.
40    //
41    // Also notice that argument position doesn't matter, and args
42    // of inappropriate type (e.g. 'a') are ignored.
43    res := call([]reflect.Value{
44        reflect.ValueOf(&a),
45        reflect.ValueOf(&false2),
46    })
47    res0 := res[0].Interface()
48    print(res0)         // @types *int | *bool | *T
49    print(res0.(*int))  // @pointsto command-line-arguments.b
50    print(res0.(*bool)) // @pointsto command-line-arguments.false2
51    print(res0.(hasF))  // @types *T
52    print(res0.(*T))    // @pointsto new@newT2:19
53}
54
55// @calls command-line-arguments.reflectValueCallIndirect -> (reflect.Value).Call$bound
56// @calls (reflect.Value).Call$bound -> command-line-arguments.g
57
58func reflectTypeInOut() {
59    var f func(float64bool) (stringint)
60    print(reflect.Zero(reflect.TypeOf(f).In(0)).Interface())    // @types float64
61    print(reflect.Zero(reflect.TypeOf(f).In(1)).Interface())    // @types bool
62    print(reflect.Zero(reflect.TypeOf(f).In(-1)).Interface())   // @types float64 | bool
63    print(reflect.Zero(reflect.TypeOf(f).In(zero)).Interface()) // @types float64 | bool
64
65    print(reflect.Zero(reflect.TypeOf(f).Out(0)).Interface()) // @types string
66    print(reflect.Zero(reflect.TypeOf(f).Out(1)).Interface()) // @types int
67    print(reflect.Zero(reflect.TypeOf(f).Out(2)).Interface()) // @types
68
69    print(reflect.Zero(reflect.TypeOf(3).Out(0)).Interface()) // @types
70}
71
72type hasF interface {
73    F()
74}
75
76type T struct{}
77
78func (TF()    {}
79func (Tg(int) {}
80
81type U struct{}
82
83func (UF(int)    {}
84func (Ug(string) {}
85
86type I interface {
87    f()
88}
89
90var nonconst string
91
92func reflectTypeMethodByName() {
93    TU := reflect.TypeOf([]interface{}{T{}, U{}}[0])
94    print(reflect.Zero(TU)) // @types T | U
95
96    F_ := TU.MethodByName("F")
97    print(reflect.Zero(F.Type)) // @types func(T) | func(U, int)
98    print(F.Func)               // @pointsto (command-line-arguments.T).F | (command-line-arguments.U).F
99
100    g_ := TU.MethodByName("g")
101    print(reflect.Zero(g.Type)) // @types func(T, int) | func(U, string)
102    print(g.Func)               // @pointsto (command-line-arguments.T).g | (command-line-arguments.U).g
103
104    // Non-literal method names are treated less precisely.
105    U := reflect.TypeOf(U{})
106    X_ := U.MethodByName(nonconst)
107    print(reflect.Zero(X.Type)) // @types func(U, int) | func(U, string)
108    print(X.Func)               // @pointsto (command-line-arguments.U).F | (command-line-arguments.U).g
109
110    // Interface methods.
111    rThasF := reflect.TypeOf(new(hasF)).Elem()
112    print(reflect.Zero(rThasF)) // @types hasF
113    F2_ := rThasF.MethodByName("F")
114    print(reflect.Zero(F2.Type)) // @types func()
115    print(F2.Func)               // @pointsto
116
117}
118
119func reflectTypeMethod() {
120    m := reflect.TypeOf(T{}).Method(0)
121    print(reflect.Zero(m.Type)) // @types func(T) | func(T, int)
122    print(m.Func)               // @pointsto (command-line-arguments.T).F | (command-line-arguments.T).g
123}
124
125func main() {
126    reflectValueCall()
127    reflectValueCallIndirect()
128    reflectTypeInOut()
129    reflectTypeMethodByName()
130    reflectTypeMethod()
131}
132
MembersX
reflectTypeMethodByName.rThasF
zero
U
reflectTypeMethodByName
reflectTypeMethodByName._
reflectTypeMethodByName.g
reflectTypeMethodByName.X
f
g.p
reflectValueCall
reflectValueCallIndirect.res0
U.g
reflectTypeMethodByName.U
reflectValueCallIndirect.call
reflectValueCallIndirect.res
reflectTypeInOut
hasF
T.F
f.q
reflectValueCallIndirect
reflectTypeMethodByName.F2
f.p
g
reflectTypeMethodByName.TU
reflectTypeMethod
reflectTypeMethod.m
U.F
reflectValueCall.rvf
reflectValueCall.res
reflectValueCallIndirect.rvf
false2
nonconst
reflectTypeMethodByName.F
Members
X