internal/lsp: do not reinitialize the workspace for didOpen events

Previously, we would treat file opens/closes as workspace
reinitialization events.

Change-Id: Ib8ca490fe7a44768a757311b058093d0bf3888c6
Reviewed-on: https://go-review.googlesource.com/c/tools/+/317450
Trust: Rebecca Stambler <rstambler@golang.org>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
Rebecca Stambler 2021-05-05 20:47:34 -04:00
parent 0185c7ed42
commit 5a667787ee
3 changed files with 42 additions and 8 deletions

View File

@ -1912,3 +1912,27 @@ func foo() int {
)
})
}
// This test confirms that the view does not reinitialize when a go.mod file is
// opened.
func TestNoReinitialize(t *testing.T) {
const files = `
-- go.mod --
module mod.com
go 1.12
-- main.go --
package main
func main() {}
`
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("go.mod")
env.Await(
OnceMet(
env.DoneWithOpen(),
LogMatching(protocol.Info, `.*query=\[builtin mod.com/...\].*`, 1),
),
)
})
}

View File

@ -408,6 +408,11 @@ type fileChange struct {
content []byte
exists bool
fileHandle source.VersionedFileHandle
// isUnchanged indicates whether the file action is one that does not
// change the actual contents of the file. Opens and closes should not
// be treated like other changes, since the file content doesn't change.
isUnchanged bool
}
func (s *Session) DidModifyFiles(ctx context.Context, changes []source.FileModification) (map[source.Snapshot][]span.URI, []func(), error) {
@ -448,6 +453,8 @@ func (s *Session) DidModifyFiles(ctx context.Context, changes []source.FileModif
}
affectedViews[c.URI] = changedViews
isUnchanged := c.Action == source.Open || c.Action == source.Close
// Apply the changes to all affected views.
for _, view := range changedViews {
// Make sure that the file is added to the view.
@ -457,9 +464,10 @@ func (s *Session) DidModifyFiles(ctx context.Context, changes []source.FileModif
}
if fh, ok := overlays[c.URI]; ok {
views[view][c.URI] = &fileChange{
content: fh.text,
exists: true,
fileHandle: fh,
content: fh.text,
exists: true,
fileHandle: fh,
isUnchanged: isUnchanged,
}
} else {
fsFile, err := s.cache.getFile(ctx, c.URI)
@ -469,9 +477,10 @@ func (s *Session) DidModifyFiles(ctx context.Context, changes []source.FileModif
content, err := fsFile.Read()
fh := &closedFile{fsFile}
views[view][c.URI] = &fileChange{
content: content,
exists: err == nil,
fileHandle: fh,
content: content,
exists: err == nil,
fileHandle: fh,
isUnchanged: isUnchanged,
}
}
}

View File

@ -277,7 +277,8 @@ func (w *workspace) invalidate(ctx context.Context, changes map[span.URI]*fileCh
// If gopls.mod has changed we need to either re-read it if it exists or
// walk the filesystem if it has been deleted.
gmURI := goplsModURI(w.root)
if change, ok := changes[gmURI]; ok {
// File opens/closes are just no-ops.
if change, ok := changes[gmURI]; ok && !change.isUnchanged {
if change.exists {
// Only invalidate if the gopls.mod actually parses.
// Otherwise, stick with the current gopls.mod.
@ -326,7 +327,7 @@ func (w *workspace) invalidate(ctx context.Context, changes map[span.URI]*fileCh
// here.
if result.moduleSource != goplsModWorkspace {
for uri, change := range changes {
if !isGoMod(uri) || !source.InDir(result.root.Filename(), uri.Filename()) {
if change.isUnchanged || !isGoMod(uri) || !source.InDir(result.root.Filename(), uri.Filename()) {
continue
}
changed = true