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
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/go/pointer/testdata/funcreflect.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/go/pointer/testdata/funcreflect.go
new file mode 100644 (file)
index 0000000..a0a9a5f
--- /dev/null
@@ -0,0 +1,130 @@
+// +build ignore
+
+package main
+
+import "reflect"
+
+var zero, a, b int
+var false2 bool
+
+func f(p *int, q hasF) *int {
+       print(p)      // @pointsto main.a
+       print(q)      // @types *T
+       print(q.(*T)) // @pointsto new@newT1:22
+       return &b
+}
+
+func g(p *bool) (*int, *bool, hasF) {
+       return &b, p, new(T) // @line newT2
+}
+
+func reflectValueCall() {
+       rvf := reflect.ValueOf(f)
+       res := rvf.Call([]reflect.Value{
+               // argument order is not significant:
+               reflect.ValueOf(new(T)), // @line newT1
+               reflect.ValueOf(&a),
+       })
+       print(res[0].Interface())        // @types *int
+       print(res[0].Interface().(*int)) // @pointsto main.b
+}
+
+// @calls main.reflectValueCall -> main.f
+
+func reflectValueCallIndirect() {
+       rvf := reflect.ValueOf(g)
+       call := rvf.Call // kids, don't try this at home
+
+       // Indirect call uses shared contour.
+       //
+       // Also notice that argument position doesn't matter, and args
+       // of inappropriate type (e.g. 'a') are ignored.
+       res := call([]reflect.Value{
+               reflect.ValueOf(&a),
+               reflect.ValueOf(&false2),
+       })
+       res0 := res[0].Interface()
+       print(res0)         // @types *int | *bool | *T
+       print(res0.(*int))  // @pointsto main.b
+       print(res0.(*bool)) // @pointsto main.false2
+       print(res0.(hasF))  // @types *T
+       print(res0.(*T))    // @pointsto new@newT2:19
+}
+
+// @calls main.reflectValueCallIndirect -> (reflect.Value).Call$bound
+// @calls (reflect.Value).Call$bound -> main.g
+
+func reflectTypeInOut() {
+       var f func(float64, bool) (string, int)
+       print(reflect.Zero(reflect.TypeOf(f).In(0)).Interface())    // @types float64
+       print(reflect.Zero(reflect.TypeOf(f).In(1)).Interface())    // @types bool
+       print(reflect.Zero(reflect.TypeOf(f).In(-1)).Interface())   // @types float64 | bool
+       print(reflect.Zero(reflect.TypeOf(f).In(zero)).Interface()) // @types float64 | bool
+
+       print(reflect.Zero(reflect.TypeOf(f).Out(0)).Interface()) // @types string
+       print(reflect.Zero(reflect.TypeOf(f).Out(1)).Interface()) // @types int
+       print(reflect.Zero(reflect.TypeOf(f).Out(2)).Interface()) // @types
+
+       print(reflect.Zero(reflect.TypeOf(3).Out(0)).Interface()) // @types
+}
+
+type hasF interface {
+       F()
+}
+
+type T struct{}
+
+func (T) F()    {}
+func (T) g(int) {}
+
+type U struct{}
+
+func (U) F(int)    {}
+func (U) g(string) {}
+
+type I interface {
+       f()
+}
+
+var nonconst string
+
+func reflectTypeMethodByName() {
+       TU := reflect.TypeOf([]interface{}{T{}, U{}}[0])
+       print(reflect.Zero(TU)) // @types T | U
+
+       F, _ := TU.MethodByName("F")
+       print(reflect.Zero(F.Type)) // @types func(T) | func(U, int)
+       print(F.Func)               // @pointsto (main.T).F | (main.U).F
+
+       g, _ := TU.MethodByName("g")
+       print(reflect.Zero(g.Type)) // @types func(T, int) | func(U, string)
+       print(g.Func)               // @pointsto (main.T).g | (main.U).g
+
+       // Non-literal method names are treated less precisely.
+       U := reflect.TypeOf(U{})
+       X, _ := U.MethodByName(nonconst)
+       print(reflect.Zero(X.Type)) // @types func(U, int) | func(U, string)
+       print(X.Func)               // @pointsto (main.U).F | (main.U).g
+
+       // Interface methods.
+       rThasF := reflect.TypeOf(new(hasF)).Elem()
+       print(reflect.Zero(rThasF)) // @types hasF
+       F2, _ := rThasF.MethodByName("F")
+       print(reflect.Zero(F2.Type)) // @types func()
+       print(F2.Func)               // @pointsto
+
+}
+
+func reflectTypeMethod() {
+       m := reflect.TypeOf(T{}).Method(0)
+       print(reflect.Zero(m.Type)) // @types func(T) | func(T, int)
+       print(m.Func)               // @pointsto (main.T).F | (main.T).g
+}
+
+func main() {
+       reflectValueCall()
+       reflectValueCallIndirect()
+       reflectTypeInOut()
+       reflectTypeMethodByName()
+       reflectTypeMethod()
+}