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

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