From 5e47a3db26e485cc95099a43408f41c65daebb6a Mon Sep 17 00:00:00 2001 From: Rob Findley Date: Tue, 26 Nov 2024 18:21:36 +0000 Subject: [PATCH] gopls/internal/cache: move Snapshot.Symbols to symbols.go Pure code movement; no behavior change. Change-Id: I7ef073d58355f9ac8853cc0c1e33e0af3f9a391f Reviewed-on: https://go-review.googlesource.com/c/tools/+/634795 Reviewed-by: Peter Weinberger LUCI-TryBot-Result: Go LUCI --- gopls/internal/cache/snapshot.go | 62 ------------------------------- gopls/internal/cache/symbols.go | 64 ++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 62 deletions(-) diff --git a/gopls/internal/cache/snapshot.go b/gopls/internal/cache/snapshot.go index 46b0a6a1b5c..50fb01ce532 100644 --- a/gopls/internal/cache/snapshot.go +++ b/gopls/internal/cache/snapshot.go @@ -17,14 +17,12 @@ import ( "path" "path/filepath" "regexp" - "runtime" "slices" "sort" "strconv" "strings" "sync" - "golang.org/x/sync/errgroup" "golang.org/x/tools/go/types/objectpath" "golang.org/x/tools/gopls/internal/cache/metadata" "golang.org/x/tools/gopls/internal/cache/methodsets" @@ -961,66 +959,6 @@ func (s *Snapshot) isWorkspacePackage(id PackageID) bool { return ok } -// Symbols extracts and returns symbol information for every file contained in -// a loaded package. It awaits snapshot loading. -// -// If workspaceOnly is set, this only includes symbols from files in a -// workspace package. Otherwise, it returns symbols from all loaded packages. -// -// TODO(rfindley): move to symbols.go. -func (s *Snapshot) Symbols(ctx context.Context, workspaceOnly bool) (map[protocol.DocumentURI][]Symbol, error) { - var ( - meta []*metadata.Package - err error - ) - if workspaceOnly { - meta, err = s.WorkspaceMetadata(ctx) - } else { - meta, err = s.AllMetadata(ctx) - } - if err != nil { - return nil, fmt.Errorf("loading metadata: %v", err) - } - - goFiles := make(map[protocol.DocumentURI]struct{}) - for _, mp := range meta { - for _, uri := range mp.GoFiles { - goFiles[uri] = struct{}{} - } - for _, uri := range mp.CompiledGoFiles { - goFiles[uri] = struct{}{} - } - } - - // Symbolize them in parallel. - var ( - group errgroup.Group - nprocs = 2 * runtime.GOMAXPROCS(-1) // symbolize is a mix of I/O and CPU - resultMu sync.Mutex - result = make(map[protocol.DocumentURI][]Symbol) - ) - group.SetLimit(nprocs) - for uri := range goFiles { - uri := uri - group.Go(func() error { - symbols, err := s.symbolize(ctx, uri) - if err != nil { - return err - } - resultMu.Lock() - result[uri] = symbols - resultMu.Unlock() - return nil - }) - } - // Keep going on errors, but log the first failure. - // Partial results are better than no symbol results. - if err := group.Wait(); err != nil { - event.Error(ctx, "getting snapshot symbols", err) - } - return result, nil -} - // AllMetadata returns a new unordered array of metadata for // all packages known to this snapshot, which includes the // packages of all workspace modules plus their transitive diff --git a/gopls/internal/cache/symbols.go b/gopls/internal/cache/symbols.go index 9954c747798..e409c9cc6aa 100644 --- a/gopls/internal/cache/symbols.go +++ b/gopls/internal/cache/symbols.go @@ -6,15 +6,21 @@ package cache import ( "context" + "fmt" "go/ast" "go/token" "go/types" + "runtime" "strings" + "sync" + "golang.org/x/sync/errgroup" + "golang.org/x/tools/gopls/internal/cache/metadata" "golang.org/x/tools/gopls/internal/cache/parsego" "golang.org/x/tools/gopls/internal/file" "golang.org/x/tools/gopls/internal/protocol" "golang.org/x/tools/gopls/internal/util/astutil" + "golang.org/x/tools/internal/event" ) // Symbol holds a precomputed symbol value. Note: we avoid using the @@ -26,6 +32,64 @@ type Symbol struct { Range protocol.Range } +// Symbols extracts and returns symbol information for every file contained in +// a loaded package. It awaits snapshot loading. +// +// If workspaceOnly is set, this only includes symbols from files in a +// workspace package. Otherwise, it returns symbols from all loaded packages. +func (s *Snapshot) Symbols(ctx context.Context, workspaceOnly bool) (map[protocol.DocumentURI][]Symbol, error) { + var ( + meta []*metadata.Package + err error + ) + if workspaceOnly { + meta, err = s.WorkspaceMetadata(ctx) + } else { + meta, err = s.AllMetadata(ctx) + } + if err != nil { + return nil, fmt.Errorf("loading metadata: %v", err) + } + + goFiles := make(map[protocol.DocumentURI]struct{}) + for _, mp := range meta { + for _, uri := range mp.GoFiles { + goFiles[uri] = struct{}{} + } + for _, uri := range mp.CompiledGoFiles { + goFiles[uri] = struct{}{} + } + } + + // Symbolize them in parallel. + var ( + group errgroup.Group + nprocs = 2 * runtime.GOMAXPROCS(-1) // symbolize is a mix of I/O and CPU + resultMu sync.Mutex + result = make(map[protocol.DocumentURI][]Symbol) + ) + group.SetLimit(nprocs) + for uri := range goFiles { + uri := uri + group.Go(func() error { + symbols, err := s.symbolize(ctx, uri) + if err != nil { + return err + } + resultMu.Lock() + result[uri] = symbols + resultMu.Unlock() + return nil + }) + } + // Keep going on errors, but log the first failure. + // Partial results are better than no symbol results. + if err := group.Wait(); err != nil { + event.Error(ctx, "getting snapshot symbols", err) + } + return result, nil +} + // symbolize returns the result of symbolizing the file identified by uri, using a cache. func (s *Snapshot) symbolize(ctx context.Context, uri protocol.DocumentURI) ([]Symbol, error) {