github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/go/pointer/testdata/reflect.go (about) 1 //go:build ignore 2 // +build ignore 3 4 package main 5 6 import ( 7 "reflect" 8 "unsafe" 9 ) 10 11 var a, b int 12 var unknown bool 13 14 func 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 22 func 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 29 func 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 43 func 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. 55 func 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 84 type 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. 88 func 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.BothDir, v) 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 111 func main() { 112 reflectIndirect() 113 reflectNewAt() 114 reflectTypeOf() 115 reflectTypeElem() 116 metareflection() 117 typeCycle() 118 }