diff --git a/internal/lsp/debug/serve.go b/internal/lsp/debug/serve.go index aec976ad6f..473518e433 100644 --- a/internal/lsp/debug/serve.go +++ b/internal/lsp/debug/serve.go @@ -181,6 +181,7 @@ type Client struct { Logfile string GoplsPath string ServerID string + Service protocol.Server } // A Server is an outgoing connection to a remote LSP server. @@ -314,6 +315,16 @@ func (i *Instance) getInfo(r *http.Request) interface{} { return template.HTML(buf.String()) } +func (i *Instance) AddService(s protocol.Server, session *cache.Session) { + for _, c := range i.State.clients { + if c.Session == session { + c.Service = s + return + } + } + stdlog.Printf("unable to find a Client to add the protocol.Server to") +} + func getMemory(r *http.Request) interface{} { var m runtime.MemStats runtime.ReadMemStats(&m) @@ -785,6 +796,29 @@ Using session: {{template "sessionlink" .Session.ID}}
{{if .DebugAddress}}Debug this client at: {{localAddress .DebugAddress}}
{{end}} Logfile: {{.Logfile}}
Gopls Path: {{.GoplsPath}}
+

Diagnostics

+{{/*Service: []protocol.Server; each server has map[uri]fileReports; + each fileReport: map[diagnosticSoure]diagnosticReport + diagnosticSource is one of 5 source + diagnosticReport: snapshotID and map[hash]*source.Diagnostic + sourceDiagnostic: struct { + Range protocol.Range + Message string + Source string + Code string + CodeHref string + Severity protocol.DiagnosticSeverity + Tags []protocol.DiagnosticTag + + Related []RelatedInformation + } + RelatedInformation: struct { + URI span.URI + Range protocol.Range + Message string + } + */}} + {{end}} `)) diff --git a/internal/lsp/diagnostics.go b/internal/lsp/diagnostics.go index 4941f007ea..adf19ad86d 100644 --- a/internal/lsp/diagnostics.go +++ b/internal/lsp/diagnostics.go @@ -50,6 +50,23 @@ type fileReports struct { reports map[diagnosticSource]diagnosticReport } +func (d diagnosticSource) String() string { + switch d { + case modSource: + return "FromSource" + case gcDetailsSource: + return "FromGCDetails" + case analysisSource: + return "FromAnalysis" + case typeCheckSource: + return "FromTypeChecking" + case orphanedSource: + return "FromOrphans" + default: + return fmt.Sprintf("From?%d?", d) + } +} + // hashDiagnostics computes a hash to identify diags. func hashDiagnostics(diags ...*source.Diagnostic) string { source.SortDiagnostics(diags) @@ -546,3 +563,34 @@ func (s *Server) shouldIgnoreError(ctx context.Context, snapshot source.Snapshot }) return !hasGo } + +// Diagnostics formattedfor the debug server +// (all the relevant fields of Server are private) +// (The alternative is to export them) +func (s *Server) Diagnostics() map[string][]string { + ans := make(map[string][]string) + s.diagnosticsMu.Lock() + defer s.diagnosticsMu.Unlock() + for k, v := range s.diagnostics { + fn := k.Filename() + for typ, d := range v.reports { + if len(d.diags) == 0 { + continue + } + for _, dx := range d.diags { + ans[fn] = append(ans[fn], auxStr(dx, d, typ)) + } + } + } + return ans +} + +func auxStr(v *source.Diagnostic, d diagnosticReport, typ diagnosticSource) string { + // Tags? RelatedInformation? + msg := fmt.Sprintf("(%s)%q(source:%q,code:%q,severity:%s,snapshot:%d,type:%s)", + v.Range, v.Message, v.Source, v.Code, v.Severity, d.snapshotID, typ) + for _, r := range v.Related { + msg += fmt.Sprintf(" [%s:%s,%q]", r.URI.Filename(), r.Range, r.Message) + } + return msg +} diff --git a/internal/lsp/lsprpc/lsprpc.go b/internal/lsp/lsprpc/lsprpc.go index 623533f22a..51267910cf 100644 --- a/internal/lsp/lsprpc/lsprpc.go +++ b/internal/lsp/lsprpc/lsprpc.go @@ -61,6 +61,7 @@ func (s *StreamServer) ServeStream(ctx context.Context, conn jsonrpc2.Conn) erro server := s.serverForTest if server == nil { server = lsp.NewServer(session, client) + debug.GetInstance(ctx).AddService(server, session) } // Clients may or may not send a shutdown message. Make sure the server is // shut down.