mirror of
https://github.com/golang/go
synced 2024-11-18 17:34:51 -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 {
|
func (f *fileBase) Handle(ctx context.Context) source.FileHandle {
|
||||||
f.handleMu.Lock()
|
f.handleMu.Lock()
|
||||||
defer f.handleMu.Unlock()
|
defer f.handleMu.Unlock()
|
||||||
|
|
||||||
if f.handle == nil {
|
if f.handle == nil {
|
||||||
f.handle = f.view.Session().GetFile(f.URI())
|
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
|
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) {
|
func (f *goFile) GetToken(ctx context.Context) (*token.File, error) {
|
||||||
file, err := f.GetAST(ctx, source.ParseFull)
|
file, err := f.GetAST(ctx, source.ParseFull)
|
||||||
if file == nil {
|
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()
|
view.mcache.mu.Lock()
|
||||||
defer view.mcache.mu.Unlock()
|
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,
|
// If the AST for this file is trimmed, and we are explicitly type-checking it,
|
||||||
// don't ignore function bodies.
|
// don't ignore function bodies.
|
||||||
if f.wrongParseMode(ctx, source.ParseFull) {
|
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.
|
// 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()
|
f.view.mcache.mu.Lock()
|
||||||
defer f.view.mcache.mu.Unlock()
|
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()
|
f.handleMu.Lock()
|
||||||
defer f.handleMu.Unlock()
|
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.
|
// Remove the package and all of its reverse dependencies from the cache.
|
||||||
for id, cph := range cphs {
|
for _, id := range toDelete {
|
||||||
if cph != nil {
|
f.view.remove(ctx, id, map[packageID]struct{}{})
|
||||||
f.view.remove(ctx, id, map[packageID]struct{}{})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f.handle = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove invalidates a package and its reverse dependencies in the view's
|
// remove invalidates a package and its reverse dependencies in the view's
|
||||||
|
Loading…
Reference in New Issue
Block a user