github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/go/pointer/testdata/chanreflect.go (about)

     1  //go:build ignore
     2  // +build ignore
     3  
     4  package main
     5  
     6  import "reflect"
     7  
     8  // Test of channels with reflection.
     9  
    10  var a, b int
    11  
    12  func chanreflect1() {
    13  	ch := make(chan *int, 0) // @line cr1make
    14  	crv := reflect.ValueOf(ch)
    15  	crv.Send(reflect.ValueOf(&a))
    16  	print(crv.Interface())             // @types chan *int
    17  	print(crv.Interface().(chan *int)) // @pointsto makechan@cr1make:12
    18  	print(<-ch)                        // @pointsto command-line-arguments.a
    19  }
    20  
    21  func chanreflect1i() {
    22  	// Exercises reflect.Value conversions to/from interfaces:
    23  	// a different code path than for concrete types.
    24  	ch := make(chan interface{}, 0)
    25  	reflect.ValueOf(ch).Send(reflect.ValueOf(&a))
    26  	v := <-ch
    27  	print(v)        // @types *int
    28  	print(v.(*int)) // @pointsto command-line-arguments.a
    29  }
    30  
    31  func chanreflect2() {
    32  	ch := make(chan *int, 0)
    33  	ch <- &b
    34  	crv := reflect.ValueOf(ch)
    35  	r, _ := crv.Recv()
    36  	print(r.Interface())        // @types *int
    37  	print(r.Interface().(*int)) // @pointsto command-line-arguments.b
    38  }
    39  
    40  func chanOfRecv() {
    41  	// MakeChan(<-chan) is a no-op.
    42  	t := reflect.ChanOf(reflect.RecvDir, reflect.TypeOf(&a))
    43  	print(reflect.Zero(t).Interface())                      // @types <-chan *int
    44  	print(reflect.MakeChan(t, 0).Interface().(<-chan *int)) // @pointsto
    45  	print(reflect.MakeChan(t, 0).Interface().(chan *int))   // @pointsto
    46  }
    47  
    48  func chanOfSend() {
    49  	// MakeChan(chan<-) is a no-op.
    50  	t := reflect.ChanOf(reflect.SendDir, reflect.TypeOf(&a))
    51  	print(reflect.Zero(t).Interface())                      // @types chan<- *int
    52  	print(reflect.MakeChan(t, 0).Interface().(chan<- *int)) // @pointsto
    53  	print(reflect.MakeChan(t, 0).Interface().(chan *int))   // @pointsto
    54  }
    55  
    56  func chanOfBoth() {
    57  	t := reflect.ChanOf(reflect.BothDir, reflect.TypeOf(&a))
    58  	print(reflect.Zero(t).Interface()) // @types chan *int
    59  	ch := reflect.MakeChan(t, 0)
    60  	print(ch.Interface().(chan *int)) // @pointsto <alloc in reflect.MakeChan>
    61  	ch.Send(reflect.ValueOf(&b))
    62  	ch.Interface().(chan *int) <- &a
    63  	r, _ := ch.Recv()
    64  	print(r.Interface().(*int))         // @pointsto command-line-arguments.a | command-line-arguments.b
    65  	print(<-ch.Interface().(chan *int)) // @pointsto command-line-arguments.a | command-line-arguments.b
    66  }
    67  
    68  var unknownDir reflect.ChanDir // not a constant
    69  
    70  func chanOfUnknown() {
    71  	// Unknown channel direction: assume all three.
    72  	// MakeChan only works on the bi-di channel type.
    73  	t := reflect.ChanOf(unknownDir, reflect.TypeOf(&a))
    74  	print(reflect.Zero(t).Interface())        // @types <-chan *int | chan<- *int | chan *int
    75  	print(reflect.MakeChan(t, 0).Interface()) // @types chan *int
    76  }
    77  
    78  func main() {
    79  	chanreflect1()
    80  	chanreflect1i()
    81  	chanreflect2()
    82  	chanOfRecv()
    83  	chanOfSend()
    84  	chanOfBoth()
    85  	chanOfUnknown()
    86  }