internal/lsp: restore snapshot ID guard for published diagnostics

A guard against publishing stale diagnostics was removed in CL 269677,
because the signficance of diagnoseDetached was overlooked. Restore it.

For golang/go#42837

Change-Id: I911c4707a9c18a632ce32e0c25c43ae2e92135b2
Reviewed-on: https://go-review.googlesource.com/c/tools/+/274241
Run-TryBot: Robert Findley <rfindley@google.com>
Trust: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
This commit is contained in:
Rob Findley 2020-11-30 19:59:07 -05:00 коммит произвёл Robert Findley
Родитель bf23c547d2
Коммит bd313628b4
1 изменённых файлов: 10 добавлений и 4 удалений

Просмотреть файл

@ -44,6 +44,7 @@ type diagnosticReport struct {
// fileReports holds a collection of diagnostic reports for a single file, as
// well as the hash of the last published set of diagnostics.
type fileReports struct {
snapshotID uint64
publishedHash string
reports map[diagnosticSource]diagnosticReport
}
@ -430,14 +431,18 @@ func (s *Server) publishDiagnostics(ctx context.Context, final bool, snapshot so
s.diagnosticsMu.Lock()
defer s.diagnosticsMu.Unlock()
for uri, r := range s.diagnostics {
// Snapshot IDs are always increasing, so we use them instead of file
// versions to create the correct order for diagnostics.
// If we've already delivered diagnostics for a future snapshot for this
// file, do not deliver them.
if r.snapshotID > snapshot.ID() {
continue
}
anyReportsChanged := false
reportHashes := map[diagnosticSource]string{}
var diags []*source.Diagnostic
for dsource, report := range r.reports {
// Note: it might be worth adding special handling for the case where
// report.snapshotID > snapshot.ID(), in which case this publish pass is
// operating on stale data, but for now this is handled by virtue of
// cancelling the old snapshot context before diagnosing the next.
if report.snapshotID != snapshot.ID() {
continue
}
@ -473,6 +478,7 @@ func (s *Server) publishDiagnostics(ctx context.Context, final bool, snapshot so
Version: version,
}); err == nil {
r.publishedHash = hash
r.snapshotID = snapshot.ID()
for dsource, hash := range reportHashes {
report := r.reports[dsource]
report.publishedHash = hash