mirror of
https://github.com/go-delve/delve.git
synced 2025-10-29 01:27:16 +08:00
proc: allow "package/path".varname syntax
If the application being debugged imports two packages with the same name (but different paths) there was no way to disambiguate the two, since the character '/' can not appear inside a go identifier. By allowing users to use a string literal as the package name a package path can be specified.
This commit is contained in:
@ -81,3 +81,12 @@ To use a field of a struct contained inside an interface variable use a type ass
|
||||
(dlv) p iface1.(*main.astruct).B
|
||||
2
|
||||
```
|
||||
|
||||
# Specifying package paths
|
||||
|
||||
Packages with the same name can be disambiguated by using the full package path. For example, if the application imports two packages, `some/package` and `some/other/package`, both defining a variable `A`, the two variables can be accessed using this syntax:
|
||||
|
||||
```
|
||||
(dlv) p "some/package".A
|
||||
(dlv) p "some/other/package".A
|
||||
```
|
||||
|
||||
@ -51,5 +51,5 @@ func main() {
|
||||
m := t.Method(0)
|
||||
fmt.Println(m.Type.In(0))
|
||||
fmt.Println(m.Type.String())
|
||||
fmt.Println(badexpr, req, amap, amap2, dir0someType, dir1someType, amap3, anarray, achan, aslice, afunc, astruct, astruct2, iface2iface, iface3, pkg.SomeVar)
|
||||
fmt.Println(badexpr, req, amap, amap2, dir0someType, dir1someType, amap3, anarray, achan, aslice, afunc, astruct, astruct2, iface2iface, iface3, pkg.SomeVar, pkg.A, dir1pkg.A)
|
||||
}
|
||||
|
||||
2
_fixtures/vendor/dir0/pkg/main.go
vendored
2
_fixtures/vendor/dir0/pkg/main.go
vendored
@ -1,5 +1,7 @@
|
||||
package pkg
|
||||
|
||||
var A = 0
|
||||
|
||||
type SomeType struct {
|
||||
X float64
|
||||
}
|
||||
|
||||
2
_fixtures/vendor/dir1/pkg/main.go
vendored
2
_fixtures/vendor/dir1/pkg/main.go
vendored
@ -1,5 +1,7 @@
|
||||
package pkg
|
||||
|
||||
var A = 1
|
||||
|
||||
type SomeType struct {
|
||||
X int
|
||||
Y int
|
||||
|
||||
@ -11,6 +11,7 @@ import (
|
||||
"go/printer"
|
||||
"go/token"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
||||
"github.com/derekparker/delve/pkg/dwarf/godwarf"
|
||||
"github.com/derekparker/delve/pkg/dwarf/reader"
|
||||
@ -187,6 +188,15 @@ func (scope *EvalScope) evalAST(t ast.Expr) (*Variable, error) {
|
||||
return v, nil
|
||||
}
|
||||
}
|
||||
// try to accept "package/path".varname syntax for package variables
|
||||
if maybePkg, ok := node.X.(*ast.BasicLit); ok && maybePkg.Kind == token.STRING {
|
||||
pkgpath, err := strconv.Unquote(maybePkg.Value)
|
||||
if err == nil {
|
||||
if v, err := scope.findGlobal(pkgpath + "." + node.Sel.Name); err == nil {
|
||||
return v, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
// if it's not a package variable then it must be a struct member access
|
||||
return scope.evalStructSelector(node)
|
||||
|
||||
|
||||
@ -920,6 +920,9 @@ func TestPackageRenames(t *testing.T) {
|
||||
{"astruct", true, `interface {}(*struct { A github.com/derekparker/delve/_fixtures/vendor/dir1/pkg.SomeType; B github.com/derekparker/delve/_fixtures/vendor/dir0/pkg.SomeType }) *{A: github.com/derekparker/delve/_fixtures/vendor/dir1/pkg.SomeType {X: 1, Y: 2}, B: github.com/derekparker/delve/_fixtures/vendor/dir0/pkg.SomeType {X: 3}}`, "", "interface {}", nil},
|
||||
{"astruct2", true, `interface {}(*struct { github.com/derekparker/delve/_fixtures/vendor/dir1/pkg.SomeType; X int }) *{SomeType: github.com/derekparker/delve/_fixtures/vendor/dir1/pkg.SomeType {X: 1, Y: 2}, X: 10}`, "", "interface {}", nil},
|
||||
{"iface2iface", true, `interface {}(*interface { AMethod(int) int; AnotherMethod(int) int }) **github.com/derekparker/delve/_fixtures/vendor/dir0/pkg.SomeType {X: 4}`, "", "interface {}", nil},
|
||||
|
||||
{`"dir0/pkg".A`, false, "0", "", "int", nil},
|
||||
{`"dir1/pkg".A`, false, "1", "", "int", nil},
|
||||
}
|
||||
|
||||
ver, _ := goversion.Parse(runtime.Version())
|
||||
|
||||
Reference in New Issue
Block a user