From 6d151481565cdd477137cd2cc2e7abf48022bb79 Mon Sep 17 00:00:00 2001 From: Rebecca Stambler Date: Wed, 18 Nov 2020 16:38:56 -0500 Subject: [PATCH] internal/lsp/cache: only invalidate metadata for go.mod files on save Throwing away all of the metadata in the package means it will be expensive to reload, so it makes sense to keep it around until a go.mod file has been saved, indicating that the user is more likely to be done typing. Otherwise, we will be triggering full package metadata reloads on every keystroke. Fixes golang/go#42529 Change-Id: Ibc4f4bc8937f8f7176da79e9fefe166468578993 Reviewed-on: https://go-review.googlesource.com/c/tools/+/271299 Trust: Rebecca Stambler Run-TryBot: Rebecca Stambler gopls-CI: kokoro Reviewed-by: Heschi Kreinick --- internal/lsp/cache/cache.go | 4 ++++ internal/lsp/cache/session.go | 4 ++++ internal/lsp/cache/snapshot.go | 5 ++++- internal/lsp/source/view.go | 5 ++--- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/internal/lsp/cache/cache.go b/internal/lsp/cache/cache.go index 5e6180d73f..6d40ecb5d5 100644 --- a/internal/lsp/cache/cache.go +++ b/internal/lsp/cache/cache.go @@ -59,6 +59,10 @@ type fileHandle struct { err error } +func (h *fileHandle) Saved() bool { + return true +} + func (c *Cache) GetFile(ctx context.Context, uri span.URI) (source.FileHandle, error) { return c.getFile(ctx, uri) } diff --git a/internal/lsp/cache/session.go b/internal/lsp/cache/session.go index 43516b7870..e1d43de3bb 100644 --- a/internal/lsp/cache/session.go +++ b/internal/lsp/cache/session.go @@ -106,6 +106,10 @@ func (c *closedFile) VersionedFileIdentity() source.VersionedFileIdentity { } } +func (c *closedFile) Saved() bool { + return true +} + func (c *closedFile) Session() string { return "" } diff --git a/internal/lsp/cache/snapshot.go b/internal/lsp/cache/snapshot.go index 3e35ca7f17..9cce32bb0c 100644 --- a/internal/lsp/cache/snapshot.go +++ b/internal/lsp/cache/snapshot.go @@ -1415,7 +1415,10 @@ func (s *snapshot) shouldInvalidateMetadata(ctx context.Context, newSnapshot *sn } // If a go.mod in the workspace has been changed, invalidate metadata. if kind := originalFH.Kind(); kind == source.Mod { - return source.InDir(filepath.Dir(s.view.rootURI.Filename()), filepath.Dir(originalFH.URI().Filename())) + if !source.InDir(filepath.Dir(s.view.rootURI.Filename()), originalFH.URI().Filename()) { + return false + } + return currentFH.Saved() } // Get the original and current parsed files in order to check package name // and imports. Use the new snapshot to parse to avoid modifying the diff --git a/internal/lsp/source/view.go b/internal/lsp/source/view.go index cc7b207d99..89f4c6a252 100644 --- a/internal/lsp/source/view.go +++ b/internal/lsp/source/view.go @@ -306,9 +306,6 @@ type Session interface { // Overlay is the type for a file held in memory on a session. type Overlay interface { VersionedFileHandle - - // Saved returns whether this overlay has been saved to disk. - Saved() bool } // FileModification represents a modification to a file. @@ -438,6 +435,8 @@ type FileHandle interface { // Read reads the contents of a file. // If the file is not available, returns a nil slice and an error. Read() ([]byte, error) + // Saved reports whether the file has the same content on disk. + Saved() bool } // FileIdentity uniquely identifies a file at a version from a FileSystem.