diff options
Diffstat (limited to 'cli/lsp/config.rs')
-rw-r--r-- | cli/lsp/config.rs | 154 |
1 files changed, 102 insertions, 52 deletions
diff --git a/cli/lsp/config.rs b/cli/lsp/config.rs index c58d2e86d..2bbd3ea7e 100644 --- a/cli/lsp/config.rs +++ b/cli/lsp/config.rs @@ -1169,6 +1169,7 @@ impl ConfigData { async fn load( config_file_specifier: Option<&ModuleSpecifier>, scope: &ModuleSpecifier, + parent: Option<(&ModuleSpecifier, &ConfigData)>, settings: &Settings, file_fetcher: Option<&FileFetcher>, ) -> Self { @@ -1182,8 +1183,14 @@ impl ConfigData { " Resolved Deno configuration file: \"{}\"", config_file.specifier.as_str() ); - Self::load_inner(Some(config_file), scope, settings, file_fetcher) - .await + Self::load_inner( + Some(config_file), + scope, + parent, + settings, + file_fetcher, + ) + .await } Err(err) => { lsp_warn!( @@ -1192,7 +1199,7 @@ impl ConfigData { err ); let mut data = - Self::load_inner(None, scope, settings, file_fetcher).await; + Self::load_inner(None, scope, parent, settings, file_fetcher).await; data .watched_files .insert(specifier.clone(), ConfigWatchedFileType::DenoJson); @@ -1210,13 +1217,14 @@ impl ConfigData { } } } else { - Self::load_inner(None, scope, settings, file_fetcher).await + Self::load_inner(None, scope, parent, settings, file_fetcher).await } } async fn load_inner( config_file: Option<ConfigFile>, scope: &ModuleSpecifier, + parent: Option<(&ModuleSpecifier, &ConfigData)>, settings: &Settings, file_fetcher: Option<&FileFetcher>, ) -> Self { @@ -1238,45 +1246,76 @@ impl ConfigData { .or_insert(ConfigWatchedFileType::DenoJson); } - // Resolve some config file fields ahead of time - let fmt_options = config_file - .as_ref() - .and_then(|config_file| { - config_file - .to_fmt_config() - .and_then(|o| { - let base_path = config_file - .specifier - .to_file_path() - .map_err(|_| anyhow!("Invalid base path."))?; - FmtOptions::resolve(o, None, &base_path) - }) - .inspect_err(|err| { - lsp_warn!(" Couldn't read formatter configuration: {}", err) - }) - .ok() - }) - .unwrap_or_default(); - let lint_options = config_file - .as_ref() - .and_then(|config_file| { - config_file - .to_lint_config() - .and_then(|o| { - let base_path = config_file - .specifier - .to_file_path() - .map_err(|_| anyhow!("Invalid base path."))?; - LintOptions::resolve(o, None, &base_path) - }) - .inspect_err(|err| { - lsp_warn!(" Couldn't read lint configuration: {}", err) - }) - .ok() - }) - .unwrap_or_default(); - let lint_rules = - get_configured_rules(lint_options.rules.clone(), config_file.as_ref()); + let mut fmt_options = None; + if let Some((_, parent_data)) = parent { + let has_own_fmt_options = config_file + .as_ref() + .is_some_and(|config_file| config_file.json.fmt.is_some()); + if !has_own_fmt_options { + fmt_options = Some(parent_data.fmt_options.clone()) + } + } + let fmt_options = fmt_options.unwrap_or_else(|| { + config_file + .as_ref() + .and_then(|config_file| { + config_file + .to_fmt_config() + .and_then(|o| { + let base_path = config_file + .specifier + .to_file_path() + .map_err(|_| anyhow!("Invalid base path."))?; + FmtOptions::resolve(o, None, &base_path) + }) + .inspect_err(|err| { + lsp_warn!(" Couldn't read formatter configuration: {}", err) + }) + .ok() + }) + .map(Arc::new) + .unwrap_or_default() + }); + + let mut lint_options_rules = None; + if let Some((_, parent_data)) = parent { + let has_own_lint_options = config_file + .as_ref() + .is_some_and(|config_file| config_file.json.lint.is_some()); + if !has_own_lint_options { + lint_options_rules = Some(( + parent_data.lint_options.clone(), + parent_data.lint_rules.clone(), + )) + } + } + let (lint_options, lint_rules) = lint_options_rules.unwrap_or_else(|| { + let lint_options = config_file + .as_ref() + .and_then(|config_file| { + config_file + .to_lint_config() + .and_then(|o| { + let base_path = config_file + .specifier + .to_file_path() + .map_err(|_| anyhow!("Invalid base path."))?; + LintOptions::resolve(o, None, &base_path) + }) + .inspect_err(|err| { + lsp_warn!(" Couldn't read lint configuration: {}", err) + }) + .ok() + }) + .map(Arc::new) + .unwrap_or_default(); + let lint_rules = Arc::new(get_configured_rules( + lint_options.rules.clone(), + config_file.as_ref(), + )); + (lint_options, lint_rules) + }); + let vendor_dir = config_file.as_ref().and_then(|c| c.vendor_dir_path()); // Load lockfile @@ -1449,9 +1488,9 @@ impl ConfigData { ConfigData { config_file: config_file.map(Arc::new), - fmt_options: Arc::new(fmt_options), - lint_options: Arc::new(lint_options), - lint_rules: Arc::new(lint_rules), + fmt_options, + lint_options, + lint_rules, ts_config: Arc::new(ts_config), byonm, node_modules_dir, @@ -1601,6 +1640,7 @@ impl ConfigTree { ConfigData::load( Some(&config_uri), folder_uri, + None, settings, Some(file_fetcher), ) @@ -1616,17 +1656,20 @@ impl ConfigTree { || specifier.path().ends_with("/deno.jsonc") { if let Ok(scope) = specifier.join(".") { - let entry = scopes.entry(scope.clone()); - #[allow(clippy::map_entry)] - if matches!(entry, std::collections::btree_map::Entry::Vacant(_)) { + if !scopes.contains_key(&scope) { + let parent = scopes + .iter() + .rev() + .find(|(s, _)| scope.as_str().starts_with(s.as_str())); let data = ConfigData::load( Some(specifier), &scope, + parent, settings, Some(file_fetcher), ) .await; - entry.or_insert(data); + scopes.insert(scope, data); } } } @@ -1639,8 +1682,14 @@ impl ConfigTree { { scopes.insert( folder_uri.clone(), - ConfigData::load(None, folder_uri, settings, Some(file_fetcher)) - .await, + ConfigData::load( + None, + folder_uri, + None, + settings, + Some(file_fetcher), + ) + .await, ); } } @@ -1654,6 +1703,7 @@ impl ConfigTree { let data = ConfigData::load_inner( Some(config_file), &scope, + None, &Default::default(), None, ) |