mirror of
https://github.com/golang/go
synced 2024-11-18 21:44:45 -07:00
go.tools/pointer: implement (*reflect.rtype).MethodByName for abstract methods.
+ test. LGTM=crawshaw R=crawshaw CC=golang-codereviews https://golang.org/cl/25810043
This commit is contained in:
parent
05bc285da4
commit
8c7a4539cd
@ -1566,6 +1566,8 @@ func (c *rtypeMethodByNameConstraint) solve(a *analysis, _ *node, delta nodeset)
|
||||
for tObj := range delta {
|
||||
T := a.nodes[tObj].obj.data.(types.Type)
|
||||
|
||||
_, isInterface := T.Underlying().(*types.Interface)
|
||||
|
||||
// We don't use Lookup(c.name) when c.name != "" to avoid
|
||||
// ambiguity: >1 unexported methods could match.
|
||||
mset := a.prog.MethodSets.MethodSet(T)
|
||||
@ -1582,8 +1584,17 @@ func (c *rtypeMethodByNameConstraint) solve(a *analysis, _ *node, delta nodeset)
|
||||
// }
|
||||
fn := a.prog.Method(sel)
|
||||
|
||||
sig := fn.Signature
|
||||
if isInterface {
|
||||
// discard receiver
|
||||
sig = types.NewSignature(nil, nil, sig.Params(), sig.Results(), sig.Variadic())
|
||||
} else {
|
||||
// move receiver to params[0]
|
||||
sig = changeRecv(sig)
|
||||
|
||||
}
|
||||
// a.offsetOf(Type) is 3.
|
||||
if id := c.result + 3; a.addLabel(id, a.makeRtype(changeRecv(fn.Signature))) {
|
||||
if id := c.result + 3; a.addLabel(id, a.makeRtype(sig)) {
|
||||
a.addWork(id)
|
||||
}
|
||||
// a.offsetOf(Func) is 4.
|
||||
|
12
go/pointer/testdata/funcreflect.go
vendored
12
go/pointer/testdata/funcreflect.go
vendored
@ -82,6 +82,10 @@ type U struct{}
|
||||
func (U) F(int) {}
|
||||
func (U) g(string) {}
|
||||
|
||||
type I interface {
|
||||
f()
|
||||
}
|
||||
|
||||
var nonconst string
|
||||
|
||||
func reflectTypeMethodByName() {
|
||||
@ -101,6 +105,14 @@ func reflectTypeMethodByName() {
|
||||
X, _ := U.MethodByName(nonconst)
|
||||
print(reflect.Zero(X.Type)) // @types func(U, int) | func(U, string)
|
||||
print(X.Func) // @pointsto (main.U).F | (main.U).g
|
||||
|
||||
// Interface methods.
|
||||
rThasF := reflect.TypeOf(new(hasF)).Elem()
|
||||
print(reflect.Zero(rThasF)) // @types hasF
|
||||
F2, _ := rThasF.MethodByName("F")
|
||||
print(reflect.Zero(F2.Type)) // @types func()
|
||||
print(F2.Func) // @pointsto (main.hasF).F
|
||||
|
||||
}
|
||||
|
||||
func reflectTypeMethod() {
|
||||
|
Loading…
Reference in New Issue
Block a user