Skip to content

Commit 9dce7c1

Browse files
committed
Revert "gopls/internal/server: rewrite the server diagnostic tracking"
This reverts commit 184d2a7. Reason for revert: Seems to have caused some flakes. Fixes golang/go#64533 Fixes golang/go#64532 Change-Id: I76ffd07ebca405aed2b111668c97923b578563f8 Reviewed-on: https://go-review.googlesource.com/c/tools/+/546855 Reviewed-by: Bryan Mills <[email protected]> Auto-Submit: Robert Findley <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent c8cb6a3 commit 9dce7c1

File tree

9 files changed

+409
-288
lines changed

9 files changed

+409
-288
lines changed

gopls/internal/debug/serve.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,29 @@ Using session: <b>{{template "sessionlink" .Session.ID}}</b><br>
791791
{{if .DebugAddress}}Debug this client at: <a href="http://{{localAddress .DebugAddress}}">{{localAddress .DebugAddress}}</a><br>{{end}}
792792
Logfile: {{.Logfile}}<br>
793793
Gopls Path: {{.GoplsPath}}<br>
794+
<h2>Diagnostics</h2>
795+
{{/*Service: []protocol.Server; each server has map[uri]fileReports;
796+
each fileReport: map[diagnosticSoure]diagnosticReport
797+
diagnosticSource is one of 5 source
798+
diagnosticReport: snapshotID and map[hash]*source.Diagnostic
799+
sourceDiagnostic: struct {
800+
Range protocol.Range
801+
Message string
802+
Source string
803+
Code string
804+
CodeHref string
805+
Severity protocol.DiagnosticSeverity
806+
Tags []protocol.DiagnosticTag
807+
808+
Related []RelatedInformation
809+
}
810+
RelatedInformation: struct {
811+
URI protocol.DocumentURI
812+
Range protocol.Range
813+
Message string
814+
}
815+
*/}}
816+
<ul>{{range $k, $v := .Service.Diagnostics}}<li>{{$k}}:<ol>{{range $v}}<li>{{.}}</li>{{end}}</ol></li>{{end}}</ul>
794817
{{end}}
795818
`))
796819

gopls/internal/lsp/cache/session.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ func (s *Session) createView(ctx context.Context, def *viewDefinition, folder *F
187187

188188
v.snapshot = &Snapshot{
189189
sequenceID: seqID,
190+
globalID: nextSnapshotID(),
190191
view: v,
191192
backgroundCtx: backgroundCtx,
192193
cancel: cancel,

gopls/internal/lsp/cache/snapshot.go

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ import (
5555
"golang.org/x/tools/internal/typesinternal"
5656
)
5757

58+
// A GlobalSnapshotID uniquely identifies a snapshot within this process and
59+
// increases monotonically with snapshot creation time.
60+
//
61+
// We use a distinct integral type for global IDs to help enforce correct
62+
// usage.
63+
//
64+
// TODO(rfindley): remove this as it should not be necessary for correctness.
65+
type GlobalSnapshotID uint64
66+
5867
// A Snapshot represents the current state for a given view.
5968
//
6069
// It is first and foremost an idempotent implementation of file.Source whose
@@ -68,6 +77,7 @@ import (
6877
// implemented in Snapshot.clone.
6978
type Snapshot struct {
7079
sequenceID uint64
80+
globalID GlobalSnapshotID
7181

7282
// TODO(rfindley): the snapshot holding a reference to the view poses
7383
// lifecycle problems: a view may be shut down and waiting for work
@@ -192,6 +202,12 @@ type Snapshot struct {
192202
gcOptimizationDetails map[metadata.PackageID]unit
193203
}
194204

205+
var globalSnapshotID uint64
206+
207+
func nextSnapshotID() GlobalSnapshotID {
208+
return GlobalSnapshotID(atomic.AddUint64(&globalSnapshotID, 1))
209+
}
210+
195211
var _ memoize.RefCounted = (*Snapshot)(nil) // snapshots are reference-counted
196212

197213
// Acquire prevents the snapshot from being destroyed until the returned function is called.
@@ -206,7 +222,7 @@ var _ memoize.RefCounted = (*Snapshot)(nil) // snapshots are reference-counted
206222
func (s *Snapshot) Acquire() func() {
207223
type uP = unsafe.Pointer
208224
if destroyedBy := atomic.LoadPointer((*uP)(uP(&s.destroyedBy))); destroyedBy != nil {
209-
log.Panicf("%s:%d: acquire() after Destroy(%q)", s.view.id, s.sequenceID, *(*string)(destroyedBy))
225+
log.Panicf("%d: acquire() after Destroy(%q)", s.globalID, *(*string)(destroyedBy))
210226
}
211227
s.refcount.Add(1)
212228
return s.refcount.Done
@@ -245,7 +261,7 @@ func (s *Snapshot) destroy(destroyedBy string) {
245261
// Not foolproof: another thread could acquire() at this moment.
246262
type uP = unsafe.Pointer // looking forward to generics...
247263
if old := atomic.SwapPointer((*uP)(uP(&s.destroyedBy)), uP(&destroyedBy)); old != nil {
248-
log.Panicf("%s:%d: Destroy(%q) after Destroy(%q)", s.view.id, s.sequenceID, destroyedBy, *(*string)(old))
264+
log.Panicf("%d: Destroy(%q) after Destroy(%q)", s.globalID, destroyedBy, *(*string)(old))
249265
}
250266

251267
s.packages.Destroy()
@@ -273,6 +289,13 @@ func (s *Snapshot) SequenceID() uint64 {
273289
return s.sequenceID
274290
}
275291

292+
// GlobalID is a globally unique identifier for this snapshot. Global IDs are
293+
// monotonic: subsequent snapshots will have higher global ID, though
294+
// subsequent snapshots in a view may not have adjacent global IDs.
295+
func (s *Snapshot) GlobalID() GlobalSnapshotID {
296+
return s.globalID
297+
}
298+
276299
// SnapshotLabels returns a new slice of labels that should be used for events
277300
// related to a snapshot.
278301
func (s *Snapshot) Labels() []label.Label {
@@ -1929,6 +1952,7 @@ func (s *Snapshot) clone(ctx, bgCtx context.Context, changed StateChange) (*Snap
19291952
bgCtx, cancel := context.WithCancel(bgCtx)
19301953
result := &Snapshot{
19311954
sequenceID: s.sequenceID + 1,
1955+
globalID: nextSnapshotID(),
19321956
store: s.store,
19331957
view: s.view,
19341958
backgroundCtx: bgCtx,

gopls/internal/lsp/source/util.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"go/token"
1212
"go/types"
1313
"regexp"
14+
"sort"
1415
"strings"
1516

1617
"golang.org/x/tools/gopls/internal/lsp/cache"
@@ -138,6 +139,31 @@ func Deref(typ types.Type) types.Type {
138139
}
139140
}
140141

142+
func SortDiagnostics(d []*cache.Diagnostic) {
143+
sort.Slice(d, func(i int, j int) bool {
144+
return CompareDiagnostic(d[i], d[j]) < 0
145+
})
146+
}
147+
148+
func CompareDiagnostic(a, b *cache.Diagnostic) int {
149+
if r := protocol.CompareRange(a.Range, b.Range); r != 0 {
150+
return r
151+
}
152+
if a.Source < b.Source {
153+
return -1
154+
}
155+
if a.Source > b.Source {
156+
return +1
157+
}
158+
if a.Message < b.Message {
159+
return -1
160+
}
161+
if a.Message > b.Message {
162+
return +1
163+
}
164+
return 0
165+
}
166+
141167
// findFileInDeps finds package metadata containing URI in the transitive
142168
// dependencies of m. When using the Go command, the answer is unique.
143169
//

gopls/internal/server/code_action.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,8 @@ func (s *server) findMatchingDiagnostics(uri protocol.DocumentURI, pd protocol.D
286286
defer s.diagnosticsMu.Unlock()
287287

288288
var sds []*cache.Diagnostic
289-
for _, viewDiags := range s.diagnostics[uri].byView {
290-
for _, sd := range viewDiags.diagnostics {
289+
for _, report := range s.diagnostics[uri].reports {
290+
for _, sd := range report.diags {
291291
sameDiagnostic := (pd.Message == strings.TrimSpace(sd.Message) && // extra space may have been trimmed when converting to protocol.Diagnostic
292292
protocol.CompareRange(pd.Range, sd.Range) == 0 &&
293293
pd.Source == string(sd.Source))

0 commit comments

Comments
 (0)