github.com/mh-cbon/go@v0.0.0-20160603070303-9e112a3fe4c0/test/method5.go (about) 1 // run 2 3 // Copyright 2013 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 package main 8 9 // Concrete types implementing M method. 10 // Smaller than a word, word-sized, larger than a word. 11 // Value and pointer receivers. 12 13 type Tinter interface { 14 M(int, byte) (byte, int) 15 } 16 17 type Tsmallv byte 18 19 func (v Tsmallv) M(x int, b byte) (byte, int) { return b, x+int(v) } 20 21 type Tsmallp byte 22 23 func (p *Tsmallp) M(x int, b byte) (byte, int) { return b, x+int(*p) } 24 25 type Twordv uintptr 26 27 func (v Twordv) M(x int, b byte) (byte, int) { return b, x+int(v) } 28 29 type Twordp uintptr 30 31 func (p *Twordp) M(x int, b byte) (byte, int) { return b, x+int(*p) } 32 33 type Tbigv [2]uintptr 34 35 func (v Tbigv) M(x int, b byte) (byte, int) { return b, x+int(v[0])+int(v[1]) } 36 37 type Tbigp [2]uintptr 38 39 func (p *Tbigp) M(x int, b byte) (byte, int) { return b, x+int(p[0])+int(p[1]) } 40 41 // Again, with an unexported method. 42 43 type tsmallv byte 44 45 func (v tsmallv) m(x int, b byte) (byte, int) { return b, x+int(v) } 46 47 type tsmallp byte 48 49 func (p *tsmallp) m(x int, b byte) (byte, int) { return b, x+int(*p) } 50 51 type twordv uintptr 52 53 func (v twordv) m(x int, b byte) (byte, int) { return b, x+int(v) } 54 55 type twordp uintptr 56 57 func (p *twordp) m(x int, b byte) (byte, int) { return b, x+int(*p) } 58 59 type tbigv [2]uintptr 60 61 func (v tbigv) m(x int, b byte) (byte, int) { return b, x+int(v[0])+int(v[1]) } 62 63 type tbigp [2]uintptr 64 65 func (p *tbigp) m(x int, b byte) (byte, int) { return b, x+int(p[0])+int(p[1]) } 66 67 type tinter interface { 68 m(int, byte) (byte, int) 69 } 70 71 // Embedding via pointer. 72 73 type T1 struct { 74 T2 75 } 76 77 type T2 struct { 78 *T3 79 } 80 81 type T3 struct { 82 *T4 83 } 84 85 type T4 struct { 86 } 87 88 func (t4 T4) M(x int, b byte) (byte, int) { return b, x+40 } 89 90 var failed = false 91 92 func CheckI(name string, i Tinter, inc int) { 93 b, x := i.M(1000, 99) 94 if b != 99 || x != 1000+inc { 95 failed = true 96 print(name, ".M(1000, 99) = ", b, ", ", x, " want 99, ", 1000+inc, "\n") 97 } 98 99 CheckF("(i="+name+")", i.M, inc) 100 } 101 102 func CheckF(name string, f func(int, byte) (byte, int), inc int) { 103 b, x := f(1000, 99) 104 if b != 99 || x != 1000+inc { 105 failed = true 106 print(name, "(1000, 99) = ", b, ", ", x, " want 99, ", 1000+inc, "\n") 107 } 108 } 109 110 func checkI(name string, i tinter, inc int) { 111 b, x := i.m(1000, 99) 112 if b != 99 || x != 1000+inc { 113 failed = true 114 print(name, ".m(1000, 99) = ", b, ", ", x, " want 99, ", 1000+inc, "\n") 115 } 116 117 checkF("(i="+name+")", i.m, inc) 118 } 119 120 func checkF(name string, f func(int, byte) (byte, int), inc int) { 121 b, x := f(1000, 99) 122 if b != 99 || x != 1000+inc { 123 failed = true 124 print(name, "(1000, 99) = ", b, ", ", x, " want 99, ", 1000+inc, "\n") 125 } 126 } 127 128 func shouldPanic(f func()) { 129 defer func() { 130 if recover() == nil { 131 panic("not panicking") 132 } 133 }() 134 f() 135 } 136 137 func shouldNotPanic(f func()) { 138 f() 139 } 140 141 func main() { 142 sv := Tsmallv(1) 143 CheckI("sv", sv, 1) 144 CheckF("sv.M", sv.M, 1) 145 CheckF("(&sv).M", (&sv).M, 1) 146 psv := &sv 147 CheckI("psv", psv, 1) 148 CheckF("psv.M", psv.M, 1) 149 CheckF("(*psv).M", (*psv).M, 1) 150 151 sp := Tsmallp(2) 152 CheckI("&sp", &sp, 2) 153 CheckF("sp.M", sp.M, 2) 154 CheckF("(&sp).M", (&sp).M, 2) 155 psp := &sp 156 CheckI("psp", psp, 2) 157 CheckF("psp.M", psp.M, 2) 158 CheckF("(*psp).M", (*psp).M, 2) 159 160 wv := Twordv(3) 161 CheckI("wv", wv, 3) 162 CheckF("wv.M", wv.M, 3) 163 CheckF("(&wv).M", (&wv).M, 3) 164 pwv := &wv 165 CheckI("pwv", pwv, 3) 166 CheckF("pwv.M", pwv.M, 3) 167 CheckF("(*pwv).M", (*pwv).M, 3) 168 169 wp := Twordp(4) 170 CheckI("&wp", &wp, 4) 171 CheckF("wp.M", wp.M, 4) 172 CheckF("(&wp).M", (&wp).M, 4) 173 pwp := &wp 174 CheckI("pwp", pwp, 4) 175 CheckF("pwp.M", pwp.M, 4) 176 CheckF("(*pwp).M", (*pwp).M, 4) 177 178 bv := Tbigv([2]uintptr{5, 6}) 179 pbv := &bv 180 CheckI("bv", bv, 11) 181 CheckF("bv.M", bv.M, 11) 182 CheckF("(&bv).M", (&bv).M, 11) 183 CheckI("pbv", pbv, 11) 184 CheckF("pbv.M", pbv.M, 11) 185 CheckF("(*pbv).M", (*pbv).M, 11) 186 187 bp := Tbigp([2]uintptr{7,8}) 188 CheckI("&bp", &bp, 15) 189 CheckF("bp.M", bp.M, 15) 190 CheckF("(&bp).M", (&bp).M, 15) 191 pbp := &bp 192 CheckI("pbp", pbp, 15) 193 CheckF("pbp.M", pbp.M, 15) 194 CheckF("(*pbp).M", (*pbp).M, 15) 195 196 _sv := tsmallv(1) 197 checkI("_sv", _sv, 1) 198 checkF("_sv.m", _sv.m, 1) 199 checkF("(&_sv).m", (&_sv).m, 1) 200 _psv := &_sv 201 checkI("_psv", _psv, 1) 202 checkF("_psv.m", _psv.m, 1) 203 checkF("(*_psv).m", (*_psv).m, 1) 204 205 _sp := tsmallp(2) 206 checkI("&_sp", &_sp, 2) 207 checkF("_sp.m", _sp.m, 2) 208 checkF("(&_sp).m", (&_sp).m, 2) 209 _psp := &_sp 210 checkI("_psp", _psp, 2) 211 checkF("_psp.m", _psp.m, 2) 212 checkF("(*_psp).m", (*_psp).m, 2) 213 214 _wv := twordv(3) 215 checkI("_wv", _wv, 3) 216 checkF("_wv.m", _wv.m, 3) 217 checkF("(&_wv).m", (&_wv).m, 3) 218 _pwv := &_wv 219 checkI("_pwv", _pwv, 3) 220 checkF("_pwv.m", _pwv.m, 3) 221 checkF("(*_pwv).m", (*_pwv).m, 3) 222 223 _wp := twordp(4) 224 checkI("&_wp", &_wp, 4) 225 checkF("_wp.m", _wp.m, 4) 226 checkF("(&_wp).m", (&_wp).m, 4) 227 _pwp := &_wp 228 checkI("_pwp", _pwp, 4) 229 checkF("_pwp.m", _pwp.m, 4) 230 checkF("(*_pwp).m", (*_pwp).m, 4) 231 232 _bv := tbigv([2]uintptr{5, 6}) 233 _pbv := &_bv 234 checkI("_bv", _bv, 11) 235 checkF("_bv.m", _bv.m, 11) 236 checkF("(&_bv).m", (&_bv).m, 11) 237 checkI("_pbv", _pbv, 11) 238 checkF("_pbv.m", _pbv.m, 11) 239 checkF("(*_pbv).m", (*_pbv).m, 11) 240 241 _bp := tbigp([2]uintptr{7,8}) 242 checkI("&_bp", &_bp, 15) 243 checkF("_bp.m", _bp.m, 15) 244 checkF("(&_bp).m", (&_bp).m, 15) 245 _pbp := &_bp 246 checkI("_pbp", _pbp, 15) 247 checkF("_pbp.m", _pbp.m, 15) 248 checkF("(*_pbp).m", (*_pbp).m, 15) 249 250 t4 := T4{} 251 t3 := T3{&t4} 252 t2 := T2{&t3} 253 t1 := T1{t2} 254 CheckI("t4", t4, 40) 255 CheckI("&t4", &t4, 40) 256 CheckI("t3", t3, 40) 257 CheckI("&t3", &t3, 40) 258 CheckI("t2", t2, 40) 259 CheckI("&t2", &t2, 40) 260 CheckI("t1", t1, 40) 261 CheckI("&t1", &t1, 40) 262 263 // x.M panics if x is an interface type and is nil, 264 // or if x.M expands to (*x).M where x is nil, 265 // or if x.M expands to x.y.z.w.M where something 266 // along the evaluation of x.y.z.w is nil. 267 var f func(int, byte) (byte, int) 268 shouldPanic(func() { psv = nil; f = psv.M }) 269 shouldPanic(func() { pwv = nil; f = pwv.M }) 270 shouldPanic(func() { pbv = nil; f = pbv.M }) 271 shouldPanic(func() { var i Tinter; f = i.M }) 272 shouldPanic(func() { _psv = nil; f = _psv.m }) 273 shouldPanic(func() { _pwv = nil; f = _pwv.m }) 274 shouldPanic(func() { _pbv = nil; f = _pbv.m }) 275 shouldPanic(func() { var _i tinter; f = _i.m }) 276 shouldPanic(func() { var t1 T1; f = t1.M }) 277 shouldPanic(func() { var t2 T2; f = t2.M }) 278 shouldPanic(func() { var t3 *T3; f = t3.M }) 279 shouldPanic(func() { var t3 T3; f = t3.M }) 280 281 if f != nil { 282 panic("something set f") 283 } 284 285 // x.M does not panic if x is a nil pointer and 286 // M is a method with a pointer receiver. 287 shouldNotPanic(func() { psp = nil; f = psp.M }) 288 shouldNotPanic(func() { pwp = nil; f = pwp.M }) 289 shouldNotPanic(func() { pbp = nil; f = pbp.M }) 290 shouldNotPanic(func() { _psp = nil; f = _psp.m }) 291 shouldNotPanic(func() { _pwp = nil; f = _pwp.m }) 292 shouldNotPanic(func() { _pbp = nil; f = _pbp.m }) 293 shouldNotPanic(func() { var t4 T4; f = t4.M }) 294 if f == nil { 295 panic("nothing set f") 296 } 297 }