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:
parent
d89ff73f9c
commit
518e4d3b3a
3 changed files with 68 additions and 43 deletions
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue