Skip to content

Commit e487248

Browse files
heschimyitcv
authored andcommitted
internal/lsp/cache: don't forget files just because they change
The situation in golang/go#35638 was as follows: didOpen main.go creates a snapshot that knows main.go is in package "mod.com". didChange main.go creates a snapshot. When a file changes, we discard its contents by leaving the file handle out of the "files" map. didOpen const.go creates a snapshot, and attempts to invalidate the metadata for packages in the same directory. The way we detect packages in the same directory is by iterating through the files in the snapshot. But we threw away the only file in "mod.com" in step 2 when its contents changed. If a diagnostics run happened to get in between the two steps, it would re-load main.go and the bug would go away. If not, step 3 would find no files and fail to invalidate "mod.com". The best way to fix this is to insert the new file handle eagerly during cloning. That way there's no confusion. Fixes golang/go#35638. Change-Id: I340bd28a96ad7b4cc912032065f3c2732c380bb2
1 parent bbbf87a commit e487248

File tree

1 file changed

+11
-7
lines changed

1 file changed

+11
-7
lines changed

internal/lsp/cache/snapshot.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -531,13 +531,20 @@ func (s *snapshot) clone(ctx context.Context, withoutFile source.File) *snapshot
531531
files: make(map[span.URI]source.FileHandle),
532532
workspacePackages: make(map[packageID]bool),
533533
}
534-
// Copy all of the FileHandles except for the one that was invalidated.
534+
535+
// Copy all of the FileHandles.
535536
for k, v := range s.files {
536-
if k == withoutFile.URI() {
537-
continue
538-
}
539537
result.files[k] = v
540538
}
539+
// Handle the invalidated file; it may have new contents or not exist.
540+
currentFH := s.view.session.GetFile(withoutFile.URI(), withoutFile.Kind())
541+
_, _, err := currentFH.Read(ctx)
542+
if os.IsNotExist(err) {
543+
delete(result.files, withoutFile.URI())
544+
} else {
545+
result.files[withoutFile.URI()] = currentFH
546+
}
547+
541548
// Collect the IDs for the packages associated with the excluded URIs.
542549
for k, ids := range s.ids {
543550
result.ids[k] = ids
@@ -561,9 +568,6 @@ func (s *snapshot) clone(ctx context.Context, withoutFile source.File) *snapshot
561568
result.workspacePackages[k] = v
562569
}
563570

564-
// Get the current FileHandle for the URI.
565-
currentFH := s.view.session.GetFile(withoutFile.URI(), withoutFile.Kind())
566-
567571
// Check if the file's package name or imports have changed,
568572
// and if so, invalidate this file's packages' metadata.
569573
invalidateMetadata := s.view.session.cache.shouldLoad(ctx, s, originalFH, currentFH)

0 commit comments

Comments
 (0)