Skip to content

Commit 518e4d3

Browse files
authored
perf(lsp): store settings in Arc (denoland#24191)
1 parent d89ff73 commit 518e4d3

File tree

3 files changed

+68
-43
lines changed

3 files changed

+68
-43
lines changed

cli/lsp/config.rs

Lines changed: 52 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -722,8 +722,9 @@ impl WorkspaceSettings {
722722

723723
#[derive(Debug, Default, Clone)]
724724
pub struct Settings {
725-
pub unscoped: WorkspaceSettings,
726-
pub by_workspace_folder: BTreeMap<ModuleSpecifier, Option<WorkspaceSettings>>,
725+
pub unscoped: Arc<WorkspaceSettings>,
726+
pub by_workspace_folder:
727+
BTreeMap<ModuleSpecifier, Option<Arc<WorkspaceSettings>>>,
727728
pub first_folder: Option<ModuleSpecifier>,
728729
}
729730

@@ -815,9 +816,9 @@ impl Settings {
815816

816817
#[derive(Clone, Debug, Default)]
817818
pub struct Config {
818-
pub client_capabilities: ClientCapabilities,
819-
pub settings: Settings,
820-
pub workspace_folders: Vec<(ModuleSpecifier, lsp::WorkspaceFolder)>,
819+
pub client_capabilities: Arc<ClientCapabilities>,
820+
pub settings: Arc<Settings>,
821+
pub workspace_folders: Arc<Vec<(ModuleSpecifier, lsp::WorkspaceFolder)>>,
821822
pub tree: ConfigTree,
822823
}
823824

@@ -845,25 +846,33 @@ impl Config {
845846
&mut self,
846847
folders: Vec<(ModuleSpecifier, lsp::WorkspaceFolder)>,
847848
) {
848-
self.settings.by_workspace_folder =
849-
folders.iter().map(|(s, _)| (s.clone(), None)).collect();
850-
self.settings.first_folder = folders.first().map(|(s, _)| s.clone());
851-
self.workspace_folders = folders;
849+
self.settings = Arc::new(Settings {
850+
unscoped: self.settings.unscoped.clone(),
851+
by_workspace_folder: folders
852+
.iter()
853+
.map(|(s, _)| (s.clone(), None))
854+
.collect(),
855+
first_folder: folders.first().map(|(s, _)| s.clone()),
856+
});
857+
self.workspace_folders = Arc::new(folders);
852858
}
853859

854860
pub fn set_workspace_settings(
855861
&mut self,
856862
unscoped: WorkspaceSettings,
857863
folder_settings: Vec<(ModuleSpecifier, WorkspaceSettings)>,
858864
) {
859-
self.settings.unscoped = unscoped;
860-
for (folder_uri, settings) in folder_settings.into_iter() {
861-
if let Some(settings_) =
862-
self.settings.by_workspace_folder.get_mut(&folder_uri)
863-
{
864-
*settings_ = Some(settings);
865-
}
866-
}
865+
let mut by_folder = folder_settings.into_iter().collect::<HashMap<_, _>>();
866+
self.settings = Arc::new(Settings {
867+
unscoped: Arc::new(unscoped),
868+
by_workspace_folder: self
869+
.settings
870+
.by_workspace_folder
871+
.keys()
872+
.map(|s| (s.clone(), by_folder.remove(s).map(Arc::new)))
873+
.collect(),
874+
first_folder: self.settings.first_folder.clone(),
875+
});
867876
}
868877

869878
pub fn workspace_settings(&self) -> &WorkspaceSettings {
@@ -966,7 +975,7 @@ impl Config {
966975
&mut self,
967976
client_capabilities: ClientCapabilities,
968977
) {
969-
self.client_capabilities = client_capabilities;
978+
self.client_capabilities = Arc::new(client_capabilities);
970979
}
971980

972981
pub fn workspace_capable(&self) -> bool {
@@ -1906,10 +1915,15 @@ mod tests {
19061915
fn test_config_specifier_disabled_path() {
19071916
let root_uri = resolve_url("file:///root/").unwrap();
19081917
let mut config = Config::new_with_roots(vec![root_uri.clone()]);
1909-
config.settings.unscoped.enable = Some(true);
1910-
config.settings.unscoped.enable_paths =
1911-
Some(vec!["mod1.ts".to_string(), "mod2.ts".to_string()]);
1912-
config.settings.unscoped.disable_paths = vec!["mod2.ts".to_string()];
1918+
config.set_workspace_settings(
1919+
WorkspaceSettings {
1920+
enable: Some(true),
1921+
enable_paths: Some(vec!["mod1.ts".to_string(), "mod2.ts".to_string()]),
1922+
disable_paths: vec!["mod2.ts".to_string()],
1923+
..Default::default()
1924+
},
1925+
vec![],
1926+
);
19131927

19141928
assert!(config.specifier_enabled(&root_uri.join("mod1.ts").unwrap()));
19151929
assert!(!config.specifier_enabled(&root_uri.join("mod2.ts").unwrap()));
@@ -2107,7 +2121,6 @@ mod tests {
21072121
async fn config_enable_via_config_file_detection() {
21082122
let root_uri = resolve_url("file:///root/").unwrap();
21092123
let mut config = Config::new_with_roots(vec![root_uri.clone()]);
2110-
config.settings.unscoped.enable = None;
21112124
assert!(!config.specifier_enabled(&root_uri));
21122125

21132126
config
@@ -2129,19 +2142,27 @@ mod tests {
21292142
fn config_specifier_enabled_matches_by_path_component() {
21302143
let root_uri = resolve_url("file:///root/").unwrap();
21312144
let mut config = Config::new_with_roots(vec![root_uri.clone()]);
2132-
config.settings.unscoped.enable_paths = Some(vec!["mo".to_string()]);
2145+
config.set_workspace_settings(
2146+
WorkspaceSettings {
2147+
enable_paths: Some(vec!["mo".to_string()]),
2148+
..Default::default()
2149+
},
2150+
vec![],
2151+
);
21332152
assert!(!config.specifier_enabled(&root_uri.join("mod.ts").unwrap()));
21342153
}
21352154

21362155
#[tokio::test]
21372156
async fn config_specifier_enabled_for_test() {
21382157
let root_uri = resolve_url("file:///root/").unwrap();
21392158
let mut config = Config::new_with_roots(vec![root_uri.clone()]);
2140-
config.settings.unscoped.enable = Some(true);
2141-
2142-
config.settings.unscoped.enable_paths =
2143-
Some(vec!["mod1.ts".to_string(), "mod2.ts".to_string()]);
2144-
config.settings.unscoped.disable_paths = vec!["mod2.ts".to_string()];
2159+
let mut settings = WorkspaceSettings {
2160+
enable: Some(true),
2161+
enable_paths: Some(vec!["mod1.ts".to_string(), "mod2.ts".to_string()]),
2162+
disable_paths: vec!["mod2.ts".to_string()],
2163+
..Default::default()
2164+
};
2165+
config.set_workspace_settings(settings.clone(), vec![]);
21452166
assert!(
21462167
config.specifier_enabled_for_test(&root_uri.join("mod1.ts").unwrap())
21472168
);
@@ -2151,7 +2172,8 @@ mod tests {
21512172
assert!(
21522173
!config.specifier_enabled_for_test(&root_uri.join("mod3.ts").unwrap())
21532174
);
2154-
config.settings.unscoped.enable_paths = None;
2175+
settings.enable_paths = None;
2176+
config.set_workspace_settings(settings, vec![]);
21552177

21562178
config
21572179
.tree

cli/lsp/diagnostics.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1611,21 +1611,21 @@ mod tests {
16111611
fn mock_config() -> Config {
16121612
let root_uri = resolve_url("file:///").unwrap();
16131613
Config {
1614-
settings: Settings {
1615-
unscoped: WorkspaceSettings {
1614+
settings: Arc::new(Settings {
1615+
unscoped: Arc::new(WorkspaceSettings {
16161616
enable: Some(true),
16171617
lint: true,
16181618
..Default::default()
1619-
},
1619+
}),
16201620
..Default::default()
1621-
},
1622-
workspace_folders: vec![(
1621+
}),
1622+
workspace_folders: Arc::new(vec![(
16231623
root_uri.clone(),
16241624
lsp::WorkspaceFolder {
16251625
uri: root_uri,
16261626
name: "".to_string(),
16271627
},
1628-
)],
1628+
)]),
16291629
..Default::default()
16301630
}
16311631
}
@@ -1719,10 +1719,13 @@ let c: number = "a";
17191719
// now test disabled specifier
17201720
{
17211721
let mut disabled_config = mock_config();
1722-
disabled_config.settings.unscoped = WorkspaceSettings {
1723-
enable: Some(false),
1724-
..Default::default()
1725-
};
1722+
disabled_config.set_workspace_settings(
1723+
WorkspaceSettings {
1724+
enable: Some(false),
1725+
..Default::default()
1726+
},
1727+
vec![],
1728+
);
17261729

17271730
let diagnostics = generate_lint_diagnostics(
17281731
&snapshot,

cli/lsp/language_server.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ impl LanguageServer {
446446
if capable {
447447
let mut scopes = Vec::with_capacity(folders.len() + 1);
448448
scopes.push(None);
449-
for (_, folder) in &folders {
449+
for (_, folder) in folders.as_ref() {
450450
scopes.push(Some(folder.uri.clone()));
451451
}
452452
let configs = client
@@ -461,7 +461,7 @@ impl LanguageServer {
461461
let mut configs = configs.into_iter();
462462
let unscoped = configs.next().unwrap();
463463
let mut folder_settings = Vec::with_capacity(folders.len());
464-
for (folder_uri, _) in &folders {
464+
for (folder_uri, _) in folders.as_ref() {
465465
folder_settings.push((folder_uri.clone(), configs.next().unwrap()));
466466
}
467467
let mut inner = self.inner.write().await;
@@ -3146,7 +3146,7 @@ impl tower_lsp::LanguageServer for LanguageServer {
31463146
)
31473147
})
31483148
.collect::<Vec<(ModuleSpecifier, WorkspaceFolder)>>();
3149-
for (specifier, folder) in &inner.config.workspace_folders {
3149+
for (specifier, folder) in inner.config.workspace_folders.as_ref() {
31503150
if !params.event.removed.is_empty()
31513151
&& params.event.removed.iter().any(|f| f.uri == folder.uri)
31523152
{

0 commit comments

Comments
 (0)