-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
lsp: Update contents before diagnosticRequestFile #1100
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -119,9 +119,8 @@ type LanguageServer struct { | |
|
||
// fileUpdateEvent is sent to a channel when an update is required for a file. | ||
type fileUpdateEvent struct { | ||
Reason string | ||
URI string | ||
Content string | ||
Reason string | ||
URI string | ||
} | ||
|
||
func (l *LanguageServer) Handle( | ||
|
@@ -216,9 +215,11 @@ func (l *LanguageServer) StartDiagnosticsWorker(ctx context.Context) { | |
case <-ctx.Done(): | ||
return | ||
case evt := <-l.diagnosticRequestFile: | ||
err := l.processTextContentUpdate(ctx, evt.URI, evt.Content) | ||
// updateParse will not return an error when the parsing failed, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. processTextContentUpdate has been removed and inlined here. |
||
// but only when it was impossible | ||
_, err := updateParse(ctx, l.cache, l.regoStore, evt.URI) | ||
if err != nil { | ||
l.logError(fmt.Errorf("failed to process text content update: %w", err)) | ||
l.logError(fmt.Errorf("failed to update module for %s: %w", evt.URI, err)) | ||
|
||
continue | ||
} | ||
|
@@ -227,11 +228,15 @@ func (l *LanguageServer) StartDiagnosticsWorker(ctx context.Context) { | |
err = updateFileDiagnostics(ctx, l.cache, l.loadedConfig, evt.URI, l.workspaceRootURI) | ||
if err != nil { | ||
l.logError(fmt.Errorf("failed to update file diagnostics: %w", err)) | ||
|
||
continue | ||
} | ||
|
||
err = l.sendFileDiagnostics(ctx, evt.URI) | ||
if err != nil { | ||
l.logError(fmt.Errorf("failed to send diagnostic: %w", err)) | ||
|
||
continue | ||
} | ||
|
||
// if the file has agg diagnostics, we trigger a run for the workspace as by changing this file, | ||
|
@@ -264,9 +269,42 @@ func (l *LanguageServer) StartHoverWorker(ctx context.Context) { | |
case <-ctx.Done(): | ||
return | ||
case evt := <-l.builtinsPositionFile: | ||
err := l.processHoverContentUpdate(ctx, evt.URI, evt.Content) | ||
fileURI := evt.URI | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. processHoverContentUpdate has also been inlined here. |
||
|
||
if l.ignoreURI(fileURI) { | ||
continue | ||
} | ||
|
||
if _, ok := l.cache.GetFileContents(fileURI); !ok { | ||
// If the file is not in the cache, exit early or else | ||
// we might accidentally put it in the cache after it's been | ||
// deleted: https://github.com/StyraInc/regal/issues/679 | ||
continue | ||
} | ||
|
||
success, err := updateParse(ctx, l.cache, l.regoStore, fileURI) | ||
if err != nil { | ||
l.logError(fmt.Errorf("failed to update parse: %w", err)) | ||
|
||
continue | ||
} | ||
|
||
if !success { | ||
continue | ||
} | ||
|
||
err = hover.UpdateBuiltinPositions(l.cache, fileURI) | ||
if err != nil { | ||
l.logError(fmt.Errorf("failed to update builtin positions: %w", err)) | ||
|
||
continue | ||
} | ||
|
||
err = hover.UpdateKeywordLocations(ctx, l.cache, fileURI) | ||
if err != nil { | ||
l.logError(fmt.Errorf("failed to process builtin and keyword positions update: %w", err)) | ||
l.logError(fmt.Errorf("failed to update keyword positions: %w", err)) | ||
|
||
continue | ||
} | ||
} | ||
} | ||
|
@@ -817,9 +855,8 @@ func (l *LanguageServer) StartTemplateWorker(ctx context.Context) { | |
|
||
// finally, trigger a diagnostics run for the new file | ||
updateEvent := fileUpdateEvent{ | ||
Reason: "internal/templateNewFile", | ||
URI: fileURI, | ||
Content: newContents, | ||
Reason: "internal/templateNewFile", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The actual issue this fixes was triggered by Where an empty update was sent causing the cache's state to be set to blank for files when they were detected as new, despite them first having their contents loaded from disk. |
||
URI: fileURI, | ||
} | ||
|
||
l.diagnosticRequestFile <- updateEvent | ||
|
@@ -1020,33 +1057,6 @@ func (l *LanguageServer) fixRenameParams( | |
}, nil | ||
} | ||
|
||
// processTextContentUpdate updates the cache with the new content for the file at the given URI, attempts to parse the | ||
// file, and returns whether the parse was successful. If it was not successful, the parse errors will be sent | ||
// on the diagnostic channel. | ||
func (l *LanguageServer) processTextContentUpdate( | ||
ctx context.Context, | ||
fileURI string, | ||
content string, | ||
) error { | ||
if l.ignoreURI(fileURI) { | ||
return nil | ||
} | ||
|
||
currentContent, ok := l.cache.GetFileContents(fileURI) | ||
if ok && currentContent == content { | ||
return nil | ||
} | ||
|
||
l.cache.SetFileContents(fileURI, content) | ||
|
||
_, err := updateParse(ctx, l.cache, l.regoStore, fileURI) | ||
if err != nil { | ||
return fmt.Errorf("failed to update parse: %w", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// processHoverContentUpdate updates information about built in, and keyword | ||
// positions in the cache for use when handling hover requests. | ||
func (l *LanguageServer) processHoverContentUpdate(ctx context.Context, fileURI string, content string) error { | ||
|
@@ -1642,10 +1652,11 @@ func (l *LanguageServer) handleTextDocumentDidOpen( | |
return struct{}{}, nil | ||
} | ||
|
||
l.cache.SetFileContents(params.TextDocument.URI, params.TextDocument.Text) | ||
|
||
evt := fileUpdateEvent{ | ||
Reason: "textDocument/didOpen", | ||
URI: params.TextDocument.URI, | ||
Content: params.TextDocument.Text, | ||
Reason: "textDocument/didOpen", | ||
URI: params.TextDocument.URI, | ||
} | ||
|
||
l.diagnosticRequestFile <- evt | ||
|
@@ -1699,10 +1710,15 @@ func (l *LanguageServer) handleTextDocumentDidChange( | |
return struct{}{}, nil | ||
} | ||
|
||
if len(params.ContentChanges) < 1 { | ||
return struct{}{}, nil | ||
} | ||
|
||
l.cache.SetFileContents(params.TextDocument.URI, params.ContentChanges[0].Text) | ||
|
||
evt := fileUpdateEvent{ | ||
Reason: "textDocument/didChange", | ||
URI: params.TextDocument.URI, | ||
Content: params.ContentChanges[0].Text, | ||
Reason: "textDocument/didChange", | ||
URI: params.TextDocument.URI, | ||
} | ||
|
||
l.diagnosticRequestFile <- evt | ||
|
@@ -1844,10 +1860,11 @@ func (l *LanguageServer) handleTextDocumentFormatting( | |
|
||
l.cache.ClearFileDiagnostics() | ||
|
||
l.cache.SetFileContents(params.TextDocument.URI, newContent) | ||
|
||
updateEvent := fileUpdateEvent{ | ||
Reason: "internal/templateFormattingFallback", | ||
URI: params.TextDocument.URI, | ||
Content: newContent, | ||
Reason: "internal/templateFormattingFallback", | ||
URI: params.TextDocument.URI, | ||
} | ||
|
||
l.diagnosticRequestFile <- updateEvent | ||
|
@@ -2056,9 +2073,8 @@ func (l *LanguageServer) handleWorkspaceDidRenameFiles( | |
l.cache.SetFileContents(renameOp.NewURI, content) | ||
|
||
evt := fileUpdateEvent{ | ||
Reason: "textDocument/didRename", | ||
URI: renameOp.NewURI, | ||
Content: content, | ||
Reason: "textDocument/didRename", | ||
URI: renameOp.NewURI, | ||
} | ||
|
||
l.diagnosticRequestFile <- evt | ||
|
@@ -2238,7 +2254,18 @@ func (l *LanguageServer) loadWorkspaceContents(ctx context.Context, newOnly bool | |
} | ||
|
||
// if the caller has requested only new files, then we can exit early | ||
if _, ok := l.cache.GetFileContents(fileURI); newOnly && ok { | ||
if contents, ok := l.cache.GetFileContents(fileURI); newOnly && ok { | ||
diskContents, err := os.ReadFile(fileURI) | ||
if err != nil { | ||
// then there is nothing we can do here | ||
return nil | ||
} | ||
|
||
if string(diskContents) == "" && contents == "" { | ||
// then there is nothing to be gained from loading from disk | ||
return nil | ||
} | ||
|
||
return nil | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has been removed so it's no longer possible to send fileUpdateEvents with no content, this reduces the responsibility on the diagnostics worker. Now it can just update parses and send diagnostics.