diff --git a/cmd/guru/serial/serial.go b/cmd/guru/serial/serial.go index 0110c06437..cab51edfa5 100644 --- a/cmd/guru/serial/serial.go +++ b/cmd/guru/serial/serial.go @@ -130,6 +130,8 @@ type What struct { Modes []string `json:"modes"` // query modes enabled for this selection. SrcDir string `json:"srcdir,omitempty"` // $GOROOT src directory containing queried package ImportPath string `json:"importpath,omitempty"` // import path of queried package + Object string `json:"object,omitempty"` // name of identified object, if any + SameIDs []string `json:"sameids,omitempty"` // locations of references to same object } // A PointsToLabel describes a pointer analysis label. diff --git a/cmd/guru/testdata/src/what/main.golden b/cmd/guru/testdata/src/what/main.golden index 56b97dde51..ac8568fe1b 100644 --- a/cmd/guru/testdata/src/what/main.golden +++ b/cmd/guru/testdata/src/what/main.golden @@ -36,4 +36,6 @@ source file modes: [callers callstack definition describe freevars implements peers pointsto referrers] srcdir: testdata/src import path: what +ch +ch diff --git a/cmd/guru/what.go b/cmd/guru/what.go index ca161350ca..196826659d 100644 --- a/cmd/guru/what.go +++ b/cmd/guru/what.go @@ -110,11 +110,32 @@ func what(q *Query) error { } sort.Strings(modes) + // Find the object referred to by the selection (if it's an + // identifier) and report the position of each identifier + // that refers to the same object. + // + // This may return spurious matches (e.g. struct fields) because + // it uses the best-effort name resolution done by go/parser. + var sameids []token.Pos + var object string + if id, ok := qpos.path[0].(*ast.Ident); ok && id.Obj != nil { + object = id.Obj.Name + decl := qpos.path[len(qpos.path)-1] + ast.Inspect(decl, func(n ast.Node) bool { + if n, ok := n.(*ast.Ident); ok && n.Obj == id.Obj { + sameids = append(sameids, n.Pos()) + } + return true + }) + } + q.result = &whatResult{ path: qpos.path, srcdir: srcdir, importPath: importPath, modes: modes, + object: object, + sameids: sameids, } return nil } @@ -186,6 +207,8 @@ type whatResult struct { modes []string srcdir string importPath string + object string + sameids []token.Pos } func (r *whatResult) display(printf printfFunc) { @@ -195,6 +218,9 @@ func (r *whatResult) display(printf printfFunc) { printf(nil, "modes: %s", r.modes) printf(nil, "srcdir: %s", r.srcdir) printf(nil, "import path: %s", r.importPath) + for _, pos := range r.sameids { + printf(pos, "%s", r.object) + } } func (r *whatResult) toSerial(res *serial.Result, fset *token.FileSet) { @@ -206,10 +232,18 @@ func (r *whatResult) toSerial(res *serial.Result, fset *token.FileSet) { End: fset.Position(n.End()).Offset, }) } + + var sameids []string + for _, pos := range r.sameids { + sameids = append(sameids, fset.Position(pos).String()) + } + res.What = &serial.What{ Modes: r.modes, SrcDir: r.srcdir, ImportPath: r.importPath, Enclosing: enclosing, + Object: r.object, + SameIDs: sameids, } }