Skip to content

Commit ed23cf1

Browse files
committed
docs(language_server): docs for WorkspaceWorker
1 parent d36d227 commit ed23cf1

File tree

1 file changed

+47
-2
lines changed

1 file changed

+47
-2
lines changed

crates/oxc_language_server/src/worker.rs

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ use crate::{
2424
options::Options,
2525
};
2626

27+
/// A worker that manages the individual tools for a specific workspace
28+
/// and reports back the results to the [`Backend`](crate::backend::Backend).
29+
///
30+
/// Each worker is responsible for a specific root URI and configures the tools `cwd` to that root URI.
31+
/// The [`Backend`](crate::backend::Backend) is responsible to target the correct worker for a given file URI.
2732
pub struct WorkspaceWorker {
2833
root_uri: Uri,
2934
server_linter: RwLock<Option<ServerLinter>>,
@@ -32,6 +37,9 @@ pub struct WorkspaceWorker {
3237
}
3338

3439
impl WorkspaceWorker {
40+
/// Create a new workspace worker.
41+
/// This will not start any programs, use [`start_worker`](Self::start_worker) for that.
42+
/// Depending on the client, we need to request the workspace configuration in `initialized.
3543
pub fn new(root_uri: Uri) -> Self {
3644
Self {
3745
root_uri,
@@ -41,17 +49,25 @@ impl WorkspaceWorker {
4149
}
4250
}
4351

52+
/// Get the root URI of the worker
4453
pub fn get_root_uri(&self) -> &Uri {
4554
&self.root_uri
4655
}
4756

57+
/// Check if the worker is responsible for the given URI
58+
/// A worker is responsible for a URI if the URI is a file URI and is located within the root URI of the worker
59+
/// e.g. root URI: file:///path/to/root
60+
/// responsible for: file:///path/to/root/file.js
61+
/// not responsible for: file:///path/to/other/file.js
4862
pub fn is_responsible_for_uri(&self, uri: &Uri) -> bool {
4963
if let Some(path) = uri.to_file_path() {
5064
return path.starts_with(self.root_uri.to_file_path().unwrap());
5165
}
5266
false
5367
}
5468

69+
/// Start all programs (linter, formatter) for the worker.
70+
/// This should be called after the client has sent the workspace configuration.
5571
pub async fn start_worker(&self, options: &Options) {
5672
*self.options.lock().await = Some(options.clone());
5773

@@ -62,8 +78,9 @@ impl WorkspaceWorker {
6278
}
6379
}
6480

65-
// WARNING: start all programs (linter, formatter) before calling this function
66-
// each program can tell us customized file watcher patterns
81+
/// Initialize file system watchers for the workspace.
82+
/// These watchers are used to watch for changes in the lint configuration files.
83+
/// The returned watchers will be registered to the client.
6784
pub async fn init_watchers(&self) -> Vec<FileSystemWatcher> {
6885
let mut watchers = Vec::new();
6986

@@ -91,6 +108,7 @@ impl WorkspaceWorker {
91108
return watchers;
92109
};
93110

111+
// Add watchers for all extended config paths of the current linter
94112
let Some(extended_paths) =
95113
self.server_linter.read().await.as_ref().map(|linter| linter.extended_paths.clone())
96114
else {
@@ -117,6 +135,7 @@ impl WorkspaceWorker {
117135
watchers
118136
}
119137

138+
/// Check if the worker needs to be initialized with options
120139
pub async fn needs_init_options(&self) -> bool {
121140
self.options.lock().await.is_none()
122141
}
@@ -125,6 +144,7 @@ impl WorkspaceWorker {
125144
self.server_formatter.read().await.is_some()
126145
}
127146

147+
/// Remove all diagnostics for the given URI
128148
pub async fn remove_diagnostics(&self, uri: &Uri) {
129149
let server_linter_guard = self.server_linter.read().await;
130150
let Some(server_linter) = server_linter_guard.as_ref() else {
@@ -133,6 +153,9 @@ impl WorkspaceWorker {
133153
server_linter.remove_diagnostics(uri);
134154
}
135155

156+
/// Refresh the server linter with the current options
157+
/// This will recreate the linter and re-read the config files.
158+
/// Call this when the options have changed and the linter needs to be updated.
136159
async fn refresh_server_linter(&self) {
137160
let options = self.options.lock().await;
138161
let default_options = Options::default();
@@ -142,6 +165,9 @@ impl WorkspaceWorker {
142165
*self.server_linter.write().await = Some(server_linter);
143166
}
144167

168+
/// Lint a file with the current linter
169+
/// - If the file is not lintable, [`None`] is returned
170+
/// - If the file is lintable, but no diagnostics are found, an empty vector is returned
145171
pub async fn lint_file(
146172
&self,
147173
uri: &Uri,
@@ -155,6 +181,9 @@ impl WorkspaceWorker {
155181
server_linter.run_single(uri, content, run_type).await
156182
}
157183

184+
/// Format a file with the current formatter
185+
/// - If no formatter is active, [`None`] is returned
186+
/// - If the formatter is active, but no changes are made, an empty vector is returned
158187
pub async fn format_file(&self, uri: &Uri, content: Option<String>) -> Option<Vec<TextEdit>> {
159188
let Some(server_formatter) = &*self.server_formatter.read().await else {
160189
return None;
@@ -163,6 +192,8 @@ impl WorkspaceWorker {
163192
server_formatter.run_single(uri, content)
164193
}
165194

195+
/// Revalidate diagnostics for the given URIs
196+
/// This will re-lint all opened files and return the new diagnostics
166197
async fn revalidate_diagnostics(
167198
&self,
168199
uris: Vec<Uri>,
@@ -174,6 +205,13 @@ impl WorkspaceWorker {
174205
server_linter.revalidate_diagnostics(uris).await
175206
}
176207

208+
/// Get all clear diagnostics for the current workspace
209+
/// This should be called when:
210+
/// - The linter is disabled (not currently implemented)
211+
/// - The workspace is closed
212+
/// - The server is shut down
213+
///
214+
/// This will return a list of URIs that had diagnostics before, each with an empty diagnostics list
177215
pub async fn get_clear_diagnostics(&self) -> Vec<(String, Vec<Diagnostic>)> {
178216
self.server_linter
179217
.read()
@@ -189,6 +227,9 @@ impl WorkspaceWorker {
189227
.unwrap_or_default()
190228
}
191229

230+
/// Get code actions or commands for the given range
231+
/// It uses the [`ServerLinter`] cached diagnostics if available, otherwise it will lint the file
232+
/// If `is_source_fix_all_oxc` is true, it will return a single code action that applies all fixes
192233
pub async fn get_code_actions_or_commands(
193234
&self,
194235
uri: &Uri,
@@ -290,6 +331,9 @@ impl WorkspaceWorker {
290331
text_edits
291332
}
292333

334+
/// Handle file changes that are watched by the client
335+
/// At the moment, this only handles changes to lint configuration files
336+
/// When a change is detected, the linter is refreshed and all diagnostics are revalidated
293337
pub async fn did_change_watched_files(
294338
&self,
295339
_file_event: &FileEvent,
@@ -303,6 +347,7 @@ impl WorkspaceWorker {
303347
Some(self.revalidate_diagnostics(files).await)
304348
}
305349

350+
/// Handle server configuration changes from the client
306351
pub async fn did_change_configuration(
307352
&self,
308353
changed_options: &Options,

0 commit comments

Comments
 (0)