diff options
Diffstat (limited to 'cli/lsp/language_server.rs')
-rw-r--r-- | cli/lsp/language_server.rs | 208 |
1 files changed, 22 insertions, 186 deletions
diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index f15f40f1b..67bae3651 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -13,9 +13,6 @@ use deno_core::url; use deno_core::ModuleSpecifier; use deno_graph::GraphKind; use deno_graph::Resolution; -use deno_npm::NpmSystemInfo; -use deno_runtime::deno_fs; -use deno_runtime::deno_node::NodeResolver; use deno_runtime::deno_tls::rustls::RootCertStore; use deno_runtime::deno_tls::RootCertStoreProvider; use deno_semver::jsr::JsrPackageReqReference; @@ -29,7 +26,6 @@ use std::collections::HashSet; use std::collections::VecDeque; use std::env; use std::fmt::Write as _; -use std::path::Path; use std::path::PathBuf; use std::sync::Arc; use tokio::sync::mpsc::unbounded_channel; @@ -52,7 +48,6 @@ use super::client::Client; use super::code_lens; use super::completions; use super::config::Config; -use super::config::ConfigData; use super::config::ConfigSnapshot; use super::config::UpdateImportsOnFileMoveEnabled; use super::config::WorkspaceSettings; @@ -79,6 +74,7 @@ use super::performance::Performance; use super::performance::PerformanceMark; use super::refactor; use super::registries::ModuleRegistry; +use super::resolver::LspResolver; use super::testing; use super::text; use super::tsc; @@ -94,7 +90,6 @@ use crate::args::CacheSetting; use crate::args::CliOptions; use crate::args::Flags; use crate::cache::DenoDir; -use crate::cache::FastInsecureHasher; use crate::cache::GlobalHttpCache; use crate::cache::HttpCache; use crate::cache::LocalLspHttpCache; @@ -106,14 +101,6 @@ use crate::lsp::config::ConfigWatchedFileType; use crate::lsp::logging::init_log_file; use crate::lsp::tsc::file_text_changes_to_workspace_edit; use crate::lsp::urls::LspUrlKind; -use crate::npm::create_cli_npm_resolver_for_lsp; -use crate::npm::CliNpmResolver; -use crate::npm::CliNpmResolverByonmCreateOptions; -use crate::npm::CliNpmResolverCreateOptions; -use crate::npm::CliNpmResolverManagedCreateOptions; -use crate::npm::CliNpmResolverManagedPackageJsonInstallerOption; -use crate::npm::CliNpmResolverManagedSnapshotOption; -use crate::resolver::CliNodeResolver; use crate::tools::fmt::format_file; use crate::tools::fmt::format_parsed_source; use crate::tools::upgrade::check_for_upgrades_for_lsp; @@ -121,8 +108,6 @@ use crate::tools::upgrade::upgrade_check_enabled; use crate::util::fs::remove_dir_all_if_exists; use crate::util::path::is_importable_ext; use crate::util::path::to_percent_decoded_str; -use crate::util::progress_bar::ProgressBar; -use crate::util::progress_bar::ProgressBarStyle; use deno_runtime::fs_util::specifier_to_file_path; struct LspRootCertStoreProvider(RootCertStore); @@ -133,46 +118,9 @@ impl RootCertStoreProvider for LspRootCertStoreProvider { } } -#[derive(Debug)] -struct LspNpmServices { - /// When this hash changes, the services need updating - config_hash: LspNpmConfigHash, - /// Npm's search api. - search_api: CliNpmSearchApi, - /// Node resolver. - node_resolver: Option<Arc<CliNodeResolver>>, - /// Resolver for npm packages. - resolver: Option<Arc<dyn CliNpmResolver>>, -} - -#[derive(Debug, PartialEq, Eq)] -struct LspNpmConfigHash(u64); - -impl LspNpmConfigHash { - pub fn from_inner(inner: &Inner) -> Self { - let config_data = inner.config.tree.root_data(); - let node_modules_dir = - config_data.and_then(|d| d.node_modules_dir.as_ref()); - let lockfile = config_data.and_then(|d| d.lockfile.as_ref()); - let mut hasher = FastInsecureHasher::new(); - hasher.write_hashable(node_modules_dir); - hasher.write_hashable(&inner.maybe_global_cache_path); - if let Some(lockfile) = lockfile { - hasher.write_hashable(&*lockfile.lock()); - } - Self(hasher.finish()) - } -} - #[derive(Debug, Clone)] pub struct LanguageServer(Arc<tokio::sync::RwLock<Inner>>, CancellationToken); -#[derive(Clone, Debug)] -pub struct StateNpmSnapshot { - pub node_resolver: Arc<CliNodeResolver>, - pub npm_resolver: Arc<dyn CliNpmResolver>, -} - /// Snapshot of the state used by TSC. #[derive(Clone, Debug)] pub struct StateSnapshot { @@ -181,7 +129,7 @@ pub struct StateSnapshot { pub cache_metadata: cache::CacheMetadata, pub config: Arc<ConfigSnapshot>, pub documents: Documents, - pub npm: Option<StateNpmSnapshot>, + pub resolver: Arc<LspResolver>, } type LanguageServerTaskFn = Box<dyn FnOnce(LanguageServer) + Send + Sync>; @@ -253,11 +201,11 @@ pub struct Inner { maybe_global_cache_path: Option<PathBuf>, /// A lazily create "server" for handling test run requests. maybe_testing_server: Option<testing::TestServer>, - /// Services used for dealing with npm related functionality. - npm: LspNpmServices, + npm_search_api: CliNpmSearchApi, project_version: usize, /// A collection of measurements which instrument that performance of the LSP. performance: Arc<Performance>, + resolver: Arc<LspResolver>, /// A memoized version of fixable diagnostic codes retrieved from TypeScript. ts_fixable_diagnostics: Vec<String>, /// An abstraction that handles interactions with TypeScript. @@ -544,13 +492,9 @@ impl Inner { maybe_testing_server: None, module_registries, module_registries_location, - npm: LspNpmServices { - config_hash: LspNpmConfigHash(0), // this will be updated in initialize - search_api: npm_search_api, - node_resolver: None, - resolver: None, - }, + npm_search_api, performance, + resolver: Default::default(), ts_fixable_diagnostics: Default::default(), ts_server, url_map: Default::default(), @@ -645,35 +589,13 @@ impl Inner { } pub fn snapshot(&self) -> Arc<StateSnapshot> { - let maybe_state_npm_snapshot = self - .npm - .resolver - .as_ref() - .map(|resolver| resolver.clone_snapshotted()) - .map(|resolver| { - let fs = Arc::new(deno_fs::RealFs); - let node_resolver = Arc::new(NodeResolver::new( - fs.clone(), - resolver.clone().into_npm_resolver(), - )); - let cli_node_resolver = Arc::new(CliNodeResolver::new( - None, - fs, - node_resolver, - resolver.clone(), - )); - StateNpmSnapshot { - node_resolver: cli_node_resolver, - npm_resolver: resolver, - } - }); Arc::new(StateSnapshot { project_version: self.project_version, assets: self.assets.snapshot(), cache_metadata: self.cache_metadata.clone(), config: self.config.snapshot(), documents: self.documents.clone(), - npm: maybe_state_npm_snapshot, + resolver: self.resolver.snapshot(), }) } @@ -747,7 +669,7 @@ impl Inner { ); self.jsr_search_api = CliJsrSearchApi::new(self.module_registries.file_fetcher.clone()); - self.npm.search_api = + self.npm_search_api = CliNpmSearchApi::new(self.module_registries.file_fetcher.clone()); // update the cache path let global_cache = Arc::new(GlobalHttpCache::new( @@ -773,42 +695,6 @@ impl Inner { Ok(()) } - async fn recreate_npm_services_if_necessary(&mut self) { - let deno_dir = match DenoDir::new(self.maybe_global_cache_path.clone()) { - Ok(deno_dir) => deno_dir, - Err(err) => { - lsp_warn!("Error getting deno dir: {:#}", err); - return; - } - }; - let config_hash = LspNpmConfigHash::from_inner(self); - if config_hash == self.npm.config_hash { - return; // no need to do anything - } - let config_data = self.config.tree.root_data(); - let npm_resolver = create_npm_resolver( - &deno_dir, - &self.initial_cwd, - &self.http_client, - config_data, - ) - .await; - let node_resolver = Arc::new(NodeResolver::new( - Arc::new(deno_fs::RealFs), - npm_resolver.clone().into_npm_resolver(), - )); - self.npm.node_resolver = Some(Arc::new(CliNodeResolver::new( - None, - Arc::new(deno_fs::RealFs), - node_resolver, - npm_resolver.clone(), - ))); - self.npm.resolver = Some(npm_resolver); - - // update the hash - self.npm.config_hash = config_hash; - } - fn create_file_fetcher(&self, cache_setting: CacheSetting) -> FileFetcher { let mut file_fetcher = FileFetcher::new( self.deps_http_cache.clone(), @@ -844,52 +730,6 @@ impl Inner { } } -async fn create_npm_resolver( - deno_dir: &DenoDir, - initial_cwd: &Path, - http_client: &Arc<HttpClient>, - config_data: Option<&ConfigData>, -) -> Arc<dyn CliNpmResolver> { - let byonm = config_data.map(|d| d.byonm).unwrap_or(false); - create_cli_npm_resolver_for_lsp(if byonm { - CliNpmResolverCreateOptions::Byonm(CliNpmResolverByonmCreateOptions { - fs: Arc::new(deno_fs::RealFs), - root_node_modules_dir: initial_cwd.join("node_modules"), - }) - } else { - CliNpmResolverCreateOptions::Managed(CliNpmResolverManagedCreateOptions { - http_client: http_client.clone(), - snapshot: match config_data.and_then(|d| d.lockfile.as_ref()) { - Some(lockfile) => { - CliNpmResolverManagedSnapshotOption::ResolveFromLockfile( - lockfile.clone(), - ) - } - None => CliNpmResolverManagedSnapshotOption::Specified(None), - }, - // Don't provide the lockfile. We don't want these resolvers - // updating it. Only the cache request should update the lockfile. - maybe_lockfile: None, - fs: Arc::new(deno_fs::RealFs), - npm_global_cache_dir: deno_dir.npm_folder_path(), - // Use an "only" cache setting in order to make the - // user do an explicit "cache" command and prevent - // the cache from being filled with lots of packages while - // the user is typing. - cache_setting: CacheSetting::Only, - text_only_progress_bar: ProgressBar::new(ProgressBarStyle::TextOnly), - maybe_node_modules_path: config_data - .and_then(|d| d.node_modules_dir.clone()), - // do not install while resolving in the lsp—leave that to the cache command - package_json_installer: - CliNpmResolverManagedPackageJsonInstallerOption::NoInstall, - npm_registry_url: crate::args::npm_registry_url().to_owned(), - npm_system_info: NpmSystemInfo::default(), - }) - }) - .await -} - // lspower::LanguageServer methods. This file's LanguageServer delegates to us. impl Inner { async fn initialize( @@ -1004,7 +844,6 @@ impl Inner { self.client.show_message(MessageType::WARNING, err); } - self.recreate_npm_services_if_necessary().await; self.assets.initialize(self.snapshot()).await; self.performance.measure(mark); @@ -1178,13 +1017,20 @@ impl Inner { } } } + self.resolver = self + .resolver + .with_new_config( + &self.config, + self.maybe_global_cache_path.as_deref(), + Some(&self.http_client), + ) + .await; } async fn refresh_documents_config(&mut self) { self.documents.update_config( &self.config, - self.npm.node_resolver.clone(), - self.npm.resolver.clone(), + &self.resolver, &self.workspace_files, ); @@ -1262,17 +1108,10 @@ impl Inner { async fn refresh_npm_specifiers(&mut self) { let package_reqs = self.documents.npm_package_reqs(); - let npm_resolver = self.npm.resolver.clone(); + let resolver = self.resolver.clone(); // spawn to avoid the LSP's Send requirements - let handle = spawn(async move { - if let Some(npm_resolver) = - npm_resolver.as_ref().and_then(|r| r.as_managed()) - { - npm_resolver.set_package_reqs(&package_reqs).await - } else { - Ok(()) - } - }); + let handle = + spawn(async move { resolver.set_npm_package_reqs(&package_reqs).await }); if let Err(err) = handle.await.unwrap() { lsp_warn!("Could not set npm package requirements. {:#}", err); } @@ -1331,7 +1170,6 @@ impl Inner { lsp_warn!("Error updating registries: {:#}", err); self.client.show_message(MessageType::WARNING, err); } - self.recreate_npm_services_if_necessary().await; self.refresh_documents_config().await; self.diagnostics_server.invalidate_all(); self.send_diagnostics_update(); @@ -1408,7 +1246,6 @@ impl Inner { }, ); } - self.recreate_npm_services_if_necessary().await; self.refresh_documents_config().await; self.diagnostics_server.invalidate_all(); self.project_changed( @@ -2003,8 +1840,7 @@ impl Inner { TsResponseImportMapper::new( &self.documents, self.config.tree.root_import_map().map(|i| i.as_ref()), - self.npm.node_resolver.as_deref(), - self.npm.resolver.as_deref(), + self.resolver.as_ref(), ) } @@ -2313,7 +2149,7 @@ impl Inner { &self.client, &self.module_registries, &self.jsr_search_api, - &self.npm.search_api, + &self.npm_search_api, &self.documents, self.config.tree.root_import_map().map(|i| i.as_ref()), ) |