mirror of
https://github.com/go-delve/delve.git
synced 2025-10-29 09:46:56 +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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Base struct{
|
||||||
|
y int
|
||||||
|
}
|
||||||
|
|
||||||
|
type Derived struct {
|
||||||
|
x int
|
||||||
|
Base
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Base) Method() int {
|
||||||
|
return b.y
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
one, two := 1, 2
|
one, two := 1, 2
|
||||||
intslice := []int{1, 2, 3}
|
intslice := []int{1, 2, 3}
|
||||||
@ -142,9 +155,13 @@ func main() {
|
|||||||
fn2ptrmeth := pa.PRcvr
|
fn2ptrmeth := pa.PRcvr
|
||||||
var fn2nil func()
|
var fn2nil func()
|
||||||
|
|
||||||
|
d := &Derived{3, Base{4}}
|
||||||
|
|
||||||
runtime.Breakpoint()
|
runtime.Breakpoint()
|
||||||
call1(one, two)
|
call1(one, two)
|
||||||
fn2clos(2)
|
fn2clos(2)
|
||||||
strings.LastIndexByte(stringslice[1], 'w')
|
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 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
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1181,6 +1181,8 @@ func TestCallFunction(t *testing.T) {
|
|||||||
{`strings.Join(stringslice, ",")`, []string{`:string:"one,two,three"`}, nil},
|
{`strings.Join(stringslice, ",")`, []string{`:string:"one,two,three"`}, nil},
|
||||||
{`strings.LastIndexByte(stringslice[1], 'w')`, []string{":int:1"}, nil},
|
{`strings.LastIndexByte(stringslice[1], 'w')`, []string{":int:1"}, nil},
|
||||||
{`strings.LastIndexByte(stringslice[1], 'o')`, []string{":int:2"}, 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{
|
var testcases113 = []testCaseCallFunction{
|
||||||
|
|||||||
Reference in New Issue
Block a user