internal/lsp/cache: parse files with ParseFull mode to check if metadata reload is required
ParseHeader mode is used to parse only the package and import declarations.
However, change of go:embed directive should also invalidate metadata.
So, we must use ParseFull mode to get all file comments to compare
old and new go:embed directives.
Fixes golang/go#47436
Change-Id: If7cdb6741e895315bb6a6de2f207b404e15b269a
GitHub-Last-Rev: 64d606cead064ed5996eb7d55c3664940e7a1deb
GitHub-Pull-Request: golang/tools#333
Reviewed-on: https://go-review.googlesource.com/c/tools/+/339469
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
Trust: Rebecca Stambler <rstambler@golang.org>
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
diff --git a/gopls/internal/regtest/misc/embed_test.go b/gopls/internal/regtest/misc/embed_test.go
index 8fb654b..2e66d78 100644
--- a/gopls/internal/regtest/misc/embed_test.go
+++ b/gopls/internal/regtest/misc/embed_test.go
@@ -22,6 +22,9 @@
_ "embed"
)
+// Issue 47436
+func F() {}
+
//go:embed NONEXISTENT
var foo string
`
diff --git a/internal/lsp/cache/snapshot.go b/internal/lsp/cache/snapshot.go
index 4f1bf19..6ea3aa5 100644
--- a/internal/lsp/cache/snapshot.go
+++ b/internal/lsp/cache/snapshot.go
@@ -2042,8 +2042,8 @@
return !o.saved && c.saved
}
-// shouldInvalidateMetadata reparses a file's package and import declarations to
-// determine if the file requires a metadata reload.
+// shouldInvalidateMetadata reparses the full file's AST to determine
+// if the file requires a metadata reload.
func (s *snapshot) shouldInvalidateMetadata(ctx context.Context, newSnapshot *snapshot, originalFH, currentFH source.FileHandle) (invalidate, pkgNameChanged, importDeleted bool) {
if originalFH == nil {
return true, false, false
@@ -2055,8 +2055,8 @@
// Get the original and current parsed files in order to check package name
// and imports. Use the new snapshot to parse to avoid modifying the
// current snapshot.
- original, originalErr := newSnapshot.ParseGo(ctx, originalFH, source.ParseHeader)
- current, currentErr := newSnapshot.ParseGo(ctx, currentFH, source.ParseHeader)
+ original, originalErr := newSnapshot.ParseGo(ctx, originalFH, source.ParseFull)
+ current, currentErr := newSnapshot.ParseGo(ctx, currentFH, source.ParseFull)
if originalErr != nil || currentErr != nil {
return (originalErr == nil) != (currentErr == nil), false, (currentErr != nil) // we don't know if an import was deleted
}