internal/lsp: fix error handling when getting go.mod codelens

This change has a fix for mod/codelens: check if we get an error from ParseModHandles().Upgrades(). This change also only runs codelens on save.

Change-Id: I6dab7ddf3a08c650e4c670b039b1e99153ec8187
Reviewed-on: https://go-review.googlesource.com/c/tools/+/219478
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
Run-TryBot: Rohan Challa <rohan@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/internal/lsp/cache/snapshot.go b/internal/lsp/cache/snapshot.go
index 897abc2..97febce 100644
--- a/internal/lsp/cache/snapshot.go
+++ b/internal/lsp/cache/snapshot.go
@@ -476,6 +476,14 @@
 	return open
 }
 
+func (s *snapshot) IsSaved(uri span.URI) bool {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+
+	ovl, open := s.files[uri].(*overlay)
+	return !open || ovl.saved
+}
+
 func (s *snapshot) awaitLoaded(ctx context.Context) error {
 	// Do not return results until the snapshot's view has been initialized.
 	s.view.awaitInitialized(ctx)
diff --git a/internal/lsp/mod/code_lens.go b/internal/lsp/mod/code_lens.go
index 3b1daa7..4217f82 100644
--- a/internal/lsp/mod/code_lens.go
+++ b/internal/lsp/mod/code_lens.go
@@ -29,6 +29,9 @@
 		return nil, err
 	}
 	f, m, upgrades, err := pmh.Upgrades(ctx)
+	if err != nil {
+		return nil, err
+	}
 	var codelens []protocol.CodeLens
 	for _, req := range f.Require {
 		dep := req.Mod.Path
diff --git a/internal/lsp/server.go b/internal/lsp/server.go
index 0a719f7..ab1c263 100644
--- a/internal/lsp/server.go
+++ b/internal/lsp/server.go
@@ -75,8 +75,10 @@
 	if err != nil {
 		return nil, err
 	}
-	snapshot := view.Snapshot()
-	fh, err := snapshot.GetFile(uri)
+	if !view.Snapshot().IsSaved(uri) {
+		return nil, nil
+	}
+	fh, err := view.Snapshot().GetFile(uri)
 	if err != nil {
 		return nil, err
 	}
@@ -84,7 +86,7 @@
 	case source.Go:
 		return nil, nil
 	case source.Mod:
-		return mod.CodeLens(ctx, snapshot, uri)
+		return mod.CodeLens(ctx, view.Snapshot(), uri)
 	}
 	return nil, nil
 }
diff --git a/internal/lsp/source/view.go b/internal/lsp/source/view.go
index b7053f9..7e824e3 100644
--- a/internal/lsp/source/view.go
+++ b/internal/lsp/source/view.go
@@ -33,10 +33,12 @@
 	// if it is not already part of the view.
 	GetFile(uri span.URI) (FileHandle, error)
 
-	// IsOpen returns whether the editor currently has a file open,
-	// and if its contents are saved on disk or not.
+	// IsOpen returns whether the editor currently has a file open.
 	IsOpen(uri span.URI) bool
 
+	// IsSaved returns whether the contents are saved on disk or not.
+	IsSaved(uri span.URI) bool
+
 	// Analyze runs the analyses for the given package at this snapshot.
 	Analyze(ctx context.Context, id string, analyzers []*analysis.Analyzer) ([]*Error, error)