Skip to content

Commit f43fd18

Browse files
committed
refactor(language_server): move the initialization of ServerLinter into a separate call (#10776)
1 parent 39e0463 commit f43fd18

File tree

3 files changed

+35
-19
lines changed

3 files changed

+35
-19
lines changed

crates/oxc_language_server/src/main.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,10 @@ impl LanguageServer for Backend {
9191

9292
// ToDo: add support for multiple workspace folders
9393
// maybe fallback when the client does not support it
94-
let root_worker =
95-
WorkspaceWorker::new(&params.root_uri.unwrap(), options.clone().unwrap_or_default());
94+
let root_worker = WorkspaceWorker::new(&params.root_uri.unwrap());
95+
// ToDo: only call init_linter when the client passed a valid Options struct
96+
// if not and the client supports `workspace/configuration`, we should request them in `initialized`
97+
root_worker.init_linter(&options.clone().unwrap_or_default()).await;
9698

9799
*self.workspace_workers.lock().await = vec![root_worker];
98100

crates/oxc_language_server/src/tester.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,15 @@ impl Tester<'_> {
9696
Self { relative_root_dir, options }
9797
}
9898

99-
fn create_workspace_worker(&self) -> WorkspaceWorker {
99+
async fn create_workspace_worker(&self) -> WorkspaceWorker {
100100
let absolute_path = std::env::current_dir()
101101
.expect("could not get current dir")
102102
.join(self.relative_root_dir);
103103
let uri = Uri::from_file_path(absolute_path).expect("could not convert current dir to uri");
104-
WorkspaceWorker::new(&uri, self.options.clone().unwrap_or_default())
104+
let worker = WorkspaceWorker::new(&uri);
105+
worker.init_linter(&self.options.clone().unwrap_or_default()).await;
106+
107+
worker
105108
}
106109

107110
/// Given a relative file path (relative to `oxc_language_server` crate root), run the linter
@@ -111,6 +114,7 @@ impl Tester<'_> {
111114
let uri = get_file_uri(&format!("{}/{}", self.relative_root_dir, relative_file_path));
112115
let reports = tokio::runtime::Runtime::new().unwrap().block_on(async {
113116
self.create_workspace_worker()
117+
.await
114118
.lint_file(&uri, None)
115119
.await
116120
.expect("lint file is ignored")

crates/oxc_language_server/src/worker.rs

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,21 @@ use crate::{
1919

2020
pub struct WorkspaceWorker {
2121
root_uri: OnceCell<Uri>,
22-
server_linter: RwLock<ServerLinter>,
22+
server_linter: RwLock<Option<ServerLinter>>,
2323
diagnostics_report_map: RwLock<ConcurrentHashMap<String, Vec<DiagnosticReport>>>,
2424
options: Mutex<Options>,
2525
}
2626

2727
impl WorkspaceWorker {
28-
pub fn new(root_uri: &Uri, options: Options) -> Self {
28+
pub fn new(root_uri: &Uri) -> Self {
2929
let root_uri_cell = OnceCell::new();
3030
root_uri_cell.set(root_uri.clone()).unwrap();
3131

32-
let server_linter = ServerLinter::new(root_uri, &options);
3332
Self {
3433
root_uri: root_uri_cell,
35-
server_linter: RwLock::new(server_linter),
34+
server_linter: RwLock::new(None),
3635
diagnostics_report_map: RwLock::new(ConcurrentHashMap::default()),
37-
options: Mutex::new(options),
36+
options: Mutex::new(Options::default()),
3837
}
3938
}
4039

@@ -51,6 +50,12 @@ impl WorkspaceWorker {
5150
false
5251
}
5352

53+
pub async fn init_linter(&self, options: &Options) {
54+
*self.options.lock().await = options.clone();
55+
*self.server_linter.write().await =
56+
Some(ServerLinter::new(self.root_uri.get().unwrap(), options));
57+
}
58+
5459
pub async fn remove_diagnostics(&self, uri: &Uri) {
5560
self.diagnostics_report_map.read().await.pin().remove(&uri.to_string());
5661
}
@@ -59,7 +64,7 @@ impl WorkspaceWorker {
5964
let options = self.options.lock().await;
6065
let server_linter = ServerLinter::new(self.root_uri.get().unwrap(), &options);
6166

62-
*self.server_linter.write().await = server_linter;
67+
*self.server_linter.write().await = Some(server_linter);
6368
}
6469

6570
fn needs_linter_restart(old_options: &Options, new_options: &Options) -> bool {
@@ -93,7 +98,11 @@ impl WorkspaceWorker {
9398
uri: &Uri,
9499
content: Option<String>,
95100
) -> Option<Vec<DiagnosticReport>> {
96-
self.server_linter.read().await.run_single(uri, content)
101+
let Some(server_linter) = &*self.server_linter.read().await else {
102+
return None;
103+
};
104+
105+
server_linter.run_single(uri, content)
97106
}
98107

99108
async fn update_diagnostics(&self, uri: &Uri, diagnostics: &[DiagnosticReport]) {
@@ -109,9 +118,14 @@ impl WorkspaceWorker {
109118
self.diagnostics_report_map.read().await.len(),
110119
FxBuildHasher,
111120
);
112-
let linter = self.server_linter.read().await;
121+
let server_linter = self.server_linter.read().await;
122+
let Some(server_linter) = &*server_linter else {
123+
debug!("no server_linter initialized in the worker");
124+
return diagnostics_map;
125+
};
113126
for uri in self.diagnostics_report_map.read().await.pin().keys() {
114-
if let Some(diagnostics) = linter.run_single(&Uri::from_str(uri).unwrap(), None) {
127+
if let Some(diagnostics) = server_linter.run_single(&Uri::from_str(uri).unwrap(), None)
128+
{
115129
diagnostics_map.pin().insert(uri.clone(), diagnostics);
116130
}
117131
}
@@ -250,18 +264,14 @@ mod tests {
250264

251265
#[test]
252266
fn test_get_root_uri() {
253-
let worker =
254-
WorkspaceWorker::new(&Uri::from_str("file:///root/").unwrap(), Options::default());
267+
let worker = WorkspaceWorker::new(&Uri::from_str("file:///root/").unwrap());
255268

256269
assert_eq!(worker.get_root_uri(), Some(Uri::from_str("file:///root/").unwrap()));
257270
}
258271

259272
#[test]
260273
fn test_is_responsible() {
261-
let worker = WorkspaceWorker::new(
262-
&Uri::from_str("file:///path/to/root").unwrap(),
263-
Options::default(),
264-
);
274+
let worker = WorkspaceWorker::new(&Uri::from_str("file:///path/to/root").unwrap());
265275

266276
assert!(
267277
worker.is_responsible_for_uri(&Uri::from_str("file:///path/to/root/file.js").unwrap())

0 commit comments

Comments
 (0)