Skip to content

Commit

Permalink
gopls/internal/lsp/source/typerefs: reexpress tests wrt ExternalRefs
Browse files Browse the repository at this point in the history
This change introduces a new API function that (in effect) computes
the path through intra-package edges to imported symbols, and
re-expresses all the tests in terms of it.

A follow-up change will implement SCC-based graph optimizations
within the Refs operation, but this bridge allows us to keep
the tests unchanged during that transition, for increased confidence.

Change-Id: I6735bee2ae8b9b940514bfd7145ad69cd442f117
Reviewed-on: https://go-review.googlesource.com/c/tools/+/481783
Run-TryBot: Alan Donovan <adonovan@google.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
  • Loading branch information
adonovan authored and gopherbot committed Apr 6, 2023
1 parent c5f768a commit 5ef3193
Show file tree
Hide file tree
Showing 2 changed files with 209 additions and 113 deletions.
34 changes: 34 additions & 0 deletions gopls/internal/lsp/source/typerefs/pkgrefs.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,40 @@ func (g *PackageGraph) buildPackage(ctx context.Context, id source.PackageID) (*
return p, nil
}

// ExternalRefs returns a new map whose keys are the exported symbols
// of the package (of the specified id, pkgIndex, and refs). The
// corresponding value of each key is the set of exported symbols
// indirectly referenced by it.
//
// TODO(adonovan): simplify the API once the SCC-based optimization lands.
func ExternalRefs(pkgIndex *PackageIndex, id source.PackageID, refs map[string][]Ref) map[string]map[Ref]bool {
// (This intrapackage recursion will go away in a follow-up CL.)
var visit func(name string, res map[Ref]bool, seen map[string]bool)
visit = func(name string, res map[Ref]bool, seen map[string]bool) {
if !seen[name] {
seen[name] = true
for _, ref := range refs[name] {
if pkgIndex.id(ref.pkg) == id {
visit(ref.name, res, seen) // intrapackage recursion
} else {
res[ref] = true // cross-package ref
}
}
}
}

results := make(map[string]map[Ref]bool)
for name := range refs {
if token.IsExported(name) {
res := make(map[Ref]bool)
seen := make(map[string]bool)
visit(name, res, seen)
results[name] = res
}
}
return results
}

// reachableByName computes the set of packages that are reachable through
// references, starting with the declaration for name in package p.
func (g *PackageGraph) reachableByName(ctx context.Context, p *Package, name string, set *PackageSet, seen map[string]bool) error {
Expand Down
Loading

0 comments on commit 5ef3193

Please sign in to comment.