Skip to content

Commit

Permalink
internal/lsp: invalidate package on go.mod change with go.work
Browse files Browse the repository at this point in the history
If a go.mod file is updated, the packages
in that module may have updated type check
errors since the go version can affect errors.

Fixes golang/go#51732

Change-Id: I3a8cd8b9ab267336ccc5c841a14c5ec5f6c986e5
Reviewed-on: https://go-review.googlesource.com/c/tools/+/393534
Trust: Suzy Mueller <suzmue@golang.org>
Run-TryBot: Suzy Mueller <suzmue@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
  • Loading branch information
suzmue committed Mar 17, 2022
1 parent c7b0e9a commit 779dfa4
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 21 deletions.
36 changes: 35 additions & 1 deletion gopls/internal/regtest/diagnostics/diagnostics_test.go
Expand Up @@ -2199,7 +2199,41 @@ package main
func F[T any](_ T) {
}
`
Run(t, files, func(t *testing.T, env *Env) { // Create a new workspace-level directory and empty file.
Run(t, files, func(_ *testing.T, env *Env) { // Create a new workspace-level directory and empty file.
var d protocol.PublishDiagnosticsParams
env.Await(
OnceMet(
env.DiagnosticAtRegexpWithMessage("main.go", `T any`, "type parameters require"),
ReadDiagnostics("main.go", &d),
),
)

env.ApplyQuickFixes("main.go", d.Diagnostics)

env.Await(
EmptyDiagnostics("main.go"),
)
})
}

func TestEditGoDirectiveWorkspace(t *testing.T) {
testenv.NeedsGo1Point(t, 18)
const files = `
-- go.mod --
module mod.com
go 1.16
-- go.work --
go 1.18
use .
-- main.go --
package main
func F[T any](_ T) {
}
`
Run(t, files, func(_ *testing.T, env *Env) { // Create a new workspace-level directory and empty file.
var d protocol.PublishDiagnosticsParams
env.Await(
OnceMet(
Expand Down
40 changes: 20 additions & 20 deletions internal/lsp/cache/workspace.go
Expand Up @@ -301,27 +301,27 @@ func (w *workspace) invalidate(ctx context.Context, changes map[span.URI]*fileCh
// we need to either re-read it if it exists or walk the filesystem if it
// has been deleted. go.work should override the gopls.mod if both exist.
changed, reload = handleWorkspaceFileChanges(ctx, result, changes, fs)
// Next, handle go.mod changes that could affect our workspace. If we're
// reading our tracked modules from the gopls.mod, there's nothing to do
// here.
if result.moduleSource != goplsModWorkspace && result.moduleSource != goWorkWorkspace {
for uri, change := range changes {
// Otherwise, we only care about go.mod files in the workspace directory.
if change.isUnchanged || !isGoMod(uri) || !source.InDir(result.root.Filename(), uri.Filename()) {
continue
}
changed = true
active := result.moduleSource != legacyWorkspace || source.CompareURI(modURI(w.root), uri) == 0
reload = reload || (active && change.fileHandle.Saved())
if change.exists {
result.knownModFiles[uri] = struct{}{}
if active {
result.activeModFiles[uri] = struct{}{}
}
} else {
delete(result.knownModFiles, uri)
delete(result.activeModFiles, uri)
// Next, handle go.mod changes that could affect our workspace.
for uri, change := range changes {
// Otherwise, we only care about go.mod files in the workspace directory.
if change.isUnchanged || !isGoMod(uri) || !source.InDir(result.root.Filename(), uri.Filename()) {
continue
}
changed = true
active := result.moduleSource != legacyWorkspace || source.CompareURI(modURI(w.root), uri) == 0
reload = reload || (active && change.fileHandle.Saved())
// Don't mess with the list of mod files if using go.work or gopls.mod.
if result.moduleSource == goplsModWorkspace || result.moduleSource == goWorkWorkspace {
continue
}
if change.exists {
result.knownModFiles[uri] = struct{}{}
if active {
result.activeModFiles[uri] = struct{}{}
}
} else {
delete(result.knownModFiles, uri)
delete(result.activeModFiles, uri)
}
}

Expand Down

0 comments on commit 779dfa4

Please sign in to comment.