github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/gnovm/tests/selector_test.go (about)

     1  package tests
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"testing"
     7  )
     8  
     9  /*
    10  This attempts to show a sufficiently exhaustive list of ValuePaths for
    11  different types of selectors.  As can be seen, even a simple selector
    12  expression can represent a number of different types of selectors.
    13  */
    14  
    15  // S1 struct
    16  type S1 struct {
    17  	F0 int
    18  }
    19  
    20  func (S1) Hello() {
    21  }
    22  
    23  func (*S1) Bye() {
    24  }
    25  
    26  // Pointer to S1
    27  type S1P *S1
    28  
    29  // Like S1 but pointer struct
    30  type PS1 *struct {
    31  	F0 int
    32  }
    33  
    34  type S7 struct {
    35  	S1
    36  }
    37  
    38  type S9 struct {
    39  	*S1
    40  }
    41  
    42  type S10PD *struct {
    43  	S1
    44  }
    45  
    46  func _printValue(x interface{}) {
    47  	if reflect.TypeOf(x).Kind() == reflect.Func {
    48  		fmt.Println("function")
    49  	} else {
    50  		fmt.Println(x)
    51  	}
    52  }
    53  
    54  func TestSelectors(t *testing.T) {
    55  	t.Parallel()
    56  
    57  	x0 := struct{ F0 int }{1}
    58  	_printValue(x0.F0) //       *ST.F0
    59  	//                            F:0
    60  	//                          VPField{depth:0,index:0}
    61  	x1 := S1{1}
    62  	_printValue(x1.F0) //       *DT(S1)>*ST.F0
    63  	//                          +1        F:0
    64  	//                          VPField{depth:1,index:0}
    65  	_printValue(x1.Hello) //    *DT(S1).Hello
    66  	//                          +1    M:0
    67  	//                          VPValMethod{index:0}
    68  	_printValue(x1.Bye) //      *PT(implied)>*DT(S1).Bye
    69  	//                          +D           +1   *M:1
    70  	//                          VPDerefPtrMethod{index:1}
    71  	x2 := &x0
    72  	_printValue(x2.F0) //       *PT>*ST.F0
    73  	//                          +D    F:0
    74  	//                          VPDerefField{depth:0,index:0}
    75  	var x3 PS1 = &struct{ F0 int }{1}
    76  	_printValue(x3.F0) //       *DT(S1P)>*PT>*ST.F0
    77  	//                          +1       +D   F:0
    78  	//                          VPDerefField{depth:1,index:0}
    79  	x4 := &S1{1}
    80  	_printValue(x4.F0) //       *PT>*DT(S1P)>*ST.F0
    81  	//                          +D  +1         F:0
    82  	//                          VPDerefField{depth:2,index:0}
    83  	var x5 S1P = &S1{1}
    84  	_printValue(x5.F0) //       *DT(S1P)>*PT>*DT(S1)>*ST.F0
    85  	//                          +1       +D  +1        F:0
    86  	//                          VPDerefField{depth:3,index:0}
    87  	x6 := &x5
    88  	_printValue(x6)
    89  	// _printValue(x6.F0)       *PT>*DT(S1P)??? > *PT>*DT(S1)>*ST.F0
    90  	//                          +D  +1            +D  +1        F:0
    91  	//                          VPDerefField{depth:1,index:0}(WRONG!!!) > VPDerefField{depth:1,index:0} XXX ERROR
    92  	x7 := S7{S1{1}}
    93  	_printValue(x7.F0) //       *DT(S7)>*ST.S1 > *DT(S1)>*ST.F0
    94  	//                          +1        F:0    +1        F:0
    95  	//                          VPField{depth:1,index:0} > VPField{depth:1,index:0}
    96  	x8 := &x7
    97  	_printValue(x8.F0) //       *PT>*DT(S7)>*ST.S1 > *DT(S1)>*ST.F0
    98  	//                          +D  +1        F:0    +1        F:0
    99  	//                          VPDerefField{depth:1,index:0} > VPField{depth:1,index:0}
   100  	x9 := S9{x5}
   101  	_printValue(x9.F0) //       *DT(S9)>*ST.S1 > *PT>*DT(S1)>*ST.F0
   102  	//                          +1        F:0    +D  +1        F:0
   103  	//                          VPField{depth:1,index:0} > VPDerefField{depth:1,index:0}
   104  	x10 := struct{ S1 }{S1{1}}
   105  	_printValue(x10.F0) //      *ST.S1 > *DT(S1)>*ST.F0
   106  	//                            F:0    +1        F:0
   107  	//                          VPField{depth:0,index:0} > VPField{depth:1,index:0}
   108  	_printValue(x10.Hello) //   *ST.S1 > *DT(S1).Hello
   109  	//                            F:0    +1    M:0
   110  	//                          VPField{depth:0,index:0} > VPValMethod{index:0}
   111  	_printValue(x10.Bye) //     (*PT>)*ST.S1 > *DT(S1).Bye
   112  	//                           +S     F:0    +1   *M:1
   113  	//                          VPSubrefField{depth:0,index:0} > VPDerefPtrMethod{index:1}
   114  	x10p := &x10
   115  	_printValue(x10p.F0) //     *PT>*ST.S1 > *DT(S1)>*ST.F0
   116  	//                          +D    F:0    +1        F:0
   117  	//                          VPDerefField{depth:0,index:0} > VPField{depth:1,index:0}
   118  	_printValue(x10p.Hello) //  *PT>*ST.S1 > *DT(S1).Hello
   119  	//                          +D    F:0    +1    M:0
   120  	//                          VPDerefField{depth:0,index:0} > VPValMethod{index:0}
   121  	_printValue(x10p.Bye) //    *PT>*ST.S1 > *DT(S1).Bye
   122  	//                          +D    F:0    +1   *M:1
   123  	//                          VPSubrefField{depth:0,index:0} > VPDerefPtrMethod{index:1}
   124  	var x10pd S10PD = &struct{ S1 }{S1{1}}
   125  	_printValue(x10pd.F0) //    *DT(S10PD)>*PT>*ST.S1 > *DT(S1)>*ST.F0
   126  	//                          +1         +D    F:0    +1        F:0
   127  	//                          VPDerefField{depth:1,index:0} > VPField{depth:1,index:0}
   128  	// _printValue(x10pd.Hello) *DT(S10PD)>*PT>*ST.S1 > *DT(S1).Hello XXX weird, doesn't work.
   129  	//                          +1         +D    F:0    +1    M:0
   130  	//                          VPDerefField{depth:1,index:0} > VPValMethod{index:0}
   131  	_printValue(x10p.Bye) //    *DT(S10PD)>*PT>*ST.S1 > *DT(S1).Bye
   132  	//                          +1         +D    F:0    +1   *M:1
   133  	//                          VPSubrefField{depth:1,index:0} > VPDerefPtrMethod{index:1}
   134  	x11 := S7{S1{1}}
   135  	_printValue(x11.F0) //      *DT(S7)>*ST.S1 > *DT(S1)>*ST.F0 NOTE same as x7.
   136  	//                          +1        F:0    +1        F:0
   137  	//                          VPField{depth:1,index:0} > VPField{depth:1,index:0}
   138  	_printValue(x11.Hello) //   *DT(S7)>*ST.S1 > *DT(S1)>*ST.Hello
   139  	//                          +1        F:0    +1        M:0
   140  	//                          VPField{depth:1,index:0} > VPValMethod{index:0}
   141  	_printValue(x11.Bye) //     (*PT>)*DT(S7)>*ST.S1 > *DT(S1).Bye
   142  	//                           +S   +1        F:0    +1   *M:1
   143  	//                          VPSubrefField{depth:2,index:0} > VPDerefPtrMethod{index:1}
   144  	x11p := &S7{S1{1}}
   145  	_printValue(x11p.F0) //     *PT>*DT(S7)>*ST.S1 > *DT(S1)>*ST.F0
   146  	//                          +1            F:0    +1        F:0
   147  	//                          VPDerefField{depth:2,index:0} > VPField{depth:1,index:0}
   148  	_printValue(x11p.Hello) //  *PT>*DT(S7)>*ST.S1 > *DT(S1).Hello
   149  	//                          +1            F:0    +1    M:0
   150  	//                          VPDerefField{depth:2,index:0} > VPValMethod{index:0}
   151  	_printValue(x11p.Bye) //    *PT>*DT(S7)>*ST.S1 > *DT(S1).Bye
   152  	//                          +1            F:0    +1   *M:1
   153  	//                          VPSubrefField{depth:2,index:0} > VPDerefPtrMethod{index:1}
   154  	x12 := struct{ *S1 }{&S1{1}}
   155  	_printValue(x12.F0) //      *ST.S1 > *PT>*DT(S1)>*ST.F0
   156  	//                            F:0    +D  +1        F:0
   157  	//                          VPField{depth:0,index:0} > VPDerefField{depth:1,index:0}
   158  	_printValue(x12.Hello) //   *ST.S1 > *PT>*DT(S1).Hello
   159  	//                            F:0    +D  +1    M:0
   160  	//                          VPField{depth:0,index:0} > VPDerefValMethod{index:0}
   161  	_printValue(x12.Bye) //     *ST.S1 > *PT>*DT(S1).Bye
   162  	//                            F:0    +D  +1   *M:1
   163  	//                          VPField{depth:0,index:0} > VPDerefPtrMethod{index:1}
   164  	x13 := &x12
   165  	_printValue(x13.F0) //      *PT>*ST.S1 > *PT>*DT(S1)>*ST.F0
   166  	//                          +D    F:0    +D  +1        F:0
   167  	//                          VPDerefField{depth:0,index:0} > VPDerefField{depth:1,index:0}
   168  	_printValue(x13.Hello) //   *PT>*ST.S1 > *PT>*DT(S1).Hello
   169  	//                          +D    F:0    +D  +1    M:0
   170  	//                          VPDerefField{depth:0,index:0} > VPDerefValMethod{index:0}
   171  	_printValue(x13.Bye) //     *PT>*ST.S1 > *PT>*DT(S1).Bye
   172  	//                          +D    F:0    +D  +1   *M:1
   173  	//                          VPDerefField{depth:0,index:0} > VPDerefPtrMethod{index:1}
   174  }