1
0
mirror of https://github.com/golang/go synced 2024-10-01 03:38:32 -06: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:
Alan Donovan 2014-02-12 12:45:55 -05:00
parent 05bc285da4
commit 8c7a4539cd
2 changed files with 24 additions and 1 deletions

View File

@ -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.

View File

@ -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() {