1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-22 15:06:54 -05:00

perf(lsp): store settings in Arc (#24191)

This commit is contained in:
Nayeem Rahman 2024-06-13 20:57:14 +01:00 committed by GitHub
parent d89ff73f9c
commit 518e4d3b3a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 68 additions and 43 deletions

View file

@ -722,8 +722,9 @@ impl WorkspaceSettings {
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]
pub struct Settings { pub struct Settings {
pub unscoped: WorkspaceSettings, pub unscoped: Arc<WorkspaceSettings>,
pub by_workspace_folder: BTreeMap<ModuleSpecifier, Option<WorkspaceSettings>>, pub by_workspace_folder:
BTreeMap<ModuleSpecifier, Option<Arc<WorkspaceSettings>>>,
pub first_folder: Option<ModuleSpecifier>, pub first_folder: Option<ModuleSpecifier>,
} }
@ -815,9 +816,9 @@ impl Settings {
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct Config { pub struct Config {
pub client_capabilities: ClientCapabilities, pub client_capabilities: Arc<ClientCapabilities>,
pub settings: Settings, pub settings: Arc<Settings>,
pub workspace_folders: Vec<(ModuleSpecifier, lsp::WorkspaceFolder)>, pub workspace_folders: Arc<Vec<(ModuleSpecifier, lsp::WorkspaceFolder)>>,
pub tree: ConfigTree, pub tree: ConfigTree,
} }
@ -845,10 +846,15 @@ impl Config {
&mut self, &mut self,
folders: Vec<(ModuleSpecifier, lsp::WorkspaceFolder)>, folders: Vec<(ModuleSpecifier, lsp::WorkspaceFolder)>,
) { ) {
self.settings.by_workspace_folder = self.settings = Arc::new(Settings {
folders.iter().map(|(s, _)| (s.clone(), None)).collect(); unscoped: self.settings.unscoped.clone(),
self.settings.first_folder = folders.first().map(|(s, _)| s.clone()); by_workspace_folder: folders
self.workspace_folders = folders; .iter()
.map(|(s, _)| (s.clone(), None))
.collect(),
first_folder: folders.first().map(|(s, _)| s.clone()),
});
self.workspace_folders = Arc::new(folders);
} }
pub fn set_workspace_settings( pub fn set_workspace_settings(
@ -856,14 +862,17 @@ impl Config {
unscoped: WorkspaceSettings, unscoped: WorkspaceSettings,
folder_settings: Vec<(ModuleSpecifier, WorkspaceSettings)>, folder_settings: Vec<(ModuleSpecifier, WorkspaceSettings)>,
) { ) {
self.settings.unscoped = unscoped; let mut by_folder = folder_settings.into_iter().collect::<HashMap<_, _>>();
for (folder_uri, settings) in folder_settings.into_iter() { self.settings = Arc::new(Settings {
if let Some(settings_) = unscoped: Arc::new(unscoped),
self.settings.by_workspace_folder.get_mut(&folder_uri) by_workspace_folder: self
{ .settings
*settings_ = Some(settings); .by_workspace_folder
} .keys()
} .map(|s| (s.clone(), by_folder.remove(s).map(Arc::new)))
.collect(),
first_folder: self.settings.first_folder.clone(),
});
} }
pub fn workspace_settings(&self) -> &WorkspaceSettings { pub fn workspace_settings(&self) -> &WorkspaceSettings {
@ -966,7 +975,7 @@ impl Config {
&mut self, &mut self,
client_capabilities: ClientCapabilities, client_capabilities: ClientCapabilities,
) { ) {
self.client_capabilities = client_capabilities; self.client_capabilities = Arc::new(client_capabilities);
} }
pub fn workspace_capable(&self) -> bool { pub fn workspace_capable(&self) -> bool {
@ -1906,10 +1915,15 @@ mod tests {
fn test_config_specifier_disabled_path() { fn test_config_specifier_disabled_path() {
let root_uri = resolve_url("file:///root/").unwrap(); let root_uri = resolve_url("file:///root/").unwrap();
let mut config = Config::new_with_roots(vec![root_uri.clone()]); let mut config = Config::new_with_roots(vec![root_uri.clone()]);
config.settings.unscoped.enable = Some(true); config.set_workspace_settings(
config.settings.unscoped.enable_paths = WorkspaceSettings {
Some(vec!["mod1.ts".to_string(), "mod2.ts".to_string()]); enable: Some(true),
config.settings.unscoped.disable_paths = vec!["mod2.ts".to_string()]; enable_paths: Some(vec!["mod1.ts".to_string(), "mod2.ts".to_string()]),
disable_paths: vec!["mod2.ts".to_string()],
..Default::default()
},
vec![],
);
assert!(config.specifier_enabled(&root_uri.join("mod1.ts").unwrap())); assert!(config.specifier_enabled(&root_uri.join("mod1.ts").unwrap()));
assert!(!config.specifier_enabled(&root_uri.join("mod2.ts").unwrap())); assert!(!config.specifier_enabled(&root_uri.join("mod2.ts").unwrap()));
@ -2107,7 +2121,6 @@ mod tests {
async fn config_enable_via_config_file_detection() { async fn config_enable_via_config_file_detection() {
let root_uri = resolve_url("file:///root/").unwrap(); let root_uri = resolve_url("file:///root/").unwrap();
let mut config = Config::new_with_roots(vec![root_uri.clone()]); let mut config = Config::new_with_roots(vec![root_uri.clone()]);
config.settings.unscoped.enable = None;
assert!(!config.specifier_enabled(&root_uri)); assert!(!config.specifier_enabled(&root_uri));
config config
@ -2129,7 +2142,13 @@ mod tests {
fn config_specifier_enabled_matches_by_path_component() { fn config_specifier_enabled_matches_by_path_component() {
let root_uri = resolve_url("file:///root/").unwrap(); let root_uri = resolve_url("file:///root/").unwrap();
let mut config = Config::new_with_roots(vec![root_uri.clone()]); let mut config = Config::new_with_roots(vec![root_uri.clone()]);
config.settings.unscoped.enable_paths = Some(vec!["mo".to_string()]); config.set_workspace_settings(
WorkspaceSettings {
enable_paths: Some(vec!["mo".to_string()]),
..Default::default()
},
vec![],
);
assert!(!config.specifier_enabled(&root_uri.join("mod.ts").unwrap())); assert!(!config.specifier_enabled(&root_uri.join("mod.ts").unwrap()));
} }
@ -2137,11 +2156,13 @@ mod tests {
async fn config_specifier_enabled_for_test() { async fn config_specifier_enabled_for_test() {
let root_uri = resolve_url("file:///root/").unwrap(); let root_uri = resolve_url("file:///root/").unwrap();
let mut config = Config::new_with_roots(vec![root_uri.clone()]); let mut config = Config::new_with_roots(vec![root_uri.clone()]);
config.settings.unscoped.enable = Some(true); let mut settings = WorkspaceSettings {
enable: Some(true),
config.settings.unscoped.enable_paths = enable_paths: Some(vec!["mod1.ts".to_string(), "mod2.ts".to_string()]),
Some(vec!["mod1.ts".to_string(), "mod2.ts".to_string()]); disable_paths: vec!["mod2.ts".to_string()],
config.settings.unscoped.disable_paths = vec!["mod2.ts".to_string()]; ..Default::default()
};
config.set_workspace_settings(settings.clone(), vec![]);
assert!( assert!(
config.specifier_enabled_for_test(&root_uri.join("mod1.ts").unwrap()) config.specifier_enabled_for_test(&root_uri.join("mod1.ts").unwrap())
); );
@ -2151,7 +2172,8 @@ mod tests {
assert!( assert!(
!config.specifier_enabled_for_test(&root_uri.join("mod3.ts").unwrap()) !config.specifier_enabled_for_test(&root_uri.join("mod3.ts").unwrap())
); );
config.settings.unscoped.enable_paths = None; settings.enable_paths = None;
config.set_workspace_settings(settings, vec![]);
config config
.tree .tree

View file

@ -1611,21 +1611,21 @@ mod tests {
fn mock_config() -> Config { fn mock_config() -> Config {
let root_uri = resolve_url("file:///").unwrap(); let root_uri = resolve_url("file:///").unwrap();
Config { Config {
settings: Settings { settings: Arc::new(Settings {
unscoped: WorkspaceSettings { unscoped: Arc::new(WorkspaceSettings {
enable: Some(true), enable: Some(true),
lint: true, lint: true,
..Default::default() ..Default::default()
}, }),
..Default::default() ..Default::default()
}, }),
workspace_folders: vec![( workspace_folders: Arc::new(vec![(
root_uri.clone(), root_uri.clone(),
lsp::WorkspaceFolder { lsp::WorkspaceFolder {
uri: root_uri, uri: root_uri,
name: "".to_string(), name: "".to_string(),
}, },
)], )]),
..Default::default() ..Default::default()
} }
} }
@ -1719,10 +1719,13 @@ let c: number = "a";
// now test disabled specifier // now test disabled specifier
{ {
let mut disabled_config = mock_config(); let mut disabled_config = mock_config();
disabled_config.settings.unscoped = WorkspaceSettings { disabled_config.set_workspace_settings(
enable: Some(false), WorkspaceSettings {
..Default::default() enable: Some(false),
}; ..Default::default()
},
vec![],
);
let diagnostics = generate_lint_diagnostics( let diagnostics = generate_lint_diagnostics(
&snapshot, &snapshot,

View file

@ -446,7 +446,7 @@ impl LanguageServer {
if capable { if capable {
let mut scopes = Vec::with_capacity(folders.len() + 1); let mut scopes = Vec::with_capacity(folders.len() + 1);
scopes.push(None); scopes.push(None);
for (_, folder) in &folders { for (_, folder) in folders.as_ref() {
scopes.push(Some(folder.uri.clone())); scopes.push(Some(folder.uri.clone()));
} }
let configs = client let configs = client
@ -461,7 +461,7 @@ impl LanguageServer {
let mut configs = configs.into_iter(); let mut configs = configs.into_iter();
let unscoped = configs.next().unwrap(); let unscoped = configs.next().unwrap();
let mut folder_settings = Vec::with_capacity(folders.len()); let mut folder_settings = Vec::with_capacity(folders.len());
for (folder_uri, _) in &folders { for (folder_uri, _) in folders.as_ref() {
folder_settings.push((folder_uri.clone(), configs.next().unwrap())); folder_settings.push((folder_uri.clone(), configs.next().unwrap()));
} }
let mut inner = self.inner.write().await; let mut inner = self.inner.write().await;
@ -3146,7 +3146,7 @@ impl tower_lsp::LanguageServer for LanguageServer {
) )
}) })
.collect::<Vec<(ModuleSpecifier, WorkspaceFolder)>>(); .collect::<Vec<(ModuleSpecifier, WorkspaceFolder)>>();
for (specifier, folder) in &inner.config.workspace_folders { for (specifier, folder) in inner.config.workspace_folders.as_ref() {
if !params.event.removed.is_empty() if !params.event.removed.is_empty()
&& params.event.removed.iter().any(|f| f.uri == folder.uri) && params.event.removed.iter().any(|f| f.uri == folder.uri)
{ {