From e8cdaf46de4db18885846748405a3c397c4bd1d2 Mon Sep 17 00:00:00 2001 From: Rob Findley Date: Tue, 25 Jul 2023 22:42:44 -0400 Subject: [PATCH] gopls/internal/lsp/cache: fast-path for type-checking active packages Partially revert CL 512636, putting back the fast path to fetch the active package. This fixes a "regression" in certain fast benchmarks, such as Definition, Hover, or References in a local package. The numbers are still small either way, but may matter in very large repos. Change-Id: Id850eaa7a2599d9fb6ad042e762b59b3d5220cf1 Reviewed-on: https://go-review.googlesource.com/c/tools/+/513101 Run-TryBot: Robert Findley gopls-CI: kokoro TryBot-Result: Gopher Robot Reviewed-by: Alan Donovan --- gopls/internal/lsp/cache/check.go | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.go index 5d36f5e2817..6852c741f08 100644 --- a/gopls/internal/lsp/cache/check.go +++ b/gopls/internal/lsp/cache/check.go @@ -93,10 +93,30 @@ type pkgOrErr struct { // the type-checking operation. func (s *snapshot) TypeCheck(ctx context.Context, ids ...PackageID) ([]source.Package, error) { pkgs := make([]source.Package, len(ids)) + + var ( + needIDs []PackageID // ids to type-check + indexes []int // original index of requested ids + ) + + // Check for existing active packages, as any package will do. + // + // This is also done inside forEachPackage, but doing it here avoids + // unnecessary set up for type checking (e.g. assembling the package handle + // graph). + for i, id := range ids { + if pkg := s.getActivePackage(id); pkg != nil { + pkgs[i] = pkg + } else { + needIDs = append(needIDs, id) + indexes = append(indexes, i) + } + } + post := func(i int, pkg *Package) { - pkgs[i] = pkg + pkgs[indexes[i]] = pkg } - return pkgs, s.forEachPackage(ctx, ids, nil, post) + return pkgs, s.forEachPackage(ctx, needIDs, nil, post) } // getImportGraph returns a shared import graph use for this snapshot, or nil.