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:
parent
958971f5c2
commit
70bfb60283
1
internal/lsp/cache/file.go
vendored
1
internal/lsp/cache/file.go
vendored
@ -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())
|
||||
}
|
||||
|
8
internal/lsp/cache/gofile.go
vendored
8
internal/lsp/cache/gofile.go
vendored
@ -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 {
|
||||
|
14
internal/lsp/cache/load.go
vendored
14
internal/lsp/cache/load.go
vendored
@ -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.
|
||||
|
28
internal/lsp/cache/view.go
vendored
28
internal/lsp/cache/view.go
vendored
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user