github.com/v2fly/tools@v0.100.0/go/pointer/testdata/mapreflect.go (about)

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