Skip to content

Commit 5abbd3e

Browse files
committed
refactor(language_server): split ServerFormatter creation with *Builder pattern (#15283)
1 parent 5f81e63 commit 5abbd3e

File tree

2 files changed

+77
-55
lines changed

2 files changed

+77
-55
lines changed

crates/oxc_language_server/src/formatter/server_formatter.rs

Lines changed: 67 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,78 @@ use tower_lsp_server::{
1515

1616
use crate::formatter::options::FormatOptions as LSPFormatOptions;
1717
use crate::{FORMAT_CONFIG_FILES, utils::normalize_path};
18+
19+
pub struct ServerFormatterBuilder {
20+
root_uri: Uri,
21+
options: LSPFormatOptions,
22+
}
23+
24+
impl ServerFormatterBuilder {
25+
pub fn new(root_uri: Uri, options: LSPFormatOptions) -> Self {
26+
Self { root_uri, options }
27+
}
28+
29+
pub fn build(self) -> ServerFormatter {
30+
let root_path = self.root_uri.to_file_path().unwrap();
31+
32+
ServerFormatter::new(Self::get_format_options(
33+
&root_path,
34+
self.options.config_path.as_ref(),
35+
))
36+
}
37+
38+
fn get_format_options(root_path: &Path, config_path: Option<&String>) -> FormatOptions {
39+
let oxfmtrc = if let Some(config) = Self::search_config_file(root_path, config_path) {
40+
if let Ok(oxfmtrc) = Oxfmtrc::from_file(&config) {
41+
oxfmtrc
42+
} else {
43+
warn!("Failed to initialize oxfmtrc config: {}", config.to_string_lossy());
44+
Oxfmtrc::default()
45+
}
46+
} else {
47+
warn!(
48+
"Config file not found: {}, fallback to default config",
49+
config_path.unwrap_or(&FORMAT_CONFIG_FILES.join(", "))
50+
);
51+
Oxfmtrc::default()
52+
};
53+
54+
match oxfmtrc.into_format_options() {
55+
Ok(options) => options,
56+
Err(err) => {
57+
warn!("Failed to parse oxfmtrc config: {err}, fallback to default config");
58+
FormatOptions::default()
59+
}
60+
}
61+
}
62+
63+
fn search_config_file(root_path: &Path, config_path: Option<&String>) -> Option<PathBuf> {
64+
if let Some(config_path) = config_path {
65+
let config = normalize_path(root_path.join(config_path));
66+
if config.try_exists().is_ok_and(|exists| exists) {
67+
return Some(config);
68+
}
69+
70+
warn!(
71+
"Config file not found: {}, searching for `{}` in the root path",
72+
config.to_string_lossy(),
73+
FORMAT_CONFIG_FILES.join(", ")
74+
);
75+
}
76+
77+
FORMAT_CONFIG_FILES.iter().find_map(|&file| {
78+
let config = normalize_path(root_path.join(file));
79+
config.try_exists().is_ok_and(|exists| exists).then_some(config)
80+
})
81+
}
82+
}
1883
pub struct ServerFormatter {
1984
options: FormatOptions,
2085
}
2186

2287
impl ServerFormatter {
23-
pub fn new(root_uri: &Uri, options: &LSPFormatOptions) -> Self {
24-
let root_path = root_uri.to_file_path().unwrap();
25-
26-
Self { options: Self::get_format_options(&root_path, options.config_path.as_ref()) }
88+
pub fn new(options: FormatOptions) -> Self {
89+
Self { options }
2790
}
2891

2992
pub fn run_single(&self, uri: &Uri, content: Option<String>) -> Option<Vec<TextEdit>> {
@@ -71,51 +134,6 @@ impl ServerFormatter {
71134
)])
72135
}
73136

74-
fn search_config_file(root_path: &Path, config_path: Option<&String>) -> Option<PathBuf> {
75-
if let Some(config_path) = config_path {
76-
let config = normalize_path(root_path.join(config_path));
77-
if config.try_exists().is_ok_and(|exists| exists) {
78-
return Some(config);
79-
}
80-
81-
warn!(
82-
"Config file not found: {}, searching for `{}` in the root path",
83-
config.to_string_lossy(),
84-
FORMAT_CONFIG_FILES.join(", ")
85-
);
86-
}
87-
88-
FORMAT_CONFIG_FILES.iter().find_map(|&file| {
89-
let config = normalize_path(root_path.join(file));
90-
config.try_exists().is_ok_and(|exists| exists).then_some(config)
91-
})
92-
}
93-
94-
fn get_format_options(root_path: &Path, config_path: Option<&String>) -> FormatOptions {
95-
let oxfmtrc = if let Some(config) = Self::search_config_file(root_path, config_path) {
96-
if let Ok(oxfmtrc) = Oxfmtrc::from_file(&config) {
97-
oxfmtrc
98-
} else {
99-
warn!("Failed to initialize oxfmtrc config: {}", config.to_string_lossy());
100-
Oxfmtrc::default()
101-
}
102-
} else {
103-
warn!(
104-
"Config file not found: {}, fallback to default config",
105-
config_path.unwrap_or(&FORMAT_CONFIG_FILES.join(", "))
106-
);
107-
Oxfmtrc::default()
108-
};
109-
110-
match oxfmtrc.into_format_options() {
111-
Ok(options) => options,
112-
Err(err) => {
113-
warn!("Failed to parse oxfmtrc config: {err}, fallback to default config");
114-
FormatOptions::default()
115-
}
116-
}
117-
}
118-
119137
#[expect(clippy::unused_self)]
120138
pub fn get_watcher_patterns(&self, options: &LSPFormatOptions) -> Vec<Pattern> {
121139
if let Some(config_path) = options.config_path.as_ref() {

crates/oxc_language_server/src/worker.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ use tower_lsp_server::{
1212

1313
use crate::{
1414
code_actions::{apply_all_fix_code_action, apply_fix_code_actions, fix_all_text_edit},
15-
formatter::{options::FormatOptions, server_formatter::ServerFormatter},
15+
formatter::{
16+
options::FormatOptions,
17+
server_formatter::{ServerFormatter, ServerFormatterBuilder},
18+
},
1619
linter::{
1720
error_with_position::DiagnosticReport,
1821
options::{LintOptions, Run},
@@ -80,7 +83,7 @@ impl WorkspaceWorker {
8083
if options.format.experimental {
8184
debug!("experimental formatter enabled");
8285
*self.server_formatter.write().await =
83-
Some(ServerFormatter::new(&self.root_uri, &options.format));
86+
Some(ServerFormatterBuilder::new(self.root_uri.clone(), options.format).build());
8487
}
8588
}
8689

@@ -186,8 +189,9 @@ impl WorkspaceWorker {
186189
/// Restart the server formatter with the current options
187190
/// This will recreate the formatter and re-read the config files.
188191
/// Call this when the options have changed and the formatter needs to be updated.
189-
async fn refresh_server_formatter(&self, format_options: &FormatOptions) {
190-
let server_formatter = ServerFormatter::new(&self.root_uri, format_options);
192+
async fn refresh_server_formatter(&self, format_options: FormatOptions) {
193+
let server_formatter =
194+
ServerFormatterBuilder::new(self.root_uri.clone(), format_options).build();
191195

192196
*self.server_formatter.write().await = Some(server_formatter);
193197
}
@@ -347,7 +351,7 @@ impl WorkspaceWorker {
347351

348352
if options.format.experimental {
349353
tokio::join!(
350-
self.refresh_server_formatter(&options.format),
354+
self.refresh_server_formatter(options.format),
351355
self.refresh_server_linter(options.lint)
352356
);
353357
} else {
@@ -404,7 +408,7 @@ impl WorkspaceWorker {
404408

405409
if current_option.format != changed_options.format {
406410
if changed_options.format.experimental {
407-
self.refresh_server_formatter(&changed_options.format).await;
411+
self.refresh_server_formatter(changed_options.format.clone()).await;
408412
formatting = true;
409413

410414
// Extract pattern data without holding the lock

0 commit comments

Comments
 (0)