1
0
mirror of https://github.com/golang/go synced 2024-11-18 16:44:43 -07:00

internal/lsp: avoid invalid state due to context cancelation

In shouldRunGopackages we would reset a goFile's metadata and pkgs in
advance of re-running go/packages. However, if we did not end up
running go/packages for whatever reason (read: we got canceled), the
goFile gets stuck in the unfortunate state of not belonging to any
packages because "pkgs" is empty. I think this leads to "no
CheckPackageHandle" errors, at least in relation to GetCachedPackage()
calls.

Fix by deferring the reset of goFile's metadata and pkgs until after
the go/packages call has succeeded.

Change-Id: I95aace85c026e1232b42cadee9e7772951c817d0
Reviewed-on: https://go-review.googlesource.com/c/tools/+/193601
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
This commit is contained in:
Muir Manders 2019-09-05 12:56:05 -07:00 committed by Rebecca Stambler
parent 4f238b926e
commit 59228eac51

View File

@ -122,6 +122,17 @@ func (v *view) checkMetadata(ctx context.Context, f *goFile, fh source.FileHandl
// Track missing imports as we look at the package's errors.
missingImports := make(map[packagePath]struct{})
// Clear metadata since we are re-running go/packages.
// Reset the file's metadata and type information if we are re-running `go list`.
f.mu.Lock()
for k := range f.meta {
delete(f.meta, k)
}
for k := range f.pkgs {
delete(f.pkgs, k)
}
f.mu.Unlock()
log.Print(ctx, "go/packages.Load", tag.Of("packages", len(pkgs)))
for _, pkg := range pkgs {
log.Print(ctx, "go/packages.Load", tag.Of("package", pkg.PkgPath), tag.Of("files", pkg.CompiledGoFiles))
@ -179,19 +190,6 @@ func sameSet(x, y map[packagePath]struct{}) bool {
// determine if they have changed.
// It assumes that the caller holds the lock on the f.mu lock.
func (v *view) shouldRunGopackages(ctx context.Context, f *goFile, fh source.FileHandle) (result bool) {
defer func() {
// Clear metadata if we are intending to re-run go/packages.
if result {
// Reset the file's metadata and type information if we are re-running `go list`.
for k := range f.meta {
delete(f.meta, k)
}
for k := range f.pkgs {
delete(f.pkgs, k)
}
}
}()
if len(f.meta) == 0 || len(f.missingImports) > 0 {
return true
}