gopls: fix windows file corruption
Fix the bug that gopls finds the wrong content when formatting an open
URI whose spelling does not match the spelling on disk (i.e. because of
case insensitivity).
Remove the whole View.filesByBase mechanism: it is problematic as we
can't generally know whether or not we want to associate two different
spellings of the same file: for the purposes of finding packages we may
want to treat Foo.go as foo.go, but we don't want to treat a symlink of
foo.go in another directory the same.
Instead, use robustio.FileID to de-duplicate content in the cache, and
otherwise treat URIs as we receive them. This fixes the formatting
corruption, but means that we don't find packages for the corresponding
file (because go/packages.Load("file=foo.go") fails). A failing test is
added for the latter bug.
Also: use a seenFiles map in the view to satisfy the concern of tracking
relevant files, with a TODO to delete this problematic map.
Along the way, refactor somewhat to separate and normalize the
implementations of source.FileSource.
For golang/go#57081
Change-Id: I02971a1702f057b644fa18a873790e8f0d98a323
Reviewed-on: https://go-review.googlesource.com/c/tools/+/462819
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
diff --git a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snapshot.go
index 995fba3..398240a 100644
--- a/gopls/internal/lsp/cache/snapshot.go
+++ b/gopls/internal/lsp/cache/snapshot.go
@@ -262,7 +262,7 @@
}
func (s *snapshot) FileSet() *token.FileSet {
- return s.view.cache.fset
+ return s.view.fset
}
func (s *snapshot) ModFiles() []span.URI {
@@ -620,7 +620,7 @@
return
}
// TODO(rstambler): Make sure not to send overlays outside of the current view.
- overlays[uri.Filename()] = overlay.text
+ overlays[uri.Filename()] = overlay.content
})
return overlays
}
@@ -1205,7 +1205,7 @@
}
func (s *snapshot) FindFile(uri span.URI) source.FileHandle {
- uri, _ = s.view.canonicalURI(uri, true)
+ s.view.markKnown(uri)
s.mu.Lock()
defer s.mu.Unlock()
@@ -1220,7 +1220,7 @@
// GetFile succeeds even if the file does not exist. A non-nil error return
// indicates some type of internal error, for example if ctx is cancelled.
func (s *snapshot) GetFile(ctx context.Context, uri span.URI) (source.FileHandle, error) {
- uri, _ = s.view.canonicalURI(uri, true)
+ s.view.markKnown(uri)
s.mu.Lock()
defer s.mu.Unlock()
@@ -1229,7 +1229,7 @@
return fh, nil
}
- fh, err := s.view.cache.GetFile(ctx, uri) // read the file
+ fh, err := s.view.fs.GetFile(ctx, uri) // read the file
if err != nil {
return nil, err
}