mirror of
https://github.com/golang/go
synced 2024-11-18 21:05:02 -07:00
internal/lsp: invalidate metadata and type info more selectively
Say you have foo.go and foo_test.go yielding packages "foo" and "foo.test". Previously when you changed foo_test.go we would invalidate the foo.test and foo packages. Invalidating foo is not necessary since it does not depend on any test files. Furthermore, it caused problems because nothing would refetch foo's metadata until foo.go changed, so various things (such as finding implementations in packages that depend on "foo") would be broken. Now we only invalidate metadata from packages that contain the modified file. We only invalidate type info from packages that contain the modified file, or from such packages' transitive reverse dependencies. Change-Id: I23d1af91bcdf22fad4faa1b048afe17ef4e403a1 Reviewed-on: https://go-review.googlesource.com/c/tools/+/210460 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:
parent
ec14b29651
commit
4da4485a1c
43
internal/lsp/cache/snapshot.go
vendored
43
internal/lsp/cache/snapshot.go
vendored
@ -452,7 +452,7 @@ func (s *snapshot) Handle(ctx context.Context, f source.File) source.FileHandle
|
|||||||
return s.files[f.URI()]
|
return s.files[f.URI()]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *snapshot) clone(ctx context.Context, withoutURI span.URI, withoutTypes, withoutMetadata map[span.URI]struct{}) *snapshot {
|
func (s *snapshot) clone(ctx context.Context, withoutURI span.URI, withoutTypes, withoutMetadata map[packageID]struct{}) *snapshot {
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
defer s.mu.Unlock()
|
defer s.mu.Unlock()
|
||||||
|
|
||||||
@ -475,46 +475,32 @@ func (s *snapshot) clone(ctx context.Context, withoutURI span.URI, withoutTypes,
|
|||||||
result.files[k] = v
|
result.files[k] = v
|
||||||
}
|
}
|
||||||
// Collect the IDs for the packages associated with the excluded URIs.
|
// Collect the IDs for the packages associated with the excluded URIs.
|
||||||
withoutMetadataIDs := make(map[packageID]struct{})
|
|
||||||
withoutTypesIDs := make(map[packageID]struct{})
|
|
||||||
for k, ids := range s.ids {
|
for k, ids := range s.ids {
|
||||||
// Map URIs to IDs for exclusion.
|
|
||||||
if _, ok := withoutTypes[k]; ok {
|
|
||||||
for _, id := range ids {
|
|
||||||
withoutTypesIDs[id] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if _, ok := withoutMetadata[k]; ok {
|
|
||||||
for _, id := range ids {
|
|
||||||
withoutMetadataIDs[id] = struct{}{}
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
result.ids[k] = ids
|
result.ids[k] = ids
|
||||||
}
|
}
|
||||||
// Copy the package type information.
|
// Copy the package type information.
|
||||||
for k, v := range s.packages {
|
for k, v := range s.packages {
|
||||||
if _, ok := withoutTypesIDs[k.id]; ok {
|
if _, ok := withoutTypes[k.id]; ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if _, ok := withoutMetadataIDs[k.id]; ok {
|
if _, ok := withoutMetadata[k.id]; ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
result.packages[k] = v
|
result.packages[k] = v
|
||||||
}
|
}
|
||||||
// Copy the package analysis information.
|
// Copy the package analysis information.
|
||||||
for k, v := range s.actions {
|
for k, v := range s.actions {
|
||||||
if _, ok := withoutTypesIDs[k.pkg.id]; ok {
|
if _, ok := withoutTypes[k.pkg.id]; ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if _, ok := withoutMetadataIDs[k.pkg.id]; ok {
|
if _, ok := withoutMetadata[k.pkg.id]; ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
result.actions[k] = v
|
result.actions[k] = v
|
||||||
}
|
}
|
||||||
// Copy the package metadata.
|
// Copy the package metadata.
|
||||||
for k, v := range s.metadata {
|
for k, v := range s.metadata {
|
||||||
if _, ok := withoutMetadataIDs[k]; ok {
|
if _, ok := withoutMetadata[k]; ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
result.metadata[k] = v
|
result.metadata[k] = v
|
||||||
@ -539,8 +525,8 @@ func (s *snapshot) ID() uint64 {
|
|||||||
// Note: The logic in this function is convoluted. Do not change without significant thought.
|
// Note: The logic in this function is convoluted. Do not change without significant thought.
|
||||||
func (v *view) invalidateContent(ctx context.Context, f source.File, action source.FileAction) bool {
|
func (v *view) invalidateContent(ctx context.Context, f source.File, action source.FileAction) bool {
|
||||||
var (
|
var (
|
||||||
withoutTypes = make(map[span.URI]struct{})
|
withoutTypes = make(map[packageID]struct{})
|
||||||
withoutMetadata = make(map[span.URI]struct{})
|
withoutMetadata = make(map[packageID]struct{})
|
||||||
ids = make(map[packageID]struct{})
|
ids = make(map[packageID]struct{})
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -591,15 +577,8 @@ func (v *view) invalidateContent(ctx context.Context, f source.File, action sour
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove the package and all of its reverse dependencies from the cache.
|
// Remove the package and all of its reverse dependencies from the cache.
|
||||||
reverseDependencies := make(map[packageID]struct{})
|
|
||||||
for id := range ids {
|
for id := range ids {
|
||||||
v.snapshot.transitiveReverseDependencies(id, reverseDependencies)
|
v.snapshot.transitiveReverseDependencies(id, withoutTypes)
|
||||||
}
|
|
||||||
for id := range reverseDependencies {
|
|
||||||
m := v.snapshot.getMetadata(id)
|
|
||||||
for _, uri := range m.compiledGoFiles {
|
|
||||||
withoutTypes[uri] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are deleting a file, make sure to clear out the overlay.
|
// If we are deleting a file, make sure to clear out the overlay.
|
||||||
@ -614,9 +593,7 @@ func (v *view) invalidateContent(ctx context.Context, f source.File, action sour
|
|||||||
// and if so, invalidate this file's packages' metadata.
|
// and if so, invalidate this file's packages' metadata.
|
||||||
if v.session.cache.shouldLoad(ctx, v.snapshot, originalFH, currentFH) {
|
if v.session.cache.shouldLoad(ctx, v.snapshot, originalFH, currentFH) {
|
||||||
for id := range ids {
|
for id := range ids {
|
||||||
for _, uri := range v.snapshot.getMetadata(id).compiledGoFiles {
|
withoutMetadata[id] = struct{}{}
|
||||||
withoutMetadata[uri] = struct{}{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: If a package's name has changed,
|
// TODO: If a package's name has changed,
|
||||||
// we should invalidate the metadata for the new package name (if it exists).
|
// we should invalidate the metadata for the new package name (if it exists).
|
||||||
|
Loading…
Reference in New Issue
Block a user