mirror of https://github.com/golang/go.git
internal/lsp: display current diagnostics in the debug server
The change displays outstanding diagnostics on the Client page of the debug server. Very occasionally gopls displays incorrect diagnostics or diagnositics that won't go away. It is possible that providing more complete information will help us find the causes, at least when the debug server is running. Change-Id: I01f2bbbfeac86e7296f57f4a9aad8e1e658babfa Reviewed-on: https://go-review.googlesource.com/c/tools/+/285252 Run-TryBot: Peter Weinberger <pjw@google.com> gopls-CI: kokoro <noreply+kokoro@google.com> TryBot-Result: Go Bot <gobot@golang.org> Trust: Peter Weinberger <pjw@google.com> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
cf1022a4b0
commit
e13398c87d
|
|
@ -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: <b>{{template "sessionlink" .Session.ID}}</b><br>
|
|||
{{if .DebugAddress}}Debug this client at: <a href="http://{{localAddress .DebugAddress}}">{{localAddress .DebugAddress}}</a><br>{{end}}
|
||||
Logfile: {{.Logfile}}<br>
|
||||
Gopls Path: {{.GoplsPath}}<br>
|
||||
<h2>Diagnostics</h2>
|
||||
{{/*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
|
||||
}
|
||||
*/}}
|
||||
<ul>{{range $k, $v := .Service.Diagnostics}}<li>{{$k}}:<ol>{{range $v}}<li>{{.}}</li>{{end}}</ol></li>{{end}}</ul>
|
||||
{{end}}
|
||||
`))
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in New Issue