Skip to content

Commit

Permalink
feat: include Go compilation warnings and errors in the LSP diagnostics
Browse files Browse the repository at this point in the history
  • Loading branch information
a-h committed May 30, 2021
1 parent 8905c85 commit 5d9259a
Showing 1 changed file with 53 additions and 7 deletions.
60 changes: 53 additions & 7 deletions cmd/lspcmd/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,17 +84,26 @@ func (p *Proxy) sendToClient(r toClientRequest) {
func (p *Proxy) proxyFromGoplsToClient(ctx context.Context, conn *jsonrpc2.Conn, r *jsonrpc2.Request) {
p.log.Info("gopls -> client", zap.String("method", r.Method), zap.Bool("notif", r.Notif))
if r.Notif {
p.log.Info("gopls -> client: notification", zap.String("method", r.Method), zap.Bool("notif", r.Notif))
if r.Method == "window/showMessage" && p.shouldSuppressWindowShowMessage(r) {
var err error
switch r.Method {
case "window/showMessage":
if p.shouldSuppressWindowShowMessage(r) {
return
}
case "textDocument/publishDiagnostics":
err = p.rewriteGoplsPublishDiagnostics(r)
}
if err != nil {
p.log.Error("gopls -> client: error rewriting notification", zap.Error(err))
return
}
err := p.client.Notify(ctx, r.Method, r.Params)
err = p.client.Notify(ctx, r.Method, r.Params)
if err != nil {
p.log.Error("gopls to client: notification: send error", zap.Error(err))
p.log.Error("gopls -> client: notification: send error", zap.Error(err))
return
}
p.log.Info("gopls -> client: notification: complete")
} else {
p.log.Info("gopls -> client: call", zap.String("method", r.Method), zap.Bool("notif", r.Notif), zap.Any("params", r.Params))
var result map[string]interface{}
err := p.client.Call(ctx, r.Method, &r.Params, &result)
if err != nil {
Expand All @@ -118,6 +127,43 @@ func (p *Proxy) shouldSuppressWindowShowMessage(r *jsonrpc2.Request) (shouldIgno
return strings.HasPrefix(params.Message, "Do not edit this file!")
}

func (p *Proxy) rewriteGoplsPublishDiagnostics(r *jsonrpc2.Request) (err error) {
// Unmarshal the params.
var params lsp.PublishDiagnosticsParams
if err = json.Unmarshal(*r.Params, &params); err != nil {
return err
}
// Get the sourcemap from the cache.
uri := strings.TrimSuffix(string(params.URI), "_templ.go") + ".templ"
sourceMap, ok := p.sourceMapCache.Get(uri)
if !ok {
return fmt.Errorf("unable to complete because the sourcemap for %q doesn't exist in the cache, has the didOpen notification been sent yet?", uri)
}
params.URI = lsp.DocumentURI(uri)
// Rewrite the positions.
for i := 0; i < len(params.Diagnostics); i++ {
item := params.Diagnostics[i]
start, _, ok := sourceMap.SourcePositionFromTarget(item.Range.Start.Line+1, item.Range.Start.Character)
if ok {
item.Range.Start.Line = start.Line - 1
item.Range.Start.Character = start.Col + 1
}
end, _, ok := sourceMap.SourcePositionFromTarget(item.Range.End.Line+1, item.Range.End.Character)
if ok {
item.Range.End = templatePositionToLSPPosition(end)
}
params.Diagnostics[i] = item
}
// Marshal the params back.
jsonMessage, err := json.Marshal(params)
if err != nil {
return
}
err = r.Params.UnmarshalJSON(jsonMessage)
// Done.
return err
}

// Handle implements jsonrpc2.Handler. This function receives from the text editor client, and calls the proxy function
// to determine how to play it back to the client.
func (p *Proxy) Handle(ctx context.Context, conn *jsonrpc2.Conn, r *jsonrpc2.Request) {
Expand Down Expand Up @@ -231,7 +277,7 @@ func (p *Proxy) rewriteCompletionResponse(uri string, resp *lsp.CompletionList)
uri = strings.TrimSuffix(uri, "_templ.go") + ".templ"
sourceMap, ok := p.sourceMapCache.Get(uri)
if !ok {
return fmt.Errorf("unable to complete because the sourcemap doesn't exist in the cache, has the didOpen notification been sent yet?")
return fmt.Errorf("unable to complete because the sourcemap for %q doesn't exist in the cache, has the didOpen notification been sent yet?", uri)
}
// Rewrite the positions.
for i := 0; i < len(resp.Items); i++ {
Expand Down Expand Up @@ -263,7 +309,7 @@ func (p *Proxy) rewriteCompletionRequest(params *lsp.CompletionParams) (err erro
// Get the sourcemap from the cache.
sourceMap, ok := p.sourceMapCache.Get(string(params.TextDocument.URI))
if !ok {
return fmt.Errorf("unable to complete because the sourcemap doesn't exist in the cache, has the didOpen notification been sent yet?")
return fmt.Errorf("unable to complete because the sourcemap for %q doesn't exist in the cache, has the didOpen notification been sent yet?", params.TextDocument.URI)
}
// Map from the source position to target Go position.
to, mapping, ok := sourceMap.TargetPositionFromSource(params.Position.Line+1, params.Position.Character)
Expand Down

0 comments on commit 5d9259a

Please sign in to comment.