mirror of
https://github.com/golang/go
synced 2024-11-27 04:11:22 -07:00
reflect: remove type info for unexported methods
Also remove some of the now unnecessary corner case handling and tests I've been adding recently for unexported method data. For #15673 Change-Id: Ie0c7b03f2370bbe8508cdc5be765028f08000bd7 Reviewed-on: https://go-review.googlesource.com/23410 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
f2f3b6cd8f
commit
9f38796270
@ -1889,32 +1889,6 @@ type Tbigp [2]uintptr
|
||||
|
||||
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)
|
||||
}
|
||||
@ -1958,7 +1932,6 @@ func TestMethod5(t *testing.T) {
|
||||
}
|
||||
|
||||
var TinterType = TypeOf(new(Tinter)).Elem()
|
||||
var tinterType = TypeOf(new(tinter)).Elem()
|
||||
|
||||
CheckI := func(name string, i interface{}, inc int) {
|
||||
v := ValueOf(i)
|
||||
@ -2000,39 +1973,6 @@ func TestMethod5(t *testing.T) {
|
||||
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) })
|
||||
@ -2416,14 +2356,8 @@ var unexpi unexpI = new(unexp)
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -2915,12 +2849,11 @@ func TestUnexported(t *testing.T) {
|
||||
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) {
|
||||
@ -5769,17 +5702,6 @@ func TestNameBytesAreAligned(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
|
||||
|
@ -768,10 +768,7 @@ var methodCache struct {
|
||||
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()
|
||||
@ -785,19 +782,21 @@ func (t *rtype) satisfiedMethods() []method {
|
||||
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)
|
||||
}
|
||||
}
|
||||
@ -819,7 +818,7 @@ func (t *rtype) NumMethod() int {
|
||||
tt := (*interfaceType)(unsafe.Pointer(t))
|
||||
return tt.NumMethod()
|
||||
}
|
||||
return len(t.satisfiedMethods())
|
||||
return len(t.exportedMethods())
|
||||
}
|
||||
|
||||
func (t *rtype) Method(i int) (m Method) {
|
||||
@ -827,7 +826,7 @@ 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")
|
||||
}
|
||||
@ -835,14 +834,6 @@ func (t *rtype) Method(i int) (m Method) {
|
||||
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()))
|
||||
|
Loading…
Reference in New Issue
Block a user