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  }