internal/lsp: don't refresh metadata when context canceled

We err on the side of refreshing package metadata if something goes
wrong getting a file's AST, but we don't want to refresh in the case
of context cancellation. Now we check for that error explicitly.

In particular, I noticed that completions would stop working when
typing quickly. Refreshing the metadata triggers "go list" calls which
can take a long time in certain cases.

Change-Id: I1b0c580e5541b1536a69ccaef241d7e8c5720d60
GitHub-Last-Rev: 6a82bfb586f93ef5e8e5996b11e06ffc7808f529
GitHub-Pull-Request: golang/tools#130
Reviewed-on: https://go-review.googlesource.com/c/tools/+/184977
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/internal/lsp/cache/load.go b/internal/lsp/cache/load.go
index 84e9f7e..ed483b1 100644
--- a/internal/lsp/cache/load.go
+++ b/internal/lsp/cache/load.go
@@ -152,17 +152,22 @@
 			}
 		}
 
-		defer f.mu.Unlock()
+		f.mu.Unlock()
 	}()
 
 	if len(f.meta) == 0 || len(f.missingImports) > 0 {
 		return true
 	}
+
 	// Get file content in case we don't already have it.
-	parsed, _ := v.session.cache.ParseGoHandle(f.Handle(ctx), source.ParseHeader).Parse(ctx)
+	parsed, err := v.session.cache.ParseGoHandle(f.Handle(ctx), source.ParseHeader).Parse(ctx)
+	if err == context.Canceled {
+		return false
+	}
 	if parsed == nil {
 		return true
 	}
+
 	// Check if the package's name has changed, by checking if this is a filename
 	// we already know about, and if so, check if its package name has changed.
 	for _, m := range f.meta {
@@ -174,15 +179,18 @@
 			}
 		}
 	}
+
 	// If the package's imports have changed, re-run `go list`.
 	if len(f.imports) != len(parsed.Imports) {
 		return true
 	}
+
 	for i, importSpec := range f.imports {
 		if importSpec.Path.Value != parsed.Imports[i].Path.Value {
 			return true
 		}
 	}
+
 	return false
 }