From ef3185ba9cbdffc5fe46ffe8df44e7934433ce91 Mon Sep 17 00:00:00 2001 From: Rob Findley Date: Wed, 30 Dec 2020 09:37:05 -0500 Subject: [PATCH] internal/lsp/cache: add a check for snapshot invariants Check that some invariants are met when cloning the snapshot, in an attempt to catch golang/go#43347 For golang/go#43347 Change-Id: I7404509027a1b0b0085133cba4d21d1006a52a57 Reviewed-on: https://go-review.googlesource.com/c/tools/+/280698 Run-TryBot: Robert Findley gopls-CI: kokoro TryBot-Result: Go Bot Trust: Robert Findley Reviewed-by: Rebecca Stambler --- internal/lsp/cache/snapshot.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/internal/lsp/cache/snapshot.go b/internal/lsp/cache/snapshot.go index 1713e96726..08459a747c 100644 --- a/internal/lsp/cache/snapshot.go +++ b/internal/lsp/cache/snapshot.go @@ -25,6 +25,7 @@ import ( "golang.org/x/tools/go/packages" "golang.org/x/tools/internal/event" "golang.org/x/tools/internal/gocommand" + "golang.org/x/tools/internal/lsp/debug/log" "golang.org/x/tools/internal/lsp/debug/tag" "golang.org/x/tools/internal/lsp/source" "golang.org/x/tools/internal/memoize" @@ -1231,6 +1232,29 @@ func generationName(v *View, snapshotID uint64) string { return fmt.Sprintf("v%v/%v", v.id, snapshotID) } +// checkSnapshotLocked verifies that some invariants are preserved on the +// snapshot. +func checkSnapshotLocked(ctx context.Context, s *snapshot) { + // Check that every go file for a workspace package is identified as + // belonging to that workspace package. + for wsID := range s.workspacePackages { + if m, ok := s.metadata[wsID]; ok { + for _, uri := range m.goFiles { + found := false + for _, id := range s.ids[uri] { + if id == wsID { + found = true + break + } + } + if !found { + log.Error.Logf(ctx, "workspace package %v not associated with %v", wsID, uri) + } + } + } + } +} + func (s *snapshot) clone(ctx, bgCtx context.Context, changes map[span.URI]*fileChange, forceReloadMetadata bool) (*snapshot, bool) { var vendorChanged bool newWorkspace, workspaceChanged, workspaceReload := s.workspace.invalidate(ctx, changes) @@ -1238,6 +1262,8 @@ func (s *snapshot) clone(ctx, bgCtx context.Context, changes map[span.URI]*fileC s.mu.Lock() defer s.mu.Unlock() + checkSnapshotLocked(ctx, s) + newGen := s.view.session.cache.store.Generation(generationName(s.view, s.id+1)) bgCtx, cancel := context.WithCancel(bgCtx) result := &snapshot{