gopls/internal/lsp/cache: a new analysis driver

This change is a new implementation of gopls' analysis driver that
supports "facts" (separate analysis across packages), and serializes
the results of each unit of analysis in a global, persistent,
file-based cache of bounded size with LRU eviction (filecache).

Dependency analysis is based on hashes of only material inputs to each
step: source files, and the types and facts of direct dependencies.
Therefore changes that do not affect these (e.g. the insertion of a
debugging print statement into a function body) will usually not
invalidate most of the graph.

Fact serialization is shared with unitchecker, though perhaps there
are gains to be made by specializing it in future.

This change uses the new API for shallow export data, in which only
the types for a single package are emitted, not all the indirectly
reachable types. This makes the size of the export data for each
package roughly constant, but requires that export data for all
transitive dependencies be available to the type checker. So, the
analysis summary holds a map of all necessary export data as a union
across dependencies. (It's actually somewhat fewer than all transitive
deps because we record the set of packages referenced during type
checking and use that to prune the set.)

Change-Id: I969ce09c31e2349f98ac7dc4554bf39f93a751fe
Reviewed-on: https://go-review.googlesource.com/c/tools/+/443099
Reviewed-by: Tim King <taking@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Alan Donovan <adonovan@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
diff --git a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snapshot.go
index 1818d0e..ea57d57 100644
--- a/gopls/internal/lsp/cache/snapshot.go
+++ b/gopls/internal/lsp/cache/snapshot.go
@@ -109,9 +109,10 @@
 	// It may be invalidated when metadata changes or a new file is opened or closed.
 	isActivePackageCache isActivePackageCacheMap
 
-	// actions maps an actionKey to the handle for the future
-	// result of execution an analysis pass on a package.
-	actions *persistent.Map // from actionKey to *actionHandle
+	// analyses maps an analysisKey (which identifies a package
+	// and a set of analyzers) to the handle for the future result
+	// of loading the package and analyzing it.
+	analyses *persistent.Map // from analysisKey to analysisHandle
 
 	// workspacePackages contains the workspace's packages, which are loaded
 	// when the view is created.
@@ -222,7 +223,7 @@
 
 	s.packages.Destroy()
 	s.isActivePackageCache.Destroy()
-	s.actions.Destroy()
+	s.analyses.Destroy()
 	s.files.Destroy()
 	s.parsedGoFiles.Destroy()
 	s.parseKeysByURI.Destroy()
@@ -835,12 +836,6 @@
 	return rdeps, nil
 }
 
-func (s *snapshot) getImportedBy(id PackageID) []PackageID {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	return s.meta.importedBy[id]
-}
-
 func (s *snapshot) workspaceMetadata() (meta []*source.Metadata) {
 	s.mu.Lock()
 	defer s.mu.Unlock()
@@ -1667,7 +1662,7 @@
 		initializedErr:       s.initializedErr,
 		packages:             s.packages.Clone(),
 		isActivePackageCache: s.isActivePackageCache.Clone(),
-		actions:              s.actions.Clone(),
+		analyses:             s.analyses.Clone(),
 		files:                s.files.Clone(),
 		parsedGoFiles:        s.parsedGoFiles.Clone(),
 		parseKeysByURI:       s.parseKeysByURI.Clone(),
@@ -1882,15 +1877,15 @@
 	}
 
 	// Delete invalidated analysis actions.
-	var actionsToDelete []actionKey
-	result.actions.Range(func(k, _ interface{}) {
-		key := k.(actionKey)
+	var actionsToDelete []analysisKey
+	result.analyses.Range(func(k, _ interface{}) {
+		key := k.(analysisKey)
 		if _, ok := idsToInvalidate[key.pkgid]; ok {
 			actionsToDelete = append(actionsToDelete, key)
 		}
 	})
 	for _, key := range actionsToDelete {
-		result.actions.Delete(key)
+		result.analyses.Delete(key)
 	}
 
 	// If a file has been deleted, we must delete metadata for all packages