gopls/internal/lsp/source: document {All,Workspace}Metadata

This change is the residue of a failed attempt to reduce the scope
of the Implementations query (and others) based on a misunderstanding.
It merely improves the documentation around these two concepts.
What is the German word for a lengthy effort that ends in
nothing more than a small amount of wistful documentation?

Also, return errors correctly in InlayHint, which I touched along
the way.

Change-Id: I5023d0abffed8d0d9cfd8a18668ba859e8fabbc2
Reviewed-on: https://go-review.googlesource.com/c/tools/+/493625
Run-TryBot: Alan Donovan <adonovan@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
diff --git a/gopls/internal/lsp/mod/inlayhint.go b/gopls/internal/lsp/mod/inlayhint.go
index e494cc7..4f08dd2 100644
--- a/gopls/internal/lsp/mod/inlayhint.go
+++ b/gopls/internal/lsp/mod/inlayhint.go
@@ -18,46 +18,46 @@
 	if err != nil {
 		return nil, err
 	}
-	return unexpectedVersion(ctx, snapshot, pm), nil
-}
 
-// Compare the version of the module used in the snapshot's metadata with the
-// version requested by the module, in both cases, taking replaces into account.
-// Produce an InlayHint when the version is the module is not the one usedd.
-func unexpectedVersion(ctx context.Context, snapshot source.Snapshot, pm *source.ParsedModule) []protocol.InlayHint {
-	var ans []protocol.InlayHint
-	if pm.File == nil {
-		return nil
-	}
+	// Compare the version of the module used in the snapshot's metadata with the
+	// version requested by the module, in both cases, taking replaces into account.
+	// Produce an InlayHint when the version is the module is not the one used.
+
 	replaces := make(map[string]*modfile.Replace)
-	requires := make(map[string]*modfile.Require)
 	for _, x := range pm.File.Replace {
 		replaces[x.Old.Path] = x
 	}
+
+	requires := make(map[string]*modfile.Require)
 	for _, x := range pm.File.Require {
 		requires[x.Mod.Path] = x
 	}
-	am, _ := snapshot.AllMetadata(ctx)
+
+	am, err := snapshot.AllMetadata(ctx)
+	if err != nil {
+		return nil, err
+	}
+
+	var ans []protocol.InlayHint
 	seen := make(map[string]bool)
 	for _, meta := range am {
-		if meta == nil || meta.Module == nil || seen[meta.Module.Path] {
+		if meta.Module == nil || seen[meta.Module.Path] {
 			continue
 		}
 		seen[meta.Module.Path] = true
-		metaMod := meta.Module
-		metaVersion := metaMod.Version
-		if metaMod.Replace != nil {
-			metaVersion = metaMod.Replace.Version
+		metaVersion := meta.Module.Version
+		if meta.Module.Replace != nil {
+			metaVersion = meta.Module.Replace.Version
 		}
 		// These versions can be blank, as in gopls/go.mod's local replace
-		if oldrepl, ok := replaces[metaMod.Path]; ok && oldrepl.New.Version != metaVersion {
+		if oldrepl, ok := replaces[meta.Module.Path]; ok && oldrepl.New.Version != metaVersion {
 			ih := genHint(oldrepl.Syntax, oldrepl.New.Version, metaVersion, pm.Mapper)
 			if ih != nil {
 				ans = append(ans, *ih)
 			}
-		} else if oldreq, ok := requires[metaMod.Path]; ok && oldreq.Mod.Version != metaVersion {
+		} else if oldreq, ok := requires[meta.Module.Path]; ok && oldreq.Mod.Version != metaVersion {
 			// maybe it was replaced:
-			if _, ok := replaces[metaMod.Path]; ok {
+			if _, ok := replaces[meta.Module.Path]; ok {
 				continue
 			}
 			ih := genHint(oldreq.Syntax, oldreq.Mod.Version, metaVersion, pm.Mapper)
@@ -66,7 +66,7 @@
 			}
 		}
 	}
-	return ans
+	return ans, nil
 }
 
 func genHint(mline *modfile.Line, oldVersion, newVersion string, m *protocol.Mapper) *protocol.InlayHint {
diff --git a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/lsp/source/completion/completion.go
index e6e53e0..f92790f 100644
--- a/gopls/internal/lsp/source/completion/completion.go
+++ b/gopls/internal/lsp/source/completion/completion.go
@@ -1174,7 +1174,8 @@
 	// not assume global Pos/Object realms and then use export
 	// data instead of the quick parse approach taken here.
 
-	// First, we search among packages in the workspace.
+	// First, we search among packages in the forward transitive
+	// closure of the workspace.
 	// We'll use a fast parse to extract package members
 	// from those that match the name/path criterion.
 	all, err := c.snapshot.AllMetadata(ctx)
@@ -1610,7 +1611,7 @@
 
 	count := 0
 
-	// Search packages across the entire workspace.
+	// Search the forward transitive closure of the workspace.
 	all, err := c.snapshot.AllMetadata(ctx)
 	if err != nil {
 		return err
diff --git a/gopls/internal/lsp/source/implementation.go b/gopls/internal/lsp/source/implementation.go
index bcb8b94..00559cf 100644
--- a/gopls/internal/lsp/source/implementation.go
+++ b/gopls/internal/lsp/source/implementation.go
@@ -152,8 +152,9 @@
 		return nil, nil
 	}
 
-	// The global search needs to look at every package in the workspace;
-	// see package ./methodsets.
+	// The global search needs to look at every package in the
+	// forward transitive closure of the workspace; see package
+	// ./methodsets.
 	//
 	// For now we do all the type checking before beginning the search.
 	// TODO(adonovan): opt: search in parallel topological order
diff --git a/gopls/internal/lsp/source/known_packages.go b/gopls/internal/lsp/source/known_packages.go
index 4414852..b1c90a9 100644
--- a/gopls/internal/lsp/source/known_packages.go
+++ b/gopls/internal/lsp/source/known_packages.go
@@ -51,7 +51,7 @@
 		}
 	}
 
-	// Now find candidates among known packages.
+	// Now find candidates among all known packages.
 	knownPkgs, err := snapshot.AllMetadata(ctx)
 	if err != nil {
 		return nil, err
diff --git a/gopls/internal/lsp/source/linkname.go b/gopls/internal/lsp/source/linkname.go
index 961e8f2..84890a6 100644
--- a/gopls/internal/lsp/source/linkname.go
+++ b/gopls/internal/lsp/source/linkname.go
@@ -117,7 +117,7 @@
 func findLinkname(ctx context.Context, snapshot Snapshot, pkgPath PackagePath, name string) (Package, *ParsedGoFile, token.Pos, error) {
 	// Typically the linkname refers to a forward dependency
 	// or a reverse dependency, but in general it may refer
-	// to any package in the workspace.
+	// to any package that is linked with this one.
 	var pkgMeta *Metadata
 	metas, err := snapshot.AllMetadata(ctx)
 	if err != nil {
diff --git a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rename.go
index 55bc95b..60fb48d 100644
--- a/gopls/internal/lsp/source/rename.go
+++ b/gopls/internal/lsp/source/rename.go
@@ -718,8 +718,8 @@
 // directory.
 //
 // It updates package clauses and import paths for the renamed package as well
-// as any other packages affected by the directory renaming among packages
-// described by allMetadata.
+// as any other packages affected by the directory renaming among all packages
+// known to the snapshot.
 func renamePackage(ctx context.Context, s Snapshot, f FileHandle, newName PackageName) (map[span.URI][]diff.Edit, error) {
 	if strings.HasSuffix(string(newName), "_test") {
 		return nil, fmt.Errorf("cannot rename to _test package")
diff --git a/gopls/internal/lsp/source/view.go b/gopls/internal/lsp/source/view.go
index a86874a..d736f3fe 100644
--- a/gopls/internal/lsp/source/view.go
+++ b/gopls/internal/lsp/source/view.go
@@ -175,9 +175,23 @@
 	// WorkspaceMetadata returns a new, unordered slice containing
 	// metadata for all ordinary and test packages (but not
 	// intermediate test variants) in the workspace.
+	//
+	// The workspace is the set of modules typically defined by a
+	// go.work file. It is not transitively closed: for example,
+	// the standard library is not usually part of the workspace
+	// even though every module in the workspace depends on it.
+	//
+	// Operations that must inspect all the dependencies of the
+	// workspace packages should instead use AllMetadata.
 	WorkspaceMetadata(ctx context.Context) ([]*Metadata, error)
 
-	// AllMetadata returns a new unordered array of metadata for all packages in the workspace.
+	// 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
+	// import dependencies.
+	//
+	// It may also contain ad-hoc packages for standalone files.
+	// It includes all test variants.
 	AllMetadata(ctx context.Context) ([]*Metadata, error)
 
 	// Metadata returns the metadata for the specified package,