1
0
mirror of https://github.com/golang/go synced 2024-11-18 14:54:40 -07:00

internal/lsp: fix deadlock in type-checking

Fixes golang/go#33992

Change-Id: I4e27501d1c619887038dfa77cc9cf064c966ff43
Reviewed-on: https://go-review.googlesource.com/c/tools/+/193317
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
This commit is contained in:
Rebecca Stambler 2019-09-04 15:30:42 -04:00
parent 958971f5c2
commit 70bfb60283
4 changed files with 27 additions and 24 deletions

View File

@ -57,6 +57,7 @@ func (f *fileBase) View() source.View {
func (f *fileBase) Handle(ctx context.Context) source.FileHandle {
f.handleMu.Lock()
defer f.handleMu.Unlock()
if f.handle == nil {
f.handle = f.view.Session().GetFile(f.URI())
}

View File

@ -40,14 +40,6 @@ type goFile struct {
meta map[packageID]*metadata
}
type astFile struct {
uri span.URI
file *ast.File
err error // parse errors
ph source.ParseGoHandle
isTrimmed bool
}
func (f *goFile) GetToken(ctx context.Context) (*token.File, error) {
file, err := f.GetAST(ctx, source.ParseFull)
if file == nil {

View File

@ -54,10 +54,22 @@ func (view *view) load(ctx context.Context, f *goFile) (map[packageID]*metadata,
view.mcache.mu.Lock()
defer view.mcache.mu.Unlock()
var toDelete []packageID
f.mu.Lock()
for id, cph := range f.pkgs {
if cph != nil {
toDelete = append(toDelete, id)
}
}
f.mu.Unlock()
// If the AST for this file is trimmed, and we are explicitly type-checking it,
// don't ignore function bodies.
if f.wrongParseMode(ctx, source.ParseFull) {
f.invalidateAST(ctx)
// Remove the package and all of its reverse dependencies from the cache.
for _, id := range toDelete {
f.view.remove(ctx, id, map[packageID]struct{}{})
}
}
// Get the metadata for the file.

View File

@ -365,26 +365,24 @@ func (f *goFile) invalidateContent(ctx context.Context) {
f.view.mcache.mu.Lock()
defer f.view.mcache.mu.Unlock()
var toDelete []packageID
f.mu.Lock()
for id, cph := range f.pkgs {
if cph != nil {
toDelete = append(toDelete, id)
}
}
f.mu.Unlock()
f.handleMu.Lock()
defer f.handleMu.Unlock()
f.invalidateAST(ctx)
f.handle = nil
}
// invalidateAST invalidates the AST of a Go file,
// including any position and type information that depends on it.
func (f *goFile) invalidateAST(ctx context.Context) {
f.mu.Lock()
cphs := f.pkgs
f.mu.Unlock()
// Remove the package and all of its reverse dependencies from the cache.
for id, cph := range cphs {
if cph != nil {
f.view.remove(ctx, id, map[packageID]struct{}{})
}
for _, id := range toDelete {
f.view.remove(ctx, id, map[packageID]struct{}{})
}
f.handle = nil
}
// remove invalidates a package and its reverse dependencies in the view's