Skip to content

Commit 3d1db9e

Browse files
authored
LSP only refresh workspace on open/save (#4121)
1 parent 14cc304 commit 3d1db9e

File tree

3 files changed

+19
-52
lines changed

3 files changed

+19
-52
lines changed

private/buf/buflsp/file.go

Lines changed: 17 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -89,13 +89,15 @@ func (f *file) Manager() *fileManager {
8989
return f.lsp.fileManager
9090
}
9191

92-
// Reset clears all bookkeeping information on this file.
92+
// Reset clears all bookkeeping information on this file and resets it.
9393
func (f *file) Reset(ctx context.Context) {
9494
f.lsp.logger.DebugContext(ctx, "resetting file", slog.String("uri", f.uri.Filename()))
95-
96-
f.ir = ir.File{}
97-
f.diagnostics = nil
98-
f.symbols = nil
95+
if f.workspace != nil {
96+
f.workspace.Release()
97+
f.workspace = nil
98+
}
99+
// Clear the file as nothing should use it after reset. This asserts that.
100+
*f = file{}
99101
}
100102

101103
// Close marks a file as closed.
@@ -104,10 +106,6 @@ func (f *file) Reset(ctx context.Context) {
104106
// for this file.
105107
func (f *file) Close(ctx context.Context) {
106108
f.Manager().Close(ctx, f.uri)
107-
if f.workspace != nil {
108-
f.workspace.Release()
109-
f.workspace = nil
110-
}
111109
}
112110

113111
// IsOpenInEditor returns whether this file was opened in the LSP client's
@@ -159,46 +157,23 @@ func (f *file) ReadFromWorkspace(ctx context.Context) (err error) {
159157
// Update updates the contents of this file with the given text received from
160158
// the LSP client.
161159
func (f *file) Update(ctx context.Context, version int32, text string) {
162-
f.Reset(ctx)
163-
f.CancelChecks(ctx)
164-
165160
f.lsp.logger.InfoContext(ctx, "file updated", slog.String("uri", f.uri.Filename()), slog.Int("old_version", int(f.version)), slog.Int("new_version", int(version)))
166161
f.version = version
167162
f.file = report.NewFile(f.uri.Filename(), text)
168163
f.hasText = true
169-
}
170-
171-
// Refresh rebuilds all of a file's internal book-keeping.
172-
func (f *file) Refresh(ctx context.Context) {
173-
var progress *progress
174-
if f.IsOpenInEditor() {
175-
// NOTE: Nil progress does nothing when methods are called. This helps
176-
// minimize RPC spam from the client when indexing lots of files.
177-
progress = newProgress(f.lsp)
178-
}
179-
progress.Begin(ctx, "Indexing")
180-
181-
progress.Report(ctx, "Setting workspace", 1.0/4)
182-
f.RefreshWorkspace(ctx)
183164

184-
progress.Report(ctx, "Parsing IR", 2.0/4)
165+
f.CancelChecks(ctx)
185166
f.RefreshIR(ctx)
186-
187-
progress.Report(ctx, "Indexing Symbols", 3.0/4)
188167
f.IndexSymbols(ctx)
189-
190-
progress.Report(ctx, "Running Checks", 4.0/4)
191168
f.RunChecks(ctx)
192169

193-
progress.Done(ctx)
194-
195170
// NOTE: Diagnostics are published unconditionally. This is necessary even
196171
// if we have zero diagnostics, so that the client correctly ticks over from
197172
// n > 0 diagnostics to 0 diagnostics.
198173
f.PublishDiagnostics(ctx)
199174
}
200175

201-
// RefreshWorkspace builds the workspace for the current file and sets the workspace it.
176+
// RefreshWorkspace rebuilds the workspace for the current file and sets the workspace.
202177
//
203178
// The Buf workspace provides the sources for the compiler to work with.
204179
func (f *file) RefreshWorkspace(ctx context.Context) {
@@ -232,13 +207,15 @@ func (f *file) RefreshWorkspace(ctx context.Context) {
232207
// RefreshIR queries for the IR of the file and the IR of each import file.
233208
// Diagnostics from the compiler are returned when applicable.
234209
//
235-
// This operation requires IndexImports.
210+
// This operation requires a workspace.
236211
func (f *file) RefreshIR(ctx context.Context) {
237212
f.lsp.logger.Info(
238213
"parsing IR for file",
239214
slog.String("uri", string(f.uri)),
240215
slog.Int("version", int(f.version)),
241216
)
217+
f.diagnostics = nil
218+
f.ir = ir.File{}
242219

243220
// Opener creates a cached view of all files in the workspace.
244221
pathToFiles := f.workspace.PathToFile()
@@ -320,7 +297,9 @@ func (f *file) IndexSymbols(ctx context.Context) {
320297
f.referenceableSymbols = make(map[string]*symbol)
321298

322299
// Process all imports as symbols
323-
f.symbols = xslices.Map(seq.ToSlice(f.ir.Imports()), f.importToSymbol)
300+
for imp := range seq.Values(f.ir.Imports()) {
301+
f.symbols = append(f.symbols, f.importToSymbol(imp))
302+
}
324303

325304
resolved, unresolved := f.indexSymbols()
326305
f.symbols = append(f.symbols, resolved...)
@@ -706,14 +685,14 @@ func (f *file) RunChecks(ctx context.Context) {
706685
}
707686
f.CancelChecks(ctx)
708687

709-
path := f.objectInfo.Path()
710688
workspace := f.workspace.Workspace()
711689
module := f.workspace.GetModule(f.uri)
712690
checkClient := f.workspace.CheckClient()
713-
if workspace == nil || module == nil || checkClient == nil {
691+
if workspace == nil || module == nil || checkClient == nil || f.objectInfo == nil {
714692
f.lsp.logger.Debug("checks skipped", slog.String("uri", f.uri.Filename()))
715693
return
716694
}
695+
path := f.objectInfo.Path()
717696

718697
opener := make(fileOpener)
719698
for path, file := range f.workspace.PathToFile() {

private/buf/buflsp/progress.go

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ package buflsp
1616

1717
import (
1818
"context"
19-
"fmt"
20-
"math/rand/v2"
2119

2220
"go.lsp.dev/protocol"
2321
)
@@ -31,14 +29,6 @@ type progress struct {
3129
token string
3230
}
3331

34-
// Creates new server-initiated progress.
35-
func newProgress(lsp *lsp) *progress {
36-
return &progress{
37-
lsp: lsp,
38-
token: fmt.Sprintf("%016x", rand.Uint64()),
39-
}
40-
}
41-
4232
// Creates progress to track client-initiated progress.
4333
//
4434
// If params is nil (i.e., the client doesn't want progress) this returns a nil progress
@@ -47,7 +37,6 @@ func newProgressFromClient(lsp *lsp, params *protocol.WorkDoneProgressParams) *p
4737
if params == nil || params.WorkDoneToken == nil {
4838
return nil
4939
}
50-
5140
return &progress{
5241
lsp: lsp,
5342
token: params.WorkDoneToken.String(),

private/buf/buflsp/server.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,8 @@ func (s *server) DidOpen(
198198
params *protocol.DidOpenTextDocumentParams,
199199
) error {
200200
file := s.fileManager.Track(params.TextDocument.URI)
201+
file.RefreshWorkspace(ctx)
201202
file.Update(ctx, params.TextDocument.Version, params.TextDocument.Text)
202-
file.Refresh(ctx)
203203
return nil
204204
}
205205

@@ -216,7 +216,6 @@ func (s *server) DidChange(
216216
}
217217

218218
file.Update(ctx, params.TextDocument.Version, params.ContentChanges[0].Text)
219-
file.Refresh(ctx)
220219
return nil
221220
}
222221

@@ -232,7 +231,7 @@ func (s *server) DidSave(
232231
// Update for a file we don't know about? Seems bad!
233232
return fmt.Errorf("received update for file that was not open: %q", params.TextDocument.URI)
234233
}
235-
file.Refresh(ctx)
234+
file.RefreshWorkspace(ctx)
236235
return nil
237236
}
238237

0 commit comments

Comments
 (0)