From c1f4e2c6dc737270fb7df7336ef12da407e4a157 Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Mon, 23 Apr 2018 12:57:10 -0700 Subject: [PATCH] cmd/guru: emit initial referrers result earlier This simplifies and unifies the code. It also improves the output: Now the initial result is referred to from the perspective of the query site, rather than from the perspective of the package containing the query object, which seems more natural. This work supported by Sourcegraph. Change-Id: Ie7a77d39dd6568334e72d894dc66d35494ed4ac4 Reviewed-on: https://go-review.googlesource.com/108936 Reviewed-by: Alan Donovan --- cmd/guru/referrers.go | 33 +++++++++------------ cmd/guru/testdata/src/referrers/main.golden | 2 +- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/cmd/guru/referrers.go b/cmd/guru/referrers.go index c4ae5104..cf9b022e 100644 --- a/cmd/guru/referrers.go +++ b/cmd/guru/referrers.go @@ -80,26 +80,25 @@ func referrers(q *Query) error { return fmt.Errorf("references to predeclared %q are everywhere!", obj.Name()) } - // For a globally accessible object defined in package P, we - // must load packages that depend on P. Specifically, for a - // package-level object, we need load only direct importers - // of P, but for a field or method, we must load - // any package that transitively imports P. - global, pkglevel := classify(obj) - if global && !pkglevel { - // We'll use the the object's position to identify it in the larger program. - objposn := fset.Position(obj.Pos()) - defpkg := obj.Pkg().Path() // defining package - return globalReferrers(q, qpos.info.Pkg.Path(), defpkg, objposn) - } - q.Output(fset, &referrersInitialResult{ qinfo: qpos.info, obj: obj, }) - if global { - return globalReferrersPkgLevel(q, obj, fset) + // For a globally accessible object defined in package P, we + // must load packages that depend on P. Specifically, for a + // package-level object, we need load only direct importers + // of P, but for a field or method, we must load + // any package that transitively imports P. + + if global, pkglevel := classify(obj); global { + if pkglevel { + return globalReferrersPkgLevel(q, obj, fset) + } + // We'll use the the object's position to identify it in the larger program. + objposn := fset.Position(obj.Pos()) + defpkg := obj.Pkg().Path() // defining package + return globalReferrers(q, qpos.info.Pkg.Path(), defpkg, objposn) } outputUses(q, fset, usesOf(obj, qpos.info), obj.Pkg()) @@ -295,10 +294,6 @@ func globalReferrers(q *Query, qpkg, defpkg string, objposn token.Position) erro // Object found. qinfo = info - q.Output(fset, &referrersInitialResult{ - qinfo: qinfo, - obj: qobj, - }) } obj := qobj mu.Unlock() diff --git a/cmd/guru/testdata/src/referrers/main.golden b/cmd/guru/testdata/src/referrers/main.golden index bf56d763..78fea14e 100644 --- a/cmd/guru/testdata/src/referrers/main.golden +++ b/cmd/guru/testdata/src/referrers/main.golden @@ -33,7 +33,7 @@ type _ lib.T var _ lib.Var // @what pkg "lib" -------- @referrers ref-method -------- -references to func (Type).Method(x *int) *int +references to func (lib.Type).Method(x *int) *int _ = (lib.Type).Method // ref from external test package _ = (lib.Type).Method // ref from internal test package _ = v.Method