From d255de4fdb38f8f5dbaf12b83013784a30f97a55 Mon Sep 17 00:00:00 2001 From: Muir Manders Date: Tue, 9 Jul 2019 17:09:04 +0000 Subject: [PATCH] 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 Run-TryBot: Rebecca Stambler TryBot-Result: Gobot Gobot --- internal/lsp/cache/load.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/internal/lsp/cache/load.go b/internal/lsp/cache/load.go index 84e9f7ee..ed483b1e 100644 --- a/internal/lsp/cache/load.go +++ b/internal/lsp/cache/load.go @@ -152,17 +152,22 @@ func (v *view) runGopackages(ctx context.Context, f *goFile) (result bool) { } } - 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 @@ func (v *view) runGopackages(ctx context.Context, f *goFile) (result bool) { } } } + // 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 }