type Private struct {
x int
y **int
+ Z int
}
func (p *Private) m() {
}
+type private struct {
+ Z int
+ z int
+ S string
+ A [1]Private
+ T []Private
+}
+
+func (p *private) P() {
+}
+
type Public struct {
X int
Y **int
+ private
}
func (p *Public) M() {
func TestUnexported(t *testing.T) {
var pub Public
+ pub.S = "S"
+ pub.T = pub.A[:]
v := ValueOf(&pub)
isValid(v.Elem().Field(0))
isValid(v.Elem().Field(1))
+ isValid(v.Elem().Field(2))
isValid(v.Elem().FieldByName("X"))
isValid(v.Elem().FieldByName("Y"))
+ isValid(v.Elem().FieldByName("Z"))
isValid(v.Type().Method(0).Func)
+ m, _ := v.Type().MethodByName("M")
+ isValid(m.Func)
+ m, _ = v.Type().MethodByName("P")
+ isValid(m.Func)
isNonNil(v.Elem().Field(0).Interface())
isNonNil(v.Elem().Field(1).Interface())
+ isNonNil(v.Elem().Field(2).Field(2).Index(0))
isNonNil(v.Elem().FieldByName("X").Interface())
isNonNil(v.Elem().FieldByName("Y").Interface())
+ isNonNil(v.Elem().FieldByName("Z").Interface())
+ isNonNil(v.Elem().FieldByName("S").Index(0).Interface())
isNonNil(v.Type().Method(0).Func.Interface())
+ m, _ = v.Type().MethodByName("P")
+ isNonNil(m.Func.Interface())
var priv Private
v = ValueOf(&priv)
shouldPanic(func() { v.Type().Method(0).Func.Interface() })
}
+func TestSetPanic(t *testing.T) {
+ ok := func(f func()) { f() }
+ bad := shouldPanic
+ clear := func(v Value) { v.Set(Zero(v.Type())) }
+
+ type t0 struct {
+ W int
+ }
+
+ type t1 struct {
+ Y int
+ t0
+ }
+
+ type T2 struct {
+ Z int
+ namedT0 t0
+ }
+
+ type T struct {
+ X int
+ t1
+ T2
+ NamedT1 t1
+ NamedT2 T2
+ namedT1 t1
+ namedT2 T2
+ }
+
+ // not addressable
+ v := ValueOf(T{})
+ bad(func() { clear(v.Field(0)) }) // .X
+ bad(func() { clear(v.Field(1)) }) // .t1
+ bad(func() { clear(v.Field(1).Field(0)) }) // .t1.Y
+ bad(func() { clear(v.Field(1).Field(1)) }) // .t1.t0
+ bad(func() { clear(v.Field(1).Field(1).Field(0)) }) // .t1.t0.W
+ bad(func() { clear(v.Field(2)) }) // .T2
+ bad(func() { clear(v.Field(2).Field(0)) }) // .T2.Z
+ bad(func() { clear(v.Field(2).Field(1)) }) // .T2.namedT0
+ bad(func() { clear(v.Field(2).Field(1).Field(0)) }) // .T2.namedT0.W
+ bad(func() { clear(v.Field(3)) }) // .NamedT1
+ bad(func() { clear(v.Field(3).Field(0)) }) // .NamedT1.Y
+ bad(func() { clear(v.Field(3).Field(1)) }) // .NamedT1.t0
+ bad(func() { clear(v.Field(3).Field(1).Field(0)) }) // .NamedT1.t0.W
+ bad(func() { clear(v.Field(4)) }) // .NamedT2
+ bad(func() { clear(v.Field(4).Field(0)) }) // .NamedT2.Z
+ bad(func() { clear(v.Field(4).Field(1)) }) // .NamedT2.namedT0
+ bad(func() { clear(v.Field(4).Field(1).Field(0)) }) // .NamedT2.namedT0.W
+ bad(func() { clear(v.Field(5)) }) // .namedT1
+ bad(func() { clear(v.Field(5).Field(0)) }) // .namedT1.Y
+ bad(func() { clear(v.Field(5).Field(1)) }) // .namedT1.t0
+ bad(func() { clear(v.Field(5).Field(1).Field(0)) }) // .namedT1.t0.W
+ bad(func() { clear(v.Field(6)) }) // .namedT2
+ bad(func() { clear(v.Field(6).Field(0)) }) // .namedT2.Z
+ bad(func() { clear(v.Field(6).Field(1)) }) // .namedT2.namedT0
+ bad(func() { clear(v.Field(6).Field(1).Field(0)) }) // .namedT2.namedT0.W
+
+ // addressable
+ v = ValueOf(&T{}).Elem()
+ ok(func() { clear(v.Field(0)) }) // .X
+ bad(func() { clear(v.Field(1)) }) // .t1
+ ok(func() { clear(v.Field(1).Field(0)) }) // .t1.Y
+ bad(func() { clear(v.Field(1).Field(1)) }) // .t1.t0
+ ok(func() { clear(v.Field(1).Field(1).Field(0)) }) // .t1.t0.W
+ ok(func() { clear(v.Field(2)) }) // .T2
+ ok(func() { clear(v.Field(2).Field(0)) }) // .T2.Z
+ bad(func() { clear(v.Field(2).Field(1)) }) // .T2.namedT0
+ bad(func() { clear(v.Field(2).Field(1).Field(0)) }) // .T2.namedT0.W
+ ok(func() { clear(v.Field(3)) }) // .NamedT1
+ ok(func() { clear(v.Field(3).Field(0)) }) // .NamedT1.Y
+ bad(func() { clear(v.Field(3).Field(1)) }) // .NamedT1.t0
+ ok(func() { clear(v.Field(3).Field(1).Field(0)) }) // .NamedT1.t0.W
+ ok(func() { clear(v.Field(4)) }) // .NamedT2
+ ok(func() { clear(v.Field(4).Field(0)) }) // .NamedT2.Z
+ bad(func() { clear(v.Field(4).Field(1)) }) // .NamedT2.namedT0
+ bad(func() { clear(v.Field(4).Field(1).Field(0)) }) // .NamedT2.namedT0.W
+ bad(func() { clear(v.Field(5)) }) // .namedT1
+ bad(func() { clear(v.Field(5).Field(0)) }) // .namedT1.Y
+ bad(func() { clear(v.Field(5).Field(1)) }) // .namedT1.t0
+ bad(func() { clear(v.Field(5).Field(1).Field(0)) }) // .namedT1.t0.W
+ bad(func() { clear(v.Field(6)) }) // .namedT2
+ bad(func() { clear(v.Field(6).Field(0)) }) // .namedT2.Z
+ bad(func() { clear(v.Field(6).Field(1)) }) // .namedT2.namedT0
+ bad(func() { clear(v.Field(6).Field(1).Field(0)) }) // .namedT2.namedT0.W
+}
+
+type timp int
+
+func (t timp) W() {}
+func (t timp) Y() {}
+func (t timp) w() {}
+func (t timp) y() {}
+
+func TestCallPanic(t *testing.T) {
+ type t0 interface {
+ W()
+ w()
+ }
+ type T1 interface {
+ Y()
+ y()
+ }
+ type T2 struct {
+ T1
+ t0
+ }
+ type T struct {
+ t0 // 0
+ T1 // 1
+
+ NamedT0 t0 // 2
+ NamedT1 T1 // 3
+ NamedT2 T2 // 4
+
+ namedT0 t0 // 5
+ namedT1 T1 // 6
+ namedT2 T2 // 7
+ }
+ ok := func(f func()) { f() }
+ bad := shouldPanic
+ call := func(v Value) { v.Call(nil) }
+
+ i := timp(0)
+ v := ValueOf(T{i, i, i, i, T2{i, i}, i, i, T2{i, i}})
+ ok(func() { call(v.Field(0).Method(0)) }) // .t0.W
+ ok(func() { call(v.Field(0).Elem().Method(0)) }) // .t0.W
+ bad(func() { call(v.Field(0).Method(1)) }) // .t0.w
+ bad(func() { call(v.Field(0).Elem().Method(2)) }) // .t0.w
+ ok(func() { call(v.Field(1).Method(0)) }) // .T1.Y
+ ok(func() { call(v.Field(1).Elem().Method(0)) }) // .T1.Y
+ bad(func() { call(v.Field(1).Method(1)) }) // .T1.y
+ bad(func() { call(v.Field(1).Elem().Method(2)) }) // .T1.y
+
+ ok(func() { call(v.Field(2).Method(0)) }) // .NamedT0.W
+ ok(func() { call(v.Field(2).Elem().Method(0)) }) // .NamedT0.W
+ bad(func() { call(v.Field(2).Method(1)) }) // .NamedT0.w
+ bad(func() { call(v.Field(2).Elem().Method(2)) }) // .NamedT0.w
+
+ ok(func() { call(v.Field(3).Method(0)) }) // .NamedT1.Y
+ ok(func() { call(v.Field(3).Elem().Method(0)) }) // .NamedT1.Y
+ bad(func() { call(v.Field(3).Method(1)) }) // .NamedT1.y
+ bad(func() { call(v.Field(3).Elem().Method(3)) }) // .NamedT1.y
+
+ ok(func() { call(v.Field(4).Field(0).Method(0)) }) // .NamedT2.T1.Y
+ ok(func() { call(v.Field(4).Field(0).Elem().Method(0)) }) // .NamedT2.T1.W
+ ok(func() { call(v.Field(4).Field(1).Method(0)) }) // .NamedT2.t0.W
+ ok(func() { call(v.Field(4).Field(1).Elem().Method(0)) }) // .NamedT2.t0.W
+
+ bad(func() { call(v.Field(5).Method(0)) }) // .namedT0.W
+ bad(func() { call(v.Field(5).Elem().Method(0)) }) // .namedT0.W
+ bad(func() { call(v.Field(5).Method(1)) }) // .namedT0.w
+ bad(func() { call(v.Field(5).Elem().Method(2)) }) // .namedT0.w
+
+ bad(func() { call(v.Field(6).Method(0)) }) // .namedT1.Y
+ bad(func() { call(v.Field(6).Elem().Method(0)) }) // .namedT1.Y
+ bad(func() { call(v.Field(6).Method(0)) }) // .namedT1.y
+ bad(func() { call(v.Field(6).Elem().Method(0)) }) // .namedT1.y
+
+ bad(func() { call(v.Field(7).Field(0).Method(0)) }) // .namedT2.T1.Y
+ bad(func() { call(v.Field(7).Field(0).Elem().Method(0)) }) // .namedT2.T1.W
+ bad(func() { call(v.Field(7).Field(1).Method(0)) }) // .namedT2.t0.W
+ bad(func() { call(v.Field(7).Field(1).Elem().Method(0)) }) // .namedT2.t0.W
+}
+
func shouldPanic(f func()) {
defer func() {
if recover() == nil {