func (p *Tbigp) M(x int, b byte) (byte, int) { return b, x + int(p[0]) + int(p[1]) }
-// Again, with an unexported method.
-
-type tsmallv byte
-
-func (v tsmallv) m(x int, b byte) (byte, int) { return b, x + int(v) }
-
-type tsmallp byte
-
-func (p *tsmallp) m(x int, b byte) (byte, int) { return b, x + int(*p) }
-
-type twordv uintptr
-
-func (v twordv) m(x int, b byte) (byte, int) { return b, x + int(v) }
-
-type twordp uintptr
-
-func (p *twordp) m(x int, b byte) (byte, int) { return b, x + int(*p) }
-
-type tbigv [2]uintptr
-
-func (v tbigv) m(x int, b byte) (byte, int) { return b, x + int(v[0]) + int(v[1]) }
-
-type tbigp [2]uintptr
-
-func (p *tbigp) m(x int, b byte) (byte, int) { return b, x + int(p[0]) + int(p[1]) }
-
type tinter interface {
m(int, byte) (byte, int)
}
}
var TinterType = TypeOf(new(Tinter)).Elem()
- var tinterType = TypeOf(new(tinter)).Elem()
CheckI := func(name string, i interface{}, inc int) {
v := ValueOf(i)
CheckI("t1", t1, 40)
CheckI("&t1", &t1, 40)
- methodShouldPanic := func(name string, i interface{}) {
- v := ValueOf(i)
- m := v.Method(0)
- shouldPanic(func() { m.Call([]Value{ValueOf(1000), ValueOf(byte(99))}) })
- shouldPanic(func() { m.Interface() })
-
- v = v.Convert(tinterType)
- m = v.Method(0)
- shouldPanic(func() { m.Call([]Value{ValueOf(1000), ValueOf(byte(99))}) })
- shouldPanic(func() { m.Interface() })
- }
-
- _sv := tsmallv(1)
- methodShouldPanic("_sv", _sv)
- methodShouldPanic("&_sv", &_sv)
-
- _sp := tsmallp(2)
- methodShouldPanic("&_sp", &_sp)
-
- _wv := twordv(3)
- methodShouldPanic("_wv", _wv)
- methodShouldPanic("&_wv", &_wv)
-
- _wp := twordp(4)
- methodShouldPanic("&_wp", &_wp)
-
- _bv := tbigv([2]uintptr{5, 6})
- methodShouldPanic("_bv", _bv)
- methodShouldPanic("&_bv", &_bv)
-
- _bp := tbigp([2]uintptr{7, 8})
- methodShouldPanic("&_bp", &_bp)
-
var tnil Tinter
vnil := ValueOf(&tnil).Elem()
shouldPanic(func() { vnil.Method(0) })
func TestUnexportedMethods(t *testing.T) {
typ := TypeOf(unexpi)
- if got := typ.NumMethod(); got != 1 {
- t.Error("NumMethod=%d, want 1 satisfied method", got)
- }
- if typ.Method(0).Type == nil {
- t.Error("missing type for satisfied method 'f'")
- }
- if !typ.Method(0).Func.IsValid() {
- t.Error("missing func for satisfied method 'f'")
+ if got := typ.NumMethod(); got != 0 {
+ t.Errorf("NumMethod=%d, want 0 satisfied methods", got)
}
}
isValid(v.Elem().Field(1))
isValid(v.Elem().FieldByName("x"))
isValid(v.Elem().FieldByName("y"))
- isValid(v.Type().Method(0).Func)
shouldPanic(func() { v.Elem().Field(0).Interface() })
shouldPanic(func() { v.Elem().Field(1).Interface() })
shouldPanic(func() { v.Elem().FieldByName("x").Interface() })
shouldPanic(func() { v.Elem().FieldByName("y").Interface() })
- shouldPanic(func() { v.Type().Method(0).Func.Interface() })
+ shouldPanic(func() { v.Type().Method(0) })
}
func TestSetPanic(t *testing.T) {
}
}
-func TestMethodPkgPathReadable(t *testing.T) {
- // Reading the Method type for an unexported method triggers an
- // offset resolution via p.name.pkgPath(). Make sure it uses a
- // valid base pointer for the offset.
- v := ValueOf(embed{})
- m := v.Type().Method(0)
- if m.PkgPath != "reflect" {
- t.Errorf(`PkgPath=%q, want "reflect"`, m.PkgPath)
- }
-}
-
func TestTypeStrings(t *testing.T) {
type stringTest struct {
typ Type
m map[*rtype][]method
}
-// satisfiedMethods returns methods of t that satisfy an interface.
-// This may include unexported methods that satisfy an interface
-// defined with unexported methods in the same package as t.
-func (t *rtype) satisfiedMethods() []method {
+func (t *rtype) exportedMethods() []method {
methodCache.RLock()
methods, found := methodCache.m[t]
methodCache.RUnlock()
return nil
}
allm := ut.methods()
- allSatisfied := true
+ allExported := true
for _, m := range allm {
- if m.mtyp == 0 {
- allSatisfied = false
+ name := t.nameOff(m.name)
+ if !name.isExported() {
+ allExported = false
break
}
}
- if allSatisfied {
+ if allExported {
methods = allm
} else {
methods = make([]method, 0, len(allm))
for _, m := range allm {
- if m.mtyp != 0 {
+ name := t.nameOff(m.name)
+ if name.isExported() {
methods = append(methods, m)
}
}
tt := (*interfaceType)(unsafe.Pointer(t))
return tt.NumMethod()
}
- return len(t.satisfiedMethods())
+ return len(t.exportedMethods())
}
func (t *rtype) Method(i int) (m Method) {
tt := (*interfaceType)(unsafe.Pointer(t))
return tt.Method(i)
}
- methods := t.satisfiedMethods()
+ methods := t.exportedMethods()
if i < 0 || i >= len(methods) {
panic("reflect: Method index out of range")
}
pname := t.nameOff(p.name)
m.Name = pname.name()
fl := flag(Func)
- if !pname.isExported() {
- m.PkgPath = pname.pkgPath()
- if m.PkgPath == "" {
- ut := t.uncommon()
- m.PkgPath = t.nameOff(ut.pkgPath).name()
- }
- fl |= flagStickyRO
- }
mtyp := t.typeOff(p.mtyp)
ft := (*funcType)(unsafe.Pointer(mtyp))
in := make([]Type, 0, 1+len(ft.in()))