Skip to content

Commit 9ac413f

Browse files
authored
LSP fix IR file state (#4119)
1 parent 4212b78 commit 9ac413f

File tree

2 files changed

+26
-21
lines changed

2 files changed

+26
-21
lines changed

private/buf/buflsp/file.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import (
4040
"github.com/bufbuild/protocompile/experimental/ir"
4141
"github.com/bufbuild/protocompile/experimental/report"
4242
"github.com/bufbuild/protocompile/experimental/seq"
43+
"github.com/bufbuild/protocompile/experimental/source"
4344
"go.lsp.dev/protocol"
4445
)
4546

@@ -243,11 +244,20 @@ func (f *file) RefreshIR(ctx context.Context) {
243244
slog.Int("version", int(f.version)),
244245
)
245246

246-
files := xslices.MapValuesToSlice(f.workspace.PathToFile())
247+
// Opener creates a cached view of all files in the workspace.
248+
pathToFiles := f.workspace.PathToFile()
249+
files := make([]*file, 0, len(pathToFiles))
250+
openerMap := make(map[string]string, len(pathToFiles))
251+
for path, file := range pathToFiles {
252+
openerMap[path] = file.file.Text()
253+
files = append(files, file)
254+
}
255+
opener := source.NewMap(openerMap)
256+
247257
session := new(ir.Session)
248258
queries := xslices.Map(files, func(file *file) incremental.Query[ir.File] {
249259
return queries.IR{
250-
Opener: f.workspace,
260+
Opener: opener,
251261
Path: file.objectInfo.Path(),
252262
Session: session,
253263
}

private/buf/buflsp/workspace.go

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ package buflsp
1717
import (
1818
"context"
1919
"fmt"
20-
"io/fs"
2120
"iter"
2221
"log/slog"
2322

@@ -139,11 +138,13 @@ type workspace struct {
139138

140139
// Lease increments the reference count.
141140
func (w *workspace) Lease() {
141+
w.lsp.logger.Debug("workspace: lease", slog.String("path", w.workspaceURI.Filename()))
142142
w.refCount++
143143
}
144144

145145
// Release decrements the reference count.
146146
func (w *workspace) Release() int {
147+
w.lsp.logger.Debug("workspace: release", slog.String("path", w.workspaceURI.Filename()))
147148
w.refCount--
148149
return w.refCount
149150
}
@@ -228,18 +229,6 @@ func (w *workspace) CheckClient() bufcheck.Client {
228229
return w.checkClient
229230
}
230231

231-
// Open implements [github.com/bufbuild/protocompile/experimental/source.Opener].
232-
func (w *workspace) Open(path string) (string, error) {
233-
if w.workspace == nil {
234-
return "", fs.ErrNotExist
235-
}
236-
file, ok := w.pathToFile[path]
237-
if !ok {
238-
return "", fs.ErrNotExist
239-
}
240-
return file.file.Text(), nil
241-
}
242-
243232
// PathToFile is an index of all files within the workspace.
244233
func (w *workspace) PathToFile() map[string]*file {
245234
if w == nil {
@@ -250,12 +239,17 @@ func (w *workspace) PathToFile() map[string]*file {
250239

251240
// indexFiles builds the pathToFile mapping.
252241
func (w *workspace) indexFiles(ctx context.Context) {
253-
unused := w.pathToFile
254-
w.pathToFile = make(map[string]*file, len(unused))
242+
w.lsp.logger.Debug("workspace: index files", slog.String("path", w.workspaceURI.Filename()))
243+
previous := w.pathToFile
244+
w.pathToFile = make(map[string]*file, len(previous))
255245

256246
for fileInfo := range w.fileInfos(ctx) {
257-
fileURI := uri.File(fileInfo.LocalPath())
258-
file := w.lsp.fileManager.Track(fileURI)
247+
file, ok := previous[fileInfo.Path()]
248+
if !ok {
249+
fileURI := uri.File(fileInfo.LocalPath())
250+
file = w.lsp.fileManager.Track(fileURI)
251+
w.lsp.logger.Debug("workspace: index track file", slog.String("path", file.uri.Filename()))
252+
}
259253

260254
// Currently we only associate a file with one workspace. This assumption isn't accurate
261255
// for shared dependencies. Here we update to the lastest, most recently used, workspace.
@@ -277,10 +271,11 @@ func (w *workspace) indexFiles(ctx context.Context) {
277271

278272
// Update index.
279273
w.pathToFile[fileInfo.Path()] = file
280-
delete(unused, fileInfo.Path())
274+
delete(previous, fileInfo.Path())
281275
}
282276
// Drop all unused files. It was deleted from the workspace.
283-
for _, file := range unused {
277+
for _, file := range previous {
278+
w.lsp.logger.Debug("workspace: index drop file", slog.String("path", file.uri.Filename()))
284279
file.Close(ctx)
285280
}
286281
}

0 commit comments

Comments
 (0)