diff options
Diffstat (limited to 'cli/lsp')
| -rw-r--r-- | cli/lsp/cache.rs | 109 | ||||
| -rw-r--r-- | cli/lsp/language_server.rs | 56 |
2 files changed, 36 insertions, 129 deletions
diff --git a/cli/lsp/cache.rs b/cli/lsp/cache.rs index fc8b50c4a..77f356486 100644 --- a/cli/lsp/cache.rs +++ b/cli/lsp/cache.rs @@ -1,123 +1,14 @@ // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. -use crate::args::ConfigFile; -use crate::args::Flags; -use crate::cache::FetchCacher; -use crate::graph_util::graph_valid; use crate::http_cache; -use crate::proc_state::ProcState; -use crate::resolver::ImportMapResolver; -use crate::resolver::JsxResolver; -use deno_core::anyhow::anyhow; -use deno_core::error::AnyError; use deno_core::parking_lot::Mutex; use deno_core::ModuleSpecifier; -use deno_runtime::permissions::Permissions; -use deno_runtime::tokio_util::create_basic_runtime; -use import_map::ImportMap; use std::collections::HashMap; use std::fs; use std::path::Path; -use std::path::PathBuf; use std::sync::Arc; -use std::thread; use std::time::SystemTime; -use tokio::sync::mpsc; -use tokio::sync::oneshot; - -type Request = ( - Vec<(ModuleSpecifier, deno_graph::ModuleKind)>, - oneshot::Sender<Result<(), AnyError>>, -); - -/// A "server" that handles requests from the language server to cache modules -/// in its own thread. -#[derive(Debug)] -pub struct CacheServer(mpsc::UnboundedSender<Request>); - -impl CacheServer { - pub async fn new( - maybe_cache_path: Option<PathBuf>, - maybe_import_map: Option<Arc<ImportMap>>, - maybe_config_file: Option<ConfigFile>, - maybe_ca_stores: Option<Vec<String>>, - maybe_ca_file: Option<String>, - unsafely_ignore_certificate_errors: Option<Vec<String>>, - ) -> Self { - let (tx, mut rx) = mpsc::unbounded_channel::<Request>(); - let _join_handle = thread::spawn(move || { - let runtime = create_basic_runtime(); - runtime.block_on(async { - let ps = ProcState::build(Flags { - cache_path: maybe_cache_path, - ca_stores: maybe_ca_stores, - ca_file: maybe_ca_file, - unsafely_ignore_certificate_errors, - ..Default::default() - }) - .await - .unwrap(); - let maybe_import_map_resolver = - maybe_import_map.map(ImportMapResolver::new); - let maybe_jsx_resolver = maybe_config_file.as_ref().and_then(|cf| { - cf.to_maybe_jsx_import_source_module() - .map(|im| JsxResolver::new(im, maybe_import_map_resolver.clone())) - }); - let maybe_resolver = if maybe_jsx_resolver.is_some() { - maybe_jsx_resolver.as_ref().map(|jr| jr.as_resolver()) - } else { - maybe_import_map_resolver - .as_ref() - .map(|im| im.as_resolver()) - }; - let maybe_imports = maybe_config_file - .and_then(|cf| cf.to_maybe_imports().ok()) - .flatten(); - let mut cache = FetchCacher::new( - ps.dir.gen_cache.clone(), - ps.file_fetcher.clone(), - Permissions::allow_all(), - Permissions::allow_all(), - ); - - while let Some((roots, tx)) = rx.recv().await { - let graph = deno_graph::create_graph( - roots, - false, - maybe_imports.clone(), - &mut cache, - maybe_resolver, - None, - None, - None, - ) - .await; - - if tx.send(graph_valid(&graph, true, false)).is_err() { - log::warn!("cannot send to client"); - } - } - }) - }); - - Self(tx) - } - - /// Attempt to cache the supplied module specifiers and their dependencies in - /// the current DENO_DIR, returning any errors, so they can be returned to the - /// client. - pub async fn cache( - &self, - roots: Vec<(ModuleSpecifier, deno_graph::ModuleKind)>, - ) -> Result<(), AnyError> { - let (tx, rx) = oneshot::channel::<Result<(), AnyError>>(); - if self.0.send((roots, tx)).is_err() { - return Err(anyhow!("failed to send request to cache thread")); - } - rx.await? - } -} /// Calculate a version for for a given path. pub fn calculate_fs_version(path: &Path) -> Option<String> { diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index 1e9da54d6..41323a300 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -8,6 +8,8 @@ use deno_core::serde_json; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::ModuleSpecifier; +use deno_graph::ModuleKind; +use deno_runtime::tokio_util::run_basic; use import_map::ImportMap; use log::error; use log::warn; @@ -55,14 +57,18 @@ use super::tsc::Assets; use super::tsc::AssetsSnapshot; use super::tsc::TsServer; use super::urls; +use crate::args::CliOptions; use crate::args::ConfigFile; +use crate::args::Flags; use crate::args::FmtConfig; use crate::args::LintConfig; use crate::args::TsConfig; use crate::deno_dir; use crate::file_fetcher::get_source_from_data_url; use crate::fs_util; +use crate::graph_util::graph_valid; 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; @@ -104,8 +110,6 @@ pub struct Inner { /// An optional path to the DENO_DIR which has been specified in the client /// options. maybe_cache_path: Option<PathBuf>, - /// A lazily created "server" for handling cache requests. - maybe_cache_server: Option<cache::CacheServer>, /// An optional configuration file which has been specified in the client /// options. maybe_config_file: Option<ConfigFile>, @@ -246,7 +250,6 @@ impl Inner { diagnostics_server, documents, maybe_cache_path: None, - maybe_cache_server: None, maybe_config_file: None, maybe_import_map: None, maybe_import_map_uri: None, @@ -429,7 +432,6 @@ impl Inner { pub fn update_cache(&mut self) -> Result<(), AnyError> { let mark = self.performance.mark("update_cache", None::<()>); self.performance.measure(mark); - self.maybe_cache_server = None; let maybe_cache = self.config.get_workspace_settings().cache; let maybe_cache_path = if let Some(cache_str) = &maybe_cache { lsp_log!("Setting cache path from: \"{}\"", cache_str); @@ -489,7 +491,6 @@ impl Inner { pub async fn update_import_map(&mut self) -> Result<(), AnyError> { let mark = self.performance.mark("update_import_map", None::<()>); - self.maybe_cache_server = None; let maybe_import_map_url = if let Some(import_map_str) = self.config.get_workspace_settings().import_map { @@ -2775,6 +2776,16 @@ impl Inner { &mut self, params: lsp_custom::CacheParams, ) -> LspResult<Option<Value>> { + async fn create_graph_for_caching( + cli_options: CliOptions, + roots: Vec<(ModuleSpecifier, ModuleKind)>, + ) -> Result<(), AnyError> { + let ps = ProcState::from_options(Arc::new(cli_options)).await?; + let graph = ps.create_graph(roots).await?; + graph_valid(&graph, true, false)?; + Ok(()) + } + let referrer = self.url_map.normalize_url(¶ms.referrer.uri); if !self.is_diagnosable(&referrer) { return Ok(None); @@ -2796,21 +2807,26 @@ impl Inner { vec![(referrer.clone(), deno_graph::ModuleKind::Esm)] }; - if self.maybe_cache_server.is_none() { - self.maybe_cache_server = Some( - cache::CacheServer::new( - self.maybe_cache_path.clone(), - self.maybe_import_map.clone(), - self.maybe_config_file.clone(), - None, - None, - None, - ) - .await, - ); - } - let cache_server = self.maybe_cache_server.as_ref().unwrap(); - if let Err(err) = cache_server.cache(roots).await { + let mut cli_options = CliOptions::new( + Flags { + cache_path: self.maybe_cache_path.clone(), + ca_stores: None, + ca_file: None, + unsafely_ignore_certificate_errors: None, + ..Default::default() + }, + self.maybe_config_file.clone(), + ); + cli_options.set_import_map_specifier(self.maybe_import_map_uri.clone()); + + // todo(dsherret): why is running this on a new thread necessary? It does + // a compile error otherwise. + let handle = tokio::task::spawn_blocking(|| { + run_basic( + async move { create_graph_for_caching(cli_options, roots).await }, + ) + }); + if let Err(err) = handle.await.unwrap() { self.client.show_message(MessageType::WARNING, err).await; } |
