GoPLS Viewer

Home|gopls/go/pointer/testdata/reflect.go
1//go:build ignore
2// +build ignore
3
4package main
5
6import (
7    "reflect"
8    "unsafe"
9)
10
11var ab int
12var unknown bool
13
14func reflectIndirect() {
15    ptr := &a
16    // Pointer:
17    print(reflect.Indirect(reflect.ValueOf(&ptr)).Interface().(*int)) // @pointsto command-line-arguments.a
18    // Non-pointer:
19    print(reflect.Indirect(reflect.ValueOf([]*int{ptr})).Interface().([]*int)[0]) // @pointsto command-line-arguments.a
20}
21
22func reflectNewAt() {
23    var x [8]byte
24    print(reflect.NewAt(reflect.TypeOf(3), unsafe.Pointer(&x)).Interface()) // @types *int
25}
26
27// @warning "unsound: command-line-arguments.reflectNewAt contains a reflect.NewAt.. call"
28
29func reflectTypeOf() {
30    t := reflect.TypeOf(3)
31    if unknown {
32        t = reflect.TypeOf("foo")
33    }
34    // TODO(adonovan): make types.Eval let us refer to unexported types.
35    print(t)                             // #@types *reflect.rtype
36    print(reflect.Zero(t).Interface())   // @types int | string
37    newint := reflect.New(t).Interface() // @line rtonew
38    print(newint)                        // @types *int | *string
39    print(newint.(*int))                 // @pointsto <alloc in reflect.New>
40    print(newint.(*string))              // @pointsto <alloc in reflect.New>
41}
42
43func reflectTypeElem() {
44    print(reflect.Zero(reflect.TypeOf(&a).Elem()).Interface())                       // @types int
45    print(reflect.Zero(reflect.TypeOf([]string{}).Elem()).Interface())               // @types string
46    print(reflect.Zero(reflect.TypeOf(make(chan bool)).Elem()).Interface())          // @types bool
47    print(reflect.Zero(reflect.TypeOf(make(map[string]float64)).Elem()).Interface()) // @types float64
48    print(reflect.Zero(reflect.TypeOf([3]complex64{}).Elem()).Interface())           // @types complex64
49    print(reflect.Zero(reflect.TypeOf(3).Elem()).Interface())                        // @types
50    print(reflect.Zero(reflect.TypeOf(new(interface{})).Elem()))                     // @types interface{}
51    print(reflect.Zero(reflect.TypeOf(new(interface{})).Elem()).Interface())         // @types
52}
53
54// reflect.Values within reflect.Values.
55func metareflection() {
56    // "box" a *int twice, unbox it twice.
57    v0 := reflect.ValueOf(&a)
58    print(v0)                              // @types *int
59    v1 := reflect.ValueOf(v0)              // box
60    print(v1)                              // @types reflect.Value
61    v2 := reflect.ValueOf(v1)              // box
62    print(v2)                              // @types reflect.Value
63    v1a := v2.Interface().(reflect.Value)  // unbox
64    print(v1a)                             // @types reflect.Value
65    v0a := v1a.Interface().(reflect.Value// unbox
66    print(v0a)                             // @types *int
67    print(v0a.Interface().(*int))          // @pointsto command-line-arguments.a
68
69    // "box" an interface{} lvalue twice, unbox it twice.
70    var iface interface{} = 3
71    x0 := reflect.ValueOf(&iface).Elem()
72    print(x0)                              // @types interface{}
73    x1 := reflect.ValueOf(x0)              // box
74    print(x1)                              // @types reflect.Value
75    x2 := reflect.ValueOf(x1)              // box
76    print(x2)                              // @types reflect.Value
77    x1a := x2.Interface().(reflect.Value)  // unbox
78    print(x1a)                             // @types reflect.Value
79    x0a := x1a.Interface().(reflect.Value// unbox
80    print(x0a)                             // @types interface{}
81    print(x0a.Interface())                 // @types int
82}
83
84type T struct{}
85
86// When the output of a type constructor flows to its input, we must
87// bound the set of types created to ensure termination of the algorithm.
88func typeCycle() {
89    t := reflect.TypeOf(0)
90    u := reflect.TypeOf("")
91    v := reflect.TypeOf(T{})
92    for unknown {
93        t = reflect.PtrTo(t)
94        t = reflect.SliceOf(t)
95
96        u = reflect.SliceOf(u)
97
98        if unknown {
99            v = reflect.ChanOf(reflect.BothDirv)
100        } else {
101            v = reflect.PtrTo(v)
102        }
103    }
104
105    // Type height is bounded to about 4 map/slice/chan/pointer constructors.
106    print(reflect.Zero(t).Interface()) // @types int | []*int | []*[]*int
107    print(reflect.Zero(u).Interface()) // @types string | []string | [][]string | [][][]string | [][][][]string
108    print(reflect.Zero(v).Interface()) // @types T | *T | **T | ***T | ****T | chan T | *chan T | **chan T | chan *T | *chan *T | chan **T | chan ***T | chan chan T | chan *chan T | chan chan *T
109}
110
111func main() {
112    reflectIndirect()
113    reflectNewAt()
114    reflectTypeOf()
115    reflectTypeElem()
116    metareflection()
117    typeCycle()
118}
119
MembersX
metareflection.x1
reflectIndirect.ptr
metareflection.v0
metareflection
metareflection.v2
reflectTypeOf
reflectTypeOf.newint
reflectTypeOf.t
typeCycle.u
typeCycle.v
reflectIndirect
reflectNewAt.x
metareflection.x0
metareflection.x2
typeCycle
typeCycle.t
reflectNewAt
metareflection.v1
Members
X