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