Skip to content

Commit 580942b

Browse files
committed
perf(lsp): avoid some clones
1 parent 1b288be commit 580942b

File tree

4 files changed

+63
-56
lines changed

4 files changed

+63
-56
lines changed

crates/oxc_language_server/src/backend.rs

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,10 @@ impl LanguageServer for Backend {
111111
let capabilities = Capabilities::from(params.capabilities);
112112

113113
// client sent workspace folders
114-
let workers = if let Some(workspace_folders) = &params.workspace_folders {
114+
let workers = if let Some(workspace_folders) = params.workspace_folders {
115115
workspace_folders
116-
.iter()
117-
.map(|workspace_folder| WorkspaceWorker::new(workspace_folder.uri.clone()))
116+
.into_iter()
117+
.map(|workspace_folder| WorkspaceWorker::new(workspace_folder.uri))
118118
.collect()
119119
// client sent deprecated root uri
120120
} else if let Some(root_uri) = params.root_uri {
@@ -130,8 +130,8 @@ impl LanguageServer for Backend {
130130
// we will init the linter after requesting for the workspace configuration.
131131
if !capabilities.workspace_configuration || options.is_some() {
132132
for worker in &workers {
133-
let option = &options
134-
.clone()
133+
let option = options
134+
.as_deref()
135135
.unwrap_or_default()
136136
.iter()
137137
.find(|workspace_option| {
@@ -140,7 +140,7 @@ impl LanguageServer for Backend {
140140
.map(|workspace_options| workspace_options.options.clone())
141141
.unwrap_or_default();
142142

143-
worker.start_worker(option.clone(), &self.tool_builders).await;
143+
worker.start_worker(option, &self.tool_builders).await;
144144
}
145145
}
146146

@@ -319,11 +319,11 @@ impl LanguageServer for Backend {
319319

320320
// Only create WorkspaceOption when the config is Some
321321
configs
322-
.iter()
322+
.into_iter()
323323
.enumerate()
324-
.map(|(index, config)| WorkspaceOption {
324+
.map(|(index, options)| WorkspaceOption {
325325
workspace_uri: workers[index].get_root_uri().clone(),
326-
options: config.clone(),
326+
options,
327327
})
328328
.collect::<Vec<_>>()
329329
} else {
@@ -456,8 +456,8 @@ impl LanguageServer for Backend {
456456
)
457457
.await;
458458

459-
for (index, folder) in params.event.added.iter().enumerate() {
460-
let worker = WorkspaceWorker::new(folder.uri.clone());
459+
for (index, folder) in params.event.added.into_iter().enumerate() {
460+
let worker = WorkspaceWorker::new(folder.uri);
461461
// get the configuration from the response and init the linter
462462
let options = configurations.get(index).unwrap_or(&serde_json::Value::Null);
463463
worker.start_worker(options.clone(), &self.tool_builders).await;
@@ -498,36 +498,36 @@ impl LanguageServer for Backend {
498498
/// See: <https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_didSave>
499499
async fn did_save(&self, params: DidSaveTextDocumentParams) {
500500
debug!("oxc server did save");
501-
let uri = &params.text_document.uri;
501+
let uri = params.text_document.uri;
502502
let workers = self.workspace_workers.read().await;
503-
let Some(worker) = workers.iter().find(|worker| worker.is_responsible_for_uri(uri)) else {
503+
let Some(worker) = workers.iter().find(|worker| worker.is_responsible_for_uri(&uri)) else {
504504
return;
505505
};
506506

507-
if let Some(diagnostics) = worker.run_diagnostic_on_save(uri, params.text.as_deref()).await
507+
if let Some(diagnostics) = worker.run_diagnostic_on_save(&uri, params.text.as_deref()).await
508508
{
509-
self.client.publish_diagnostics(uri.clone(), diagnostics, None).await;
509+
self.client.publish_diagnostics(uri, diagnostics, None).await;
510510
}
511511
}
512512
/// It will update the in-memory file content if the client supports dynamic formatting.
513513
/// It will re-lint the file and send updated diagnostics, if necessary.
514514
///
515515
/// See: <https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_didChange>
516516
async fn did_change(&self, params: DidChangeTextDocumentParams) {
517-
let uri = &params.text_document.uri;
517+
let uri = params.text_document.uri;
518518
let workers = self.workspace_workers.read().await;
519-
let Some(worker) = workers.iter().find(|worker| worker.is_responsible_for_uri(uri)) else {
519+
let Some(worker) = workers.iter().find(|worker| worker.is_responsible_for_uri(&uri)) else {
520520
return;
521521
};
522522
let content = params.content_changes.first().map(|c| c.text.clone());
523523

524524
if let Some(content) = &content {
525-
self.file_system.write().await.set(uri, content.clone());
525+
self.file_system.write().await.set(&uri, content.clone());
526526
}
527527

528-
if let Some(diagnostics) = worker.run_diagnostic_on_change(uri, content.as_deref()).await {
528+
if let Some(diagnostics) = worker.run_diagnostic_on_change(&uri, content.as_deref()).await {
529529
self.client
530-
.publish_diagnostics(uri.clone(), diagnostics, Some(params.text_document.version))
530+
.publish_diagnostics(uri, diagnostics, Some(params.text_document.version))
531531
.await;
532532
}
533533
}
@@ -537,19 +537,19 @@ impl LanguageServer for Backend {
537537
///
538538
/// See: <https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_didOpen>
539539
async fn did_open(&self, params: DidOpenTextDocumentParams) {
540-
let uri = &params.text_document.uri;
540+
let uri = params.text_document.uri;
541541
let workers = self.workspace_workers.read().await;
542-
let Some(worker) = workers.iter().find(|worker| worker.is_responsible_for_uri(uri)) else {
542+
let Some(worker) = workers.iter().find(|worker| worker.is_responsible_for_uri(&uri)) else {
543543
return;
544544
};
545545

546546
let content = params.text_document.text;
547547

548-
self.file_system.write().await.set(uri, content.clone());
548+
self.file_system.write().await.set(&uri, content.clone());
549549

550-
if let Some(diagnostics) = worker.run_diagnostic(uri, Some(&content)).await {
550+
if let Some(diagnostics) = worker.run_diagnostic(&uri, Some(&content)).await {
551551
self.client
552-
.publish_diagnostics(uri.clone(), diagnostics, Some(params.text_document.version))
552+
.publish_diagnostics(uri, diagnostics, Some(params.text_document.version))
553553
.await;
554554
}
555555
}

crates/oxc_language_server/src/linter/code_actions.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,19 @@ pub const CODE_ACTION_KIND_SOURCE_FIX_ALL_OXC: CodeActionKind =
77
CodeActionKind::new("source.fixAll.oxc");
88

99
fn fix_content_to_code_action(
10-
fixed_content: &FixedContent,
11-
uri: &Uri,
10+
fixed_content: FixedContent,
11+
uri: Uri,
1212
is_preferred: bool,
1313
) -> CodeAction {
1414
CodeAction {
15-
title: fixed_content.message.clone(),
15+
title: fixed_content.message,
1616
kind: Some(CodeActionKind::QUICKFIX),
1717
is_preferred: Some(is_preferred),
1818
edit: Some(WorkspaceEdit {
1919
#[expect(clippy::disallowed_types)]
2020
changes: Some(std::collections::HashMap::from([(
21-
uri.clone(),
22-
vec![TextEdit { range: fixed_content.range, new_text: fixed_content.code.clone() }],
21+
uri,
22+
vec![TextEdit { range: fixed_content.range, new_text: fixed_content.code }],
2323
)])),
2424
..WorkspaceEdit::default()
2525
}),
@@ -30,13 +30,13 @@ fn fix_content_to_code_action(
3030
}
3131
}
3232

33-
pub fn apply_fix_code_actions(action: &LinterCodeAction, uri: &Uri) -> Vec<CodeAction> {
33+
pub fn apply_fix_code_actions(action: LinterCodeAction, uri: &Uri) -> Vec<CodeAction> {
3434
let mut code_actions = vec![];
3535

3636
// only the first code action is preferred
3737
let mut preferred = true;
38-
for fixed in &action.fixed_content {
39-
let action = fix_content_to_code_action(fixed, uri, preferred);
38+
for fixed in action.fixed_content {
39+
let action = fix_content_to_code_action(fixed, uri.clone(), preferred);
4040
preferred = false;
4141
code_actions.push(action);
4242
}
@@ -46,7 +46,7 @@ pub fn apply_fix_code_actions(action: &LinterCodeAction, uri: &Uri) -> Vec<CodeA
4646

4747
pub fn apply_all_fix_code_action(
4848
actions: impl Iterator<Item = LinterCodeAction>,
49-
uri: &Uri,
49+
uri: Uri,
5050
) -> Option<CodeAction> {
5151
let quick_fixes: Vec<TextEdit> = fix_all_text_edit(actions);
5252

@@ -60,7 +60,7 @@ pub fn apply_all_fix_code_action(
6060
is_preferred: Some(true),
6161
edit: Some(WorkspaceEdit {
6262
#[expect(clippy::disallowed_types)]
63-
changes: Some(std::collections::HashMap::from([(uri.clone(), quick_fixes)])),
63+
changes: Some(std::collections::HashMap::from([(uri, quick_fixes)])),
6464
..WorkspaceEdit::default()
6565
}),
6666
disabled: None,
@@ -98,8 +98,11 @@ pub fn fix_all_text_edit(actions: impl Iterator<Item = LinterCodeAction>) -> Vec
9898
// and return them as one workspace edit.
9999
// it is possible that one fix will change the range for the next fix
100100
// see oxc-project/oxc#10422
101-
text_edits
102-
.push(TextEdit { range: fixed_content.range, new_text: fixed_content.code.clone() });
101+
text_edits.push(TextEdit {
102+
range: fixed_content.range,
103+
// TODO: avoid cloning here
104+
new_text: fixed_content.code.clone(),
105+
});
103106
}
104107

105108
text_edits

crates/oxc_language_server/src/linter/server_linter.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ impl ServerLinterBuilder {
8383

8484
// TODO(refactor): pull this into a shared function, because in oxlint we have the same functionality.
8585
let use_nested_config = options.use_nested_configs();
86-
let fix_kind = FixKind::from(options.fix_kind.clone());
86+
let fix_kind = FixKind::from(options.fix_kind);
8787

8888
let use_cross_module = config_builder.plugins().has_import()
8989
|| (use_nested_config
@@ -124,7 +124,7 @@ impl ServerLinterBuilder {
124124
&IsolatedLintHandlerOptions {
125125
use_cross_module,
126126
type_aware: options.type_aware,
127-
fix_kind: FixKind::from(options.fix_kind.clone()),
127+
fix_kind,
128128
root_path: root_path.to_path_buf(),
129129
tsconfig_path: options.ts_config_path.as_ref().map(|path| {
130130
let path = Path::new(path).to_path_buf();
@@ -428,13 +428,13 @@ impl Tool for ServerLinter {
428428
}
429429

430430
let args = FixAllCommandArgs::try_from(arguments).map_err(|_| ErrorCode::InvalidParams)?;
431-
let uri = &Uri::from_str(&args.uri).map_err(|_| ErrorCode::InvalidParams)?;
431+
let uri = Uri::from_str(&args.uri).map_err(|_| ErrorCode::InvalidParams)?;
432432

433-
if !self.is_responsible_for_uri(uri) {
433+
if !self.is_responsible_for_uri(&uri) {
434434
return Ok(None);
435435
}
436436

437-
let actions = self.get_code_actions_for_uri(uri);
437+
let actions = self.get_code_actions_for_uri(&uri);
438438

439439
let Some(actions) = actions else {
440440
return Ok(None);
@@ -448,7 +448,7 @@ impl Tool for ServerLinter {
448448

449449
Ok(Some(WorkspaceEdit {
450450
#[expect(clippy::disallowed_types)]
451-
changes: Some(std::collections::HashMap::from([(uri.clone(), text_edits)])),
451+
changes: Some(std::collections::HashMap::from([(uri, text_edits)])),
452452
document_changes: None,
453453
change_annotations: None,
454454
}))
@@ -476,15 +476,16 @@ impl Tool for ServerLinter {
476476
.is_some_and(|only| only.contains(&CODE_ACTION_KIND_SOURCE_FIX_ALL_OXC));
477477

478478
if is_source_fix_all_oxc {
479-
return apply_all_fix_code_action(actions, uri).map_or(vec![], |code_actions| {
480-
vec![CodeActionOrCommand::CodeAction(code_actions)]
481-
});
479+
return apply_all_fix_code_action(actions, uri.clone())
480+
.map_or(vec![], |code_actions| {
481+
vec![CodeActionOrCommand::CodeAction(code_actions)]
482+
});
482483
}
483484

484485
let mut code_actions_vec: Vec<CodeActionOrCommand> = vec![];
485486

486487
for action in actions {
487-
let fix_actions = apply_fix_code_actions(&action, uri);
488+
let fix_actions = apply_fix_code_actions(action, uri);
488489
code_actions_vec.extend(fix_actions.into_iter().map(CodeActionOrCommand::CodeAction));
489490
}
490491

crates/oxc_language_server/src/worker.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -264,19 +264,22 @@ impl WorkspaceWorker {
264264
"
265265
);
266266

267+
let result = self
268+
.handle_tool_changes(file_system, |tool| {
269+
tool.handle_configuration_change(
270+
&self.root_uri,
271+
&old_options,
272+
changed_options_json.clone(),
273+
)
274+
})
275+
.await;
276+
267277
{
268278
let mut options_guard = self.options.lock().await;
269-
*options_guard = Some(changed_options_json.clone());
279+
*options_guard = Some(changed_options_json);
270280
}
271281

272-
self.handle_tool_changes(file_system, |tool| {
273-
tool.handle_configuration_change(
274-
&self.root_uri,
275-
&old_options,
276-
changed_options_json.clone(),
277-
)
278-
})
279-
.await
282+
result
280283
}
281284

282285
/// Common implementation for handling tool changes that may result in

0 commit comments

Comments
 (0)