From 633b092c1ed37a3d99a4cff506d3044328b2e5cb Mon Sep 17 00:00:00 2001 From: Rebecca Stambler Date: Fri, 17 Jan 2020 13:12:00 -0500 Subject: [PATCH] internal/lsp: add recency check to avoid sending old diagnostics This change uses snapshot IDs instead of file versions to determine if diagnostics are stale. Fixes golang/go#36601. Change-Id: I7727a30222fecf2d7733fa013c6cee6338ffd968 Reviewed-on: https://go-review.googlesource.com/c/tools/+/215298 Run-TryBot: Rebecca Stambler TryBot-Result: Gobot Gobot Reviewed-by: Heschi Kreinick --- internal/lsp/diagnostics.go | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/internal/lsp/diagnostics.go b/internal/lsp/diagnostics.go index c09f08fb4c..d6d204c57d 100644 --- a/internal/lsp/diagnostics.go +++ b/internal/lsp/diagnostics.go @@ -113,20 +113,35 @@ func (s *Server) publishReports(ctx context.Context, snapshot source.Snapshot, r withAnalysis: withAnalysis, snapshotID: snapshot.ID(), } + // We use the zero values if this is an unknown file. delivered := s.delivered[fileID.URI] - // Reuse cached diagnostics and update the delivered map. - if fileID.Version >= delivered.version && equalDiagnostics(delivered.sorted, 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 delivered.snapshotID > toSend.snapshotID { + // Do not update the delivered map since it already contains newer diagnostics. + continue + } + + // Check if we should reuse the cached diagnostics. + if equalDiagnostics(delivered.sorted, diagnostics) { + // Make sure to update the delivered map. s.delivered[fileID.URI] = toSend continue } - // If we've already delivered diagnostics with analyses for this file, for this snapshot, - // at this version, do not send diagnostics without analyses. + + // If we've already delivered diagnostics for this file, at this + // snapshot, with analyses, do not send diagnostics without analyses. if delivered.snapshotID == toSend.snapshotID && delivered.version == toSend.version && delivered.withAnalysis && !toSend.withAnalysis { + // Do not update the delivered map since it already contains better diagnostics. continue } + if err := s.client.PublishDiagnostics(ctx, &protocol.PublishDiagnosticsParams{ Diagnostics: toProtocolDiagnostics(diagnostics), URI: protocol.NewURI(fileID.URI),