mirror of
https://github.com/go-delve/delve.git
synced 2025-10-29 01:27:16 +08:00
pkg/proc: fix can not call method of an embedded filed directly (#1691)
`func (v *Variable) findMethod` should support for searching methods of an embedded filed. Fixes #1688
This commit is contained in:
@ -121,6 +121,19 @@ func noreturncall(n int) {
|
||||
return
|
||||
}
|
||||
|
||||
type Base struct{
|
||||
y int
|
||||
}
|
||||
|
||||
type Derived struct {
|
||||
x int
|
||||
Base
|
||||
}
|
||||
|
||||
func (b *Base) Method() int {
|
||||
return b.y
|
||||
}
|
||||
|
||||
func main() {
|
||||
one, two := 1, 2
|
||||
intslice := []int{1, 2, 3}
|
||||
@ -142,9 +155,13 @@ func main() {
|
||||
fn2ptrmeth := pa.PRcvr
|
||||
var fn2nil func()
|
||||
|
||||
d := &Derived{3, Base{4}}
|
||||
|
||||
runtime.Breakpoint()
|
||||
call1(one, two)
|
||||
fn2clos(2)
|
||||
strings.LastIndexByte(stringslice[1], 'w')
|
||||
fmt.Println(one, two, zero, callpanic, callstacktrace, stringsJoin, intslice, stringslice, comma, a.VRcvr, a.PRcvr, pa, vable_a, vable_pa, pable_pa, fn2clos, fn2glob, fn2valmeth, fn2ptrmeth, fn2nil, ga, escapeArg, a2, square, intcallpanic, onetwothree, curriedAdd, getAStruct, getAStructPtr, getVRcvrableFromAStruct, getPRcvrableFromAStructPtr, getVRcvrableFromAStructPtr, pa2, noreturncall, str)
|
||||
d.Method()
|
||||
d.Base.Method()
|
||||
fmt.Println(one, two, zero, callpanic, callstacktrace, stringsJoin, intslice, stringslice, comma, a.VRcvr, a.PRcvr, pa, vable_a, vable_pa, pable_pa, fn2clos, fn2glob, fn2valmeth, fn2ptrmeth, fn2nil, ga, escapeArg, a2, square, intcallpanic, onetwothree, curriedAdd, getAStruct, getAStructPtr, getVRcvrableFromAStruct, getPRcvrableFromAStructPtr, getVRcvrableFromAStructPtr, pa2, noreturncall, str, d)
|
||||
}
|
||||
|
||||
@ -1847,7 +1847,32 @@ func (v *Variable) findMethod(mname string) (*Variable, error) {
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
return v.tryFindMethodInEmbeddedFields(mname)
|
||||
}
|
||||
|
||||
func (v *Variable) tryFindMethodInEmbeddedFields(mname string) (*Variable, error) {
|
||||
structVar := v.maybeDereference()
|
||||
structVar.Name = v.Name
|
||||
if structVar.Unreadable != nil {
|
||||
return structVar, nil
|
||||
}
|
||||
switch t := structVar.RealType.(type) {
|
||||
case *godwarf.StructType:
|
||||
for _, field := range t.Field {
|
||||
if field.Embedded {
|
||||
// Recursively check for promoted fields on the embedded field
|
||||
embeddedVar, err := structVar.toField(field)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if embeddedMethod, err := embeddedVar.findMethod(mname); err != nil {
|
||||
return nil, err
|
||||
} else if embeddedMethod != nil {
|
||||
return embeddedMethod, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
||||
@ -1181,6 +1181,8 @@ func TestCallFunction(t *testing.T) {
|
||||
{`strings.Join(stringslice, ",")`, []string{`:string:"one,two,three"`}, nil},
|
||||
{`strings.LastIndexByte(stringslice[1], 'w')`, []string{":int:1"}, nil},
|
||||
{`strings.LastIndexByte(stringslice[1], 'o')`, []string{":int:2"}, nil},
|
||||
{`d.Base.Method()`, []string{ `:int:4` }, nil },
|
||||
{`d.Method()`, []string{ `:int:4` }, nil },
|
||||
}
|
||||
|
||||
var testcases113 = []testCaseCallFunction{
|
||||
|
||||
Reference in New Issue
Block a user