diff --git a/internal/lsp/cache/load.go b/internal/lsp/cache/load.go index a6bdc6901d..6d8a9ef1d2 100644 --- a/internal/lsp/cache/load.go +++ b/internal/lsp/cache/load.go @@ -80,6 +80,9 @@ func (c *cache) shouldLoad(ctx context.Context, s *snapshot, originalFH, current if originalFH == nil { return true } + if originalFH.Identity().Kind == currentFH.Identity().Kind && currentFH.Identity().Kind == source.Mod { + return true + } // Get the original and current parsed files in order to check package name and imports. original, _, _, originalErr := c.ParseGoHandle(originalFH, source.ParseHeader).Parse(ctx) diff --git a/internal/lsp/cache/snapshot.go b/internal/lsp/cache/snapshot.go index 98fd270e18..72806589b5 100644 --- a/internal/lsp/cache/snapshot.go +++ b/internal/lsp/cache/snapshot.go @@ -537,7 +537,7 @@ func (s *snapshot) ID() uint64 { // It returns true if we were already tracking the given file, false otherwise. // // Note: The logic in this function is convoluted. Do not change without significant thought. -func (v *view) invalidateContent(ctx context.Context, f source.File, kind source.FileKind, action source.FileAction) bool { +func (v *view) invalidateContent(ctx context.Context, f source.File, action source.FileAction) bool { var ( withoutTypes = make(map[span.URI]struct{}) withoutMetadata = make(map[span.URI]struct{}) @@ -553,6 +553,13 @@ func (v *view) invalidateContent(ctx context.Context, f source.File, kind source ids[id] = struct{}{} } + // If we are invalidating a go.mod file then we should invalidate all of the packages in the module + if f.Kind() == source.Mod { + for id := range v.snapshot.workspacePackages { + ids[id] = struct{}{} + } + } + // Get the original FileHandle for the URI, if it exists. originalFH := v.snapshot.getFile(f.URI()) diff --git a/internal/lsp/cache/view.go b/internal/lsp/cache/view.go index c7971938ad..6cd68b6d72 100644 --- a/internal/lsp/cache/view.go +++ b/internal/lsp/cache/view.go @@ -378,7 +378,7 @@ func (v *view) getFile(ctx context.Context, uri span.URI, kind source.FileKind) } v.session.filesWatchMap.Watch(uri, func(action source.FileAction) bool { ctx := xcontext.Detach(ctx) - return v.invalidateContent(ctx, f, kind, action) + return v.invalidateContent(ctx, f, action) }) v.mapFile(uri, f) return f, nil diff --git a/internal/lsp/text_synchronization.go b/internal/lsp/text_synchronization.go index 75e2820438..6496cf3829 100644 --- a/internal/lsp/text_synchronization.go +++ b/internal/lsp/text_synchronization.go @@ -106,7 +106,15 @@ func (s *Server) didModifyFile(ctx context.Context, c source.FileModification) e // We should run diagnostics after opening or changing a file. switch c.Action { case source.Open, source.Change: - go s.diagnoseFile(view.Snapshot(), c.URI) + f, err := view.GetFile(ctx, c.URI) + if err != nil { + return err + } + if f.Kind() == source.Mod { + go s.diagnoseSnapshot(view.Snapshot()) + } else { + go s.diagnoseFile(view.Snapshot(), c.URI) + } } return nil }