mirror of
				https://github.com/go-delve/delve.git
				synced 2025-10-31 02:36:18 +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
	 chainhelen
					chainhelen