diff options
Diffstat (limited to 'cli/lsp/language_server.rs')
-rw-r--r-- | cli/lsp/language_server.rs | 177 |
1 files changed, 108 insertions, 69 deletions
diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index 0941fe0fb..7f53b17f3 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -57,6 +57,7 @@ use super::tsc::AssetsSnapshot; use super::tsc::TsServer; use super::urls; use crate::args::get_root_cert_store; +use crate::args::import_map_from_value; use crate::args::CaData; use crate::args::CacheSetting; use crate::args::CliOptions; @@ -72,7 +73,6 @@ use crate::http_util::HttpClient; use crate::npm::NpmCache; use crate::npm::NpmPackageResolver; use crate::npm::RealNpmRegistryApi; -use crate::proc_state::import_map_from_text; use crate::proc_state::ProcState; use crate::tools::fmt::format_file; use crate::tools::fmt::format_parsed_source; @@ -601,47 +601,84 @@ impl Inner { pub async fn update_import_map(&mut self) -> Result<(), AnyError> { let mark = self.performance.mark("update_import_map", None::<()>); - let maybe_import_map_url = if let Some(import_map_str) = self - .config - .get_workspace_settings() - .import_map - .and_then(|s| if s.is_empty() { None } else { Some(s) }) - { - lsp_log!( - "Setting import map from workspace settings: \"{}\"", - import_map_str - ); - if let Some(config_file) = &self.maybe_config_file { - if let Some(import_map_path) = config_file.to_import_map_path() { - lsp_log!("Warning: Import map \"{}\" configured in \"{}\" being ignored due to an import map being explicitly configured in workspace settings.", import_map_path, config_file.specifier); - } - } - if let Ok(url) = Url::from_file_path(&import_map_str) { - Some(url) - } else if import_map_str.starts_with("data:") { - Some(Url::parse(&import_map_str).map_err(|_| { - anyhow!("Bad data url for import map: {}", import_map_str) - })?) - } else if let Some(root_uri) = &self.config.root_uri { - let root_path = specifier_to_file_path(root_uri)?; - let import_map_path = root_path.join(&import_map_str); - Some(Url::from_file_path(import_map_path).map_err(|_| { - anyhow!("Bad file path for import map: {}", import_map_str) - })?) - } else { - return Err(anyhow!( - "The path to the import map (\"{}\") is not resolvable.", - import_map_str - )); - } - } else if let Some(config_file) = &self.maybe_config_file { - if let Some(import_map_path) = config_file.to_import_map_path() { + let maybe_import_map_url = self.resolve_import_map_specifier()?; + if let Some(import_map_url) = maybe_import_map_url { + let import_map = self + .resolve_import_map_from_specifier(&import_map_url) + .await + .map_err(|err| { + anyhow!( + "Failed to load the import map at: {}. {:#}", + import_map_url, + err + ) + })?; + self.maybe_import_map_uri = Some(import_map_url); + self.maybe_import_map = Some(Arc::new(import_map)); + } else { + self.maybe_import_map_uri = None; + self.maybe_import_map = None; + } + self.performance.measure(mark); + Ok(()) + } + + fn resolve_import_map_specifier( + &self, + ) -> Result<Option<ModuleSpecifier>, AnyError> { + Ok( + if let Some(import_map_str) = self + .config + .get_workspace_settings() + .import_map + .and_then(|s| if s.is_empty() { None } else { Some(s) }) + { lsp_log!( - "Setting import map from configuration file: \"{}\"", - import_map_path + "Setting import map from workspace settings: \"{}\"", + import_map_str ); - let specifier = - if let Ok(config_file_path) = config_file.specifier.to_file_path() { + if let Some(config_file) = &self.maybe_config_file { + if let Some(import_map_path) = config_file.to_import_map_path() { + lsp_log!("Warning: Import map \"{}\" configured in \"{}\" being ignored due to an import map being explicitly configured in workspace settings.", import_map_path, config_file.specifier); + } + } + if let Ok(url) = Url::from_file_path(&import_map_str) { + Some(url) + } else if import_map_str.starts_with("data:") { + let import_map_url = Url::parse(&import_map_str).map_err(|_| { + anyhow!("Bad data url for import map: {}", import_map_str) + })?; + Some(import_map_url) + } else if let Some(root_uri) = &self.config.root_uri { + let root_path = specifier_to_file_path(root_uri)?; + let import_map_path = root_path.join(&import_map_str); + let import_map_url = + Url::from_file_path(import_map_path).map_err(|_| { + anyhow!("Bad file path for import map: {}", import_map_str) + })?; + Some(import_map_url) + } else { + return Err(anyhow!( + "The path to the import map (\"{}\") is not resolvable.", + import_map_str + )); + } + } else if let Some(config_file) = &self.maybe_config_file { + if config_file.is_an_import_map() { + lsp_log!( + "Setting import map defined in configuration file: \"{}\"", + config_file.specifier + ); + let import_map_url = config_file.specifier.clone(); + Some(import_map_url) + } else if let Some(import_map_path) = config_file.to_import_map_path() { + lsp_log!( + "Setting import map from configuration file: \"{}\"", + import_map_path + ); + let specifier = if let Ok(config_file_path) = + config_file.specifier.to_file_path() + { let import_map_file_path = config_file_path .parent() .ok_or_else(|| { @@ -655,39 +692,41 @@ impl Inner { config_file.specifier.as_str(), )? }; - Some(specifier) + Some(specifier) + } else { + None + } } else { None - } + }, + ) + } + + async fn resolve_import_map_from_specifier( + &self, + import_map_url: &ModuleSpecifier, + ) -> Result<ImportMap, AnyError> { + let import_map_json: Value = if import_map_url.scheme() == "data" { + serde_json::from_str(&get_source_from_data_url(import_map_url)?.0)? } else { - None + let import_map_path = specifier_to_file_path(import_map_url)?; + lsp_log!( + " Resolved import map: \"{}\"", + import_map_path.to_string_lossy() + ); + let import_map_config_file = self + .maybe_config_file + .as_ref() + .filter(|c| c.specifier == *import_map_url); + match import_map_config_file { + Some(c) => c.to_import_map_value(), + None => { + serde_json::from_str(&fs::read_to_string(import_map_path).await?)? + } + } }; - if let Some(import_map_url) = maybe_import_map_url { - let import_map_json = if import_map_url.scheme() == "data" { - get_source_from_data_url(&import_map_url)?.0 - } else { - let import_map_path = specifier_to_file_path(&import_map_url)?; - lsp_log!( - " Resolved import map: \"{}\"", - import_map_path.to_string_lossy() - ); - fs::read_to_string(import_map_path).await.map_err(|err| { - anyhow!( - "Failed to load the import map at: {}. [{}]", - import_map_url, - err - ) - })? - }; - let import_map = import_map_from_text(&import_map_url, &import_map_json)?; - self.maybe_import_map_uri = Some(import_map_url); - self.maybe_import_map = Some(Arc::new(import_map)); - } else { - self.maybe_import_map_uri = None; - self.maybe_import_map = None; - } - self.performance.measure(mark); - Ok(()) + + import_map_from_value(import_map_url, import_map_json) } pub fn update_debug_flag(&self) { |