github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/go/pointer/testdata/mapreflect.go (about) 1 //go:build ignore 2 // +build ignore 3 4 package main 5 6 // Test of maps with reflection. 7 8 import "reflect" 9 10 var a int 11 var b bool 12 13 func reflectMapKeysIndex() { 14 m := make(map[*int]*bool) // @line mr1make 15 m[&a] = &b 16 17 mrv := reflect.ValueOf(m) 18 print(mrv.Interface()) // @types map[*int]*bool 19 print(mrv.Interface().(map[*int]*bool)) // @pointsto makemap@mr1make:11 20 print(mrv) // @pointsto makeinterface:map[*int]*bool 21 print(mrv) // @types map[*int]*bool 22 23 keys := mrv.MapKeys() 24 print(keys) // @pointsto <alloc in (reflect.Value).MapKeys> 25 for _, k := range keys { 26 print(k) // @pointsto <alloc in (reflect.Value).MapKeys> 27 print(k) // @types *int 28 print(k.Interface()) // @types *int 29 print(k.Interface().(*int)) // @pointsto command-line-arguments.a 30 31 v := mrv.MapIndex(k) 32 print(v.Interface()) // @types *bool 33 print(v.Interface().(*bool)) // @pointsto command-line-arguments.b 34 } 35 } 36 37 func reflectSetMapIndex() { 38 m := make(map[*int]*bool) 39 mrv := reflect.ValueOf(m) 40 mrv.SetMapIndex(reflect.ValueOf(&a), reflect.ValueOf(&b)) 41 42 print(m[nil]) // @pointsto command-line-arguments.b 43 44 for _, k := range mrv.MapKeys() { 45 print(k.Interface()) // @types *int 46 print(k.Interface().(*int)) // @pointsto command-line-arguments.a 47 } 48 49 tmap := reflect.TypeOf(m) 50 // types.EvalNode won't let us refer to non-exported types: 51 // print(tmap) // #@types *reflect.rtype 52 print(tmap) // @pointsto map[*int]*bool 53 54 zmap := reflect.Zero(tmap) 55 print(zmap) // @pointsto <alloc in reflect.Zero> 56 print(zmap.Interface()) // @pointsto <alloc in reflect.Zero> 57 58 print(tmap.Key()) // @pointsto *int 59 print(tmap.Elem()) // @pointsto *bool 60 print(reflect.Zero(tmap.Key())) // @pointsto <alloc in reflect.Zero> 61 print(reflect.Zero(tmap.Key()).Interface()) // @pointsto <alloc in reflect.Zero> 62 print(reflect.Zero(tmap.Key()).Interface()) // @types *int 63 print(reflect.Zero(tmap.Elem())) // @pointsto <alloc in reflect.Zero> 64 print(reflect.Zero(tmap.Elem()).Interface()) // @pointsto <alloc in reflect.Zero> 65 print(reflect.Zero(tmap.Elem()).Interface()) // @types *bool 66 } 67 68 func reflectSetMapIndexInterface() { 69 // Exercises reflect.Value conversions to/from interfaces: 70 // a different code path than for concrete types. 71 m := make(map[interface{}]interface{}) 72 reflect.ValueOf(m).SetMapIndex(reflect.ValueOf(&a), reflect.ValueOf(&b)) 73 for k, v := range m { 74 print(k) // @types *int 75 print(k.(*int)) // @pointsto command-line-arguments.a 76 print(v) // @types *bool 77 print(v.(*bool)) // @pointsto command-line-arguments.b 78 } 79 } 80 81 func reflectSetMapIndexAssignable() { 82 // SetMapIndex performs implicit assignability conversions. 83 type I *int 84 type J *int 85 86 str := reflect.ValueOf("") 87 88 // *int is assignable to I. 89 m1 := make(map[string]I) 90 reflect.ValueOf(m1).SetMapIndex(str, reflect.ValueOf(new(int))) // @line int 91 print(m1[""]) // @pointsto new@int:58 92 93 // I is assignable to I. 94 m2 := make(map[string]I) 95 reflect.ValueOf(m2).SetMapIndex(str, reflect.ValueOf(I(new(int)))) // @line I 96 print(m2[""]) // @pointsto new@I:60 97 98 // J is not assignable to I. 99 m3 := make(map[string]I) 100 reflect.ValueOf(m3).SetMapIndex(str, reflect.ValueOf(J(new(int)))) 101 print(m3[""]) // @pointsto 102 } 103 104 func reflectMakeMap() { 105 t := reflect.TypeOf(map[*int]*bool(nil)) 106 v := reflect.MakeMap(t) 107 print(v) // @types map[*int]*bool 108 print(v) // @pointsto <alloc in reflect.MakeMap> 109 } 110 111 func main() { 112 reflectMapKeysIndex() 113 reflectSetMapIndex() 114 reflectSetMapIndexInterface() 115 reflectSetMapIndexAssignable() 116 reflectMakeMap() 117 // TODO(adonovan): reflect.MapOf(Type) 118 }