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 <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
diff --git a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.go
index 5d36f5e..6852c74 100644
--- a/gopls/internal/lsp/cache/check.go
+++ b/gopls/internal/lsp/cache/check.go
@@ -93,10 +93,30 @@
 // the type-checking operation.
 func (s *snapshot) TypeCheck(ctx context.Context, ids ...PackageID) ([]source.Package, error) {
 	pkgs := make([]source.Package, len(ids))
-	post := func(i int, pkg *Package) {
-		pkgs[i] = pkg
+
+	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)
+		}
 	}
-	return pkgs, s.forEachPackage(ctx, ids, nil, post)
+
+	post := func(i int, pkg *Package) {
+		pkgs[indexes[i]] = pkg
+	}
+	return pkgs, s.forEachPackage(ctx, needIDs, nil, post)
 }
 
 // getImportGraph returns a shared import graph use for this snapshot, or nil.