Skip to content

Commit e286d22

Browse files
committed
gopls/internal/lsp: eliminate diagnoseDetached
There is no reason to diagnose on a detached context. If the snapshot background context is cancelled, it is either because the view is shut down (and so we don't care about the results) or a subsequent snapshot has been created. In the latter case, any results that may be published using the detached context could be inaccurate, and we must overwrite them with the later snapshot anyway. Instead, use the diagnoseSnapshot helper, which runs on the snapshot background context. In order to avoid unnecessary delay, lift the delay value used in this method to the callsites. This should also speed up go.mod related custom commands that were unnecessarily incurring the delay. Change-Id: I648e9ebcffb027efc76b74ca38354b9ad99da6e7 Reviewed-on: https://go-review.googlesource.com/c/tools/+/487137 gopls-CI: kokoro <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Robert Findley <[email protected]> Reviewed-by: Alan Donovan <[email protected]>
1 parent 4e3238a commit e286d22

File tree

4 files changed

+17
-21
lines changed

4 files changed

+17
-21
lines changed

gopls/internal/lsp/command.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ func (c *commandHandler) CheckUpgrades(ctx context.Context, args command.CheckUp
205205
}
206206
deps.snapshot.View().RegisterModuleUpgrades(args.URI.SpanURI(), upgrades)
207207
// Re-diagnose the snapshot to publish the new module diagnostics.
208-
c.s.diagnoseSnapshot(deps.snapshot, nil, false)
208+
c.s.diagnoseSnapshot(deps.snapshot, nil, false, 0)
209209
return nil
210210
})
211211
}
@@ -236,7 +236,7 @@ func (c *commandHandler) ResetGoModDiagnostics(ctx context.Context, args command
236236
}
237237

238238
// Re-diagnose the snapshot to remove the diagnostics.
239-
c.s.diagnoseSnapshot(deps.snapshot, nil, false)
239+
c.s.diagnoseSnapshot(deps.snapshot, nil, false, 0)
240240
return nil
241241
})
242242
}
@@ -713,7 +713,7 @@ func (c *commandHandler) ToggleGCDetails(ctx context.Context, args command.URIAr
713713
c.s.gcOptimizationDetails[meta.ID] = struct{}{}
714714
}
715715
c.s.gcOptimizationDetailsMu.Unlock()
716-
c.s.diagnoseSnapshot(deps.snapshot, nil, false)
716+
c.s.diagnoseSnapshot(deps.snapshot, nil, false, 0)
717717
return nil
718718
})
719719
}
@@ -914,7 +914,7 @@ func (c *commandHandler) RunGovulncheck(ctx context.Context, args command.Vulnch
914914
result.AsOf = time.Now()
915915
deps.snapshot.View().SetVulnerabilities(args.URI.SpanURI(), &result)
916916

917-
c.s.diagnoseSnapshot(deps.snapshot, nil, false)
917+
c.s.diagnoseSnapshot(deps.snapshot, nil, false, 0)
918918
vulns := result.Vulns
919919
affecting := make([]string, 0, len(vulns))
920920
for _, v := range vulns {

gopls/internal/lsp/diagnostics.go

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import (
2424
"golang.org/x/tools/internal/bug"
2525
"golang.org/x/tools/internal/event"
2626
"golang.org/x/tools/internal/event/tag"
27-
"golang.org/x/tools/internal/xcontext"
2827
)
2928

3029
// TODO(rfindley): simplify this very complicated logic for publishing
@@ -150,34 +149,31 @@ func computeDiagnosticHash(diags ...*source.Diagnostic) string {
150149
return fmt.Sprintf("%x", h.Sum(nil))
151150
}
152151

153-
// TODO(rfindley): is diagnoseDetached even necessary? We should always
154-
// eventually diagnose after a change. I don't see the value in ensuring that
155-
// the first diagnostics pass completes.
156-
func (s *Server) diagnoseDetached(snapshot source.Snapshot) {
157-
ctx := snapshot.BackgroundContext()
158-
ctx = xcontext.Detach(ctx)
159-
s.diagnose(ctx, snapshot, analyzeOpenPackages)
160-
s.publishDiagnostics(ctx, true, snapshot)
161-
}
162-
163152
func (s *Server) diagnoseSnapshots(snapshots map[source.Snapshot][]span.URI, onDisk bool) {
164153
var diagnosticWG sync.WaitGroup
165154
for snapshot, uris := range snapshots {
166155
diagnosticWG.Add(1)
167156
go func(snapshot source.Snapshot, uris []span.URI) {
168157
defer diagnosticWG.Done()
169-
s.diagnoseSnapshot(snapshot, uris, onDisk)
158+
s.diagnoseSnapshot(snapshot, uris, onDisk, snapshot.View().Options().DiagnosticsDelay)
170159
}(snapshot, uris)
171160
}
172161
diagnosticWG.Wait()
173162
}
174163

175-
func (s *Server) diagnoseSnapshot(snapshot source.Snapshot, changedURIs []span.URI, onDisk bool) {
164+
// diagnoseSnapshot computes and publishes diagnostics for the given snapshot.
165+
//
166+
// If delay is non-zero, computing diagnostics does not start until after this
167+
// delay has expired, to allow work to be cancelled by subsequent changes.
168+
//
169+
// If changedURIs is non-empty, it is a set of recently changed files that
170+
// should be diagnosed immediately, and onDisk reports whether these file
171+
// changes came from a change to on-disk files.
172+
func (s *Server) diagnoseSnapshot(snapshot source.Snapshot, changedURIs []span.URI, onDisk bool, delay time.Duration) {
176173
ctx := snapshot.BackgroundContext()
177174
ctx, done := event.Start(ctx, "Server.diagnoseSnapshot", source.SnapshotLabels(snapshot)...)
178175
defer done()
179176

180-
delay := snapshot.View().Options().DiagnosticsDelay
181177
if delay > 0 {
182178
// 2-phase diagnostics.
183179
//

gopls/internal/lsp/general.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ func (s *Server) addFolders(ctx context.Context, folders []protocol.WorkspaceFol
362362
// Diagnose the newly created view asynchronously.
363363
ndiagnose.Add(1)
364364
go func() {
365-
s.diagnoseDetached(snapshot)
365+
s.diagnoseSnapshot(snapshot, nil, false, 0)
366366
<-initialized
367367
release()
368368
ndiagnose.Done()
@@ -625,7 +625,7 @@ func (s *Server) exit(ctx context.Context) error {
625625
// TODO: We should be able to do better than this.
626626
os.Exit(1)
627627
}
628-
// we don't terminate the process on a normal exit, we just allow it to
628+
// We don't terminate the process on a normal exit, we just allow it to
629629
// close naturally if needed after the connection is closed.
630630
return nil
631631
}

gopls/internal/lsp/workspace.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func (s *Server) didChangeConfiguration(ctx context.Context, _ *protocol.DidChan
7171
return // view is shut down; no need to diagnose
7272
}
7373
defer release()
74-
s.diagnoseDetached(snapshot)
74+
s.diagnoseSnapshot(snapshot, nil, false, 0)
7575
}()
7676
}
7777

0 commit comments

Comments
 (0)