From ac2db28e8130c9a3086ce3adef32547cbcb3a981 Mon Sep 17 00:00:00 2001 From: Rohan Challa Date: Thu, 5 Dec 2019 16:03:59 -0500 Subject: [PATCH] internal/lsp: invalidate workspace packages when go.mod file changes When the go.mod file changes, we should invalidate all the files that are contained in the package for the mod file. This will allow the files to recheck their packages in case new packages were added in the go.mod file. This still does not fix issue where changes to go.mod files do not trigger recalculation of diagnostics. Updates golang/go#31999 Change-Id: I6d8f1531f5c28ed2dca7fb8ad4ee0317fada787b Reviewed-on: https://go-review.googlesource.com/c/tools/+/210557 Run-TryBot: Rohan Challa TryBot-Result: Gobot Gobot Reviewed-by: Rebecca Stambler --- internal/lsp/cache/load.go | 3 +++ internal/lsp/cache/snapshot.go | 9 ++++++++- internal/lsp/cache/view.go | 2 +- internal/lsp/text_synchronization.go | 10 +++++++++- 4 files changed, 21 insertions(+), 3 deletions(-) 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 }