on main help sign in
fix(lsp): return a copy of lsp diagnostics to avoid data race (#681)
f8da476Liiiz
internal/llm/tools/diagnostics.go+1−3
@@ -5,7 +5,6 @@ import (
5 "encoding/json"
5 "encoding/json"
6 "fmt"
6 "fmt"
7 "log/slog"
7 "log/slog"
8− "maps"
9 "sort"
8 "sort"
10 "strings"
9 "strings"
11 "time"
10 "time"
@@ -109,8 +108,7 @@ func waitForLspDiagnostics(ctx context.Context, filePath string, lsps map[string
109 diagChan := make(chan struct{}, 1)
108 diagChan := make(chan struct{}, 1)
110
109
111 for _, client := range lsps {
110 for _, client := range lsps {
112− originalDiags := make(map[protocol.DocumentURI][]protocol.Diagnostic)
113− maps.Copy(originalDiags, client.GetDiagnostics())
111+ originalDiags := client.GetDiagnostics()
114
112
115 handler := func(params json.RawMessage) {
113 handler := func(params json.RawMessage) {
116 lsp.HandleDiagnostics(client, params)
114 lsp.HandleDiagnostics(client, params)
internal/lsp/client.go+5−1
@@ -7,6 +7,7 @@ import (
7 "fmt"
7 "fmt"
8 "io"
8 "io"
9 "log/slog"
9 "log/slog"
10+ "maps"
10 "os"
11 "os"
11 "os/exec"
12 "os/exec"
12 "path/filepath"
13 "path/filepath"
@@ -765,7 +766,10 @@ func (c *Client) GetFileDiagnostics(uri protocol.DocumentURI) []protocol.Diagnos
765
766
766// GetDiagnostics returns all diagnostics for all files
767// GetDiagnostics returns all diagnostics for all files
767func (c *Client) GetDiagnostics() map[protocol.DocumentURI][]protocol.Diagnostic {
768func (c *Client) GetDiagnostics() map[protocol.DocumentURI][]protocol.Diagnostic {
769+ c.diagnosticsMu.RLock()
770+ defer c.diagnosticsMu.RUnlock()
771+
768− return c.diagnostics
772+ return maps.Clone(c.diagnostics)
769}
773}
770
774
771// OpenFileOnDemand opens a file only if it's not already open
775// OpenFileOnDemand opens a file only if it's not already open