diff --git a/cli/lsp/analysis.rs b/cli/lsp/analysis.rs index 23b6bb0999..63d39ad6e3 100644 --- a/cli/lsp/analysis.rs +++ b/cli/lsp/analysis.rs @@ -259,7 +259,8 @@ impl<'a> TsResponseImportMapper<'a> { let version = Version::parse_standard(segments.next()?).ok()?; let nv = PackageNv { name, version }; let path = segments.collect::>().join("/"); - let export = self.resolver.jsr_lookup_export_for_path(&nv, &path)?; + let jsr_resolver = self.documents.get_jsr_resolver(); + let export = jsr_resolver.lookup_export_for_path(&nv, &path)?; let sub_path = (export != ".").then_some(export); let mut req = None; req = req.or_else(|| { @@ -281,7 +282,7 @@ impl<'a> TsResponseImportMapper<'a> { } None }); - req = req.or_else(|| self.resolver.jsr_lookup_req_for_nv(&nv)); + req = req.or_else(|| jsr_resolver.lookup_req_for_nv(&nv)); let spec_str = if let Some(req) = req { let req_ref = PackageReqReference { req, sub_path }; JsrPackageReqReference::new(req_ref).to_string() diff --git a/cli/lsp/diagnostics.rs b/cli/lsp/diagnostics.rs index 1825a97a42..87bb72d1e5 100644 --- a/cli/lsp/diagnostics.rs +++ b/cli/lsp/diagnostics.rs @@ -1591,7 +1591,7 @@ mod tests { location.to_path_buf(), RealDenoCacheEnv, )); - let mut documents = Documents::new(cache.clone()); + let mut documents = Documents::new(cache); for (specifier, source, version, language_id) in fixtures { let specifier = resolve_url(specifier).expect("failed to create specifier"); @@ -1614,7 +1614,7 @@ mod tests { config.tree.inject_config_file(config_file).await; } let resolver = LspResolver::default() - .with_new_config(&config, cache, None, None) + .with_new_config(&config, None, None) .await; StateSnapshot { project_version: 0, diff --git a/cli/lsp/documents.rs b/cli/lsp/documents.rs index 60b2385cb5..71cc63f836 100644 --- a/cli/lsp/documents.rs +++ b/cli/lsp/documents.rs @@ -12,6 +12,7 @@ use super::tsc::AssetDocument; use crate::cache::HttpCache; use crate::graph_util::CliJsrUrlProvider; +use crate::jsr::JsrCacheResolver; use crate::lsp::logging::lsp_warn; use crate::resolver::SloppyImportsFsEntry; use crate::resolver::SloppyImportsResolution; @@ -31,6 +32,7 @@ use deno_core::futures::FutureExt; use deno_core::parking_lot::Mutex; use deno_core::ModuleSpecifier; use deno_graph::source::ResolutionMode; +use deno_graph::GraphImport; use deno_graph::Resolution; use deno_lockfile::Lockfile; use deno_runtime::deno_node; @@ -714,6 +716,64 @@ pub fn to_lsp_range(range: &deno_graph::Range) -> lsp::Range { } } +#[derive(Debug)] +struct RedirectResolver { + cache: Arc, + redirects: Mutex>, +} + +impl RedirectResolver { + pub fn new(cache: Arc) -> Self { + Self { + cache, + redirects: Mutex::new(HashMap::new()), + } + } + + pub fn resolve( + &self, + specifier: &ModuleSpecifier, + ) -> Option { + let scheme = specifier.scheme(); + if !DOCUMENT_SCHEMES.contains(&scheme) { + return None; + } + + if scheme == "http" || scheme == "https" { + let mut redirects = self.redirects.lock(); + if let Some(specifier) = redirects.get(specifier) { + Some(specifier.clone()) + } else { + let redirect = self.resolve_remote(specifier, 10)?; + redirects.insert(specifier.clone(), redirect.clone()); + Some(redirect) + } + } else { + Some(specifier.clone()) + } + } + + fn resolve_remote( + &self, + specifier: &ModuleSpecifier, + redirect_limit: usize, + ) -> Option { + if redirect_limit > 0 { + let cache_key = self.cache.cache_item_key(specifier).ok()?; + let headers = self.cache.read_headers(&cache_key).ok().flatten()?; + if let Some(location) = headers.get("location") { + let redirect = + deno_core::resolve_import(location, specifier.as_str()).ok()?; + self.resolve_remote(&redirect, redirect_limit - 1) + } else { + Some(specifier.clone()) + } + } else { + None + } + } +} + #[derive(Debug, Default)] struct FileSystemDocuments { docs: DashMap>, @@ -858,15 +918,21 @@ pub struct Documents { open_docs: HashMap>, /// Documents stored on the file system. file_system_docs: Arc, + /// Any imports to the context supplied by configuration files. This is like + /// the imports into the a module graph in CLI. + imports: Arc>, /// A resolver that takes into account currently loaded import map and JSX /// settings. resolver: Arc, + jsr_resolver: Arc, lockfile: Option>>, /// The npm package requirements found in npm specifiers. npm_specifier_reqs: Arc>, /// Gets if any document had a node: specifier such that a @types/node package /// should be injected. has_injected_types_node_package: bool, + /// Resolves a specifier to its final redirected to specifier. + redirect_resolver: Arc, /// If --unstable-sloppy-imports is enabled. unstable_sloppy_imports: bool, } @@ -879,14 +945,29 @@ impl Documents { dirty: true, open_docs: HashMap::default(), file_system_docs: Default::default(), + imports: Default::default(), resolver: Default::default(), + jsr_resolver: Arc::new(JsrCacheResolver::new(cache.clone(), None)), lockfile: None, npm_specifier_reqs: Default::default(), has_injected_types_node_package: false, + redirect_resolver: Arc::new(RedirectResolver::new(cache)), unstable_sloppy_imports: false, } } + pub fn initialize(&mut self, config: &Config) { + self.config = Arc::new(config.clone()); + } + + pub fn module_graph_imports(&self) -> impl Iterator { + self + .imports + .values() + .flat_map(|i| i.dependencies.values()) + .flat_map(|value| value.get_type().or_else(|| value.get_code())) + } + /// "Open" a document from the perspective of the editor, meaning that /// requests for information from the document will come from the in-memory /// representation received from the language server client, versus reading @@ -1021,14 +1102,11 @@ impl Documents { let specifier = if let Ok(jsr_req_ref) = JsrPackageReqReference::from_specifier(specifier) { - Cow::Owned(self.resolver.jsr_to_registry_url(&jsr_req_ref)?) + Cow::Owned(self.jsr_resolver.jsr_to_registry_url(&jsr_req_ref)?) } else { Cow::Borrowed(specifier) }; - if !DOCUMENT_SCHEMES.contains(&specifier.scheme()) { - return None; - } - self.resolver.resolve_redirects(&specifier) + self.redirect_resolver.resolve(&specifier) } } @@ -1201,8 +1279,7 @@ impl Documents { results.push(None); } } else if let Some(specifier) = self - .resolver - .resolve_graph_import(specifier) + .resolve_imports_dependency(specifier) .and_then(|r| r.maybe_specifier()) { results.push(self.resolve_dependency(specifier, referrer)); @@ -1231,19 +1308,62 @@ impl Documents { results } + /// Update the location of the on disk cache for the document store. + pub fn set_cache(&mut self, cache: Arc) { + // TODO update resolved dependencies? + self.cache = cache.clone(); + self.redirect_resolver = Arc::new(RedirectResolver::new(cache)); + self.dirty = true; + } + + pub fn get_jsr_resolver(&self) -> &Arc { + &self.jsr_resolver + } + + pub fn refresh_lockfile(&mut self, lockfile: Option>>) { + self.jsr_resolver = + Arc::new(JsrCacheResolver::new(self.cache.clone(), lockfile.clone())); + self.lockfile = lockfile; + } + pub fn update_config( &mut self, config: &Config, resolver: &Arc, - cache: Arc, workspace_files: &BTreeSet, ) { self.config = Arc::new(config.clone()); - self.cache = cache; let config_data = config.tree.root_data(); let config_file = config_data.and_then(|d| d.config_file.as_deref()); self.resolver = resolver.clone(); + self.jsr_resolver = Arc::new(JsrCacheResolver::new( + self.cache.clone(), + config.tree.root_lockfile().cloned(), + )); self.lockfile = config.tree.root_lockfile().cloned(); + self.redirect_resolver = + Arc::new(RedirectResolver::new(self.cache.clone())); + let graph_resolver = self.resolver.as_graph_resolver(); + let npm_resolver = self.resolver.as_graph_npm_resolver(); + self.imports = Arc::new( + if let Some(Ok(imports)) = config_file.map(|cf| cf.to_maybe_imports()) { + imports + .into_iter() + .map(|(referrer, imports)| { + let graph_import = GraphImport::new( + &referrer, + imports, + &CliJsrUrlProvider, + Some(graph_resolver), + Some(npm_resolver), + ); + (referrer, graph_import) + }) + .collect() + } else { + IndexMap::new() + }, + ); self.unstable_sloppy_imports = config_file .map(|c| c.has_unstable("sloppy-imports")) .unwrap_or(false); @@ -1396,6 +1516,19 @@ impl Documents { Some((doc.specifier().clone(), media_type)) } } + + /// Iterate through any "imported" modules, checking to see if a dependency + /// is available. This is used to provide "global" imports like the JSX import + /// source. + fn resolve_imports_dependency(&self, specifier: &str) -> Option<&Resolution> { + for graph_imports in self.imports.values() { + let maybe_dep = graph_imports.dependencies.get(specifier); + if maybe_dep.is_some() { + return maybe_dep.map(|d| &d.maybe_type); + } + } + None + } } fn node_resolve_npm_req_ref( @@ -1569,20 +1702,20 @@ mod tests { use test_util::PathRef; use test_util::TempDir; - fn setup(temp_dir: &TempDir) -> (Documents, PathRef, Arc) { + fn setup(temp_dir: &TempDir) -> (Documents, PathRef) { let location = temp_dir.path().join("deps"); let cache = Arc::new(GlobalHttpCache::new( location.to_path_buf(), RealDenoCacheEnv, )); - let documents = Documents::new(cache.clone()); - (documents, location, cache) + let documents = Documents::new(cache); + (documents, location) } #[test] fn test_documents_open_close() { let temp_dir = TempDir::new(); - let (mut documents, _, _) = setup(&temp_dir); + let (mut documents, _) = setup(&temp_dir); let specifier = ModuleSpecifier::parse("file:///a.ts").unwrap(); let content = r#"import * as b from "./b.ts"; console.log(b); @@ -1608,7 +1741,7 @@ console.log(b); #[test] fn test_documents_change() { let temp_dir = TempDir::new(); - let (mut documents, _, _) = setup(&temp_dir); + let (mut documents, _) = setup(&temp_dir); let specifier = ModuleSpecifier::parse("file:///a.ts").unwrap(); let content = r#"import * as b from "./b.ts"; console.log(b); @@ -1652,7 +1785,7 @@ console.log(b, "hello deno"); // it should never happen that a user of this API causes this to happen, // but we'll guard against it anyway let temp_dir = TempDir::new(); - let (mut documents, documents_path, _) = setup(&temp_dir); + let (mut documents, documents_path) = setup(&temp_dir); let file_path = documents_path.join("file.ts"); let file_specifier = ModuleSpecifier::from_file_path(&file_path).unwrap(); documents_path.create_dir_all(); @@ -1680,7 +1813,7 @@ console.log(b, "hello deno"); // it should never happen that a user of this API causes this to happen, // but we'll guard against it anyway let temp_dir = TempDir::new(); - let (mut documents, documents_path, cache) = setup(&temp_dir); + let (mut documents, documents_path) = setup(&temp_dir); fs::create_dir_all(&documents_path).unwrap(); let file1_path = documents_path.join("file1.ts"); @@ -1729,14 +1862,9 @@ console.log(b, "hello deno"); .await; let resolver = LspResolver::default() - .with_new_config(&config, cache.clone(), None, None) + .with_new_config(&config, None, None) .await; - documents.update_config( - &config, - &resolver, - cache.clone(), - &workspace_files, - ); + documents.update_config(&config, &resolver, &workspace_files); // open the document let document = documents.open( @@ -1778,9 +1906,9 @@ console.log(b, "hello deno"); .await; let resolver = LspResolver::default() - .with_new_config(&config, cache.clone(), None, None) + .with_new_config(&config, None, None) .await; - documents.update_config(&config, &resolver, cache, &workspace_files); + documents.update_config(&config, &resolver, &workspace_files); // check the document's dependencies let document = documents.get(&file1_specifier).unwrap(); diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index 3a378d0ea4..07d3d8cb78 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -312,8 +312,9 @@ impl LanguageServer { .show_message(MessageType::WARNING, err); } let mut inner = self.0.write().await; - inner.refresh_resolver().await; - inner.refresh_documents_config().await; + let lockfile = inner.config.tree.root_lockfile().cloned(); + inner.documents.refresh_lockfile(lockfile); + inner.refresh_npm_specifiers().await; inner.post_cache(result.mark).await; } Ok(Some(json!(true))) @@ -686,6 +687,7 @@ impl Inner { .map(|c| c as Arc) .unwrap_or(global_cache); self.deps_http_cache = cache.clone(); + self.documents.set_cache(cache.clone()); self.cache_metadata.set_cache(cache); self.url_map.set_cache(maybe_local_cache); self.maybe_global_cache_path = new_cache_path; @@ -808,6 +810,8 @@ impl Inner { self.config.update_capabilities(¶ms.capabilities); } + self.documents.initialize(&self.config); + if let Err(e) = self .ts_server .start(self.config.internal_inspect().to_address()) @@ -1012,14 +1016,10 @@ impl Inner { } } } - } - - async fn refresh_resolver(&mut self) { self.resolver = self .resolver .with_new_config( &self.config, - self.deps_http_cache.clone(), self.maybe_global_cache_path.as_deref(), Some(&self.http_client), ) @@ -1030,7 +1030,6 @@ impl Inner { self.documents.update_config( &self.config, &self.resolver, - self.deps_http_cache.clone(), &self.workspace_files, ); @@ -1170,7 +1169,6 @@ impl Inner { lsp_warn!("Error updating registries: {:#}", err); self.client.show_message(MessageType::WARNING, err); } - self.refresh_resolver().await; self.refresh_documents_config().await; self.diagnostics_server.invalidate_all(); self.send_diagnostics_update(); @@ -1219,7 +1217,6 @@ impl Inner { self.workspace_files_hash = 0; self.refresh_workspace_files(); self.refresh_config_tree().await; - self.refresh_resolver().await; deno_config_changes.extend(changes.iter().filter_map(|(s, e)| { self.config.tree.watched_file_type(s).and_then(|t| { let configuration_type = match t.1 { @@ -1521,7 +1518,10 @@ impl Inner { if let Ok(jsr_req_ref) = JsrPackageReqReference::from_specifier(specifier) { - if let Some(url) = self.resolver.jsr_to_registry_url(&jsr_req_ref) + if let Some(url) = self + .documents + .get_jsr_resolver() + .jsr_to_registry_url(&jsr_req_ref) { result = format!("{result} (<{url}>)"); } @@ -2991,7 +2991,6 @@ impl tower_lsp::LanguageServer for LanguageServer { { let mut ls = self.0.write().await; init_log_file(ls.config.log_file()); - ls.refresh_resolver().await; ls.refresh_documents_config().await; ls.diagnostics_server.invalidate_all(); ls.send_diagnostics_update(); @@ -3126,7 +3125,6 @@ impl tower_lsp::LanguageServer for LanguageServer { let mut ls = self.0.write().await; ls.refresh_workspace_files(); ls.refresh_config_tree().await; - ls.refresh_resolver().await; ls.refresh_documents_config().await; ls.diagnostics_server.invalidate_all(); ls.send_diagnostics_update(); diff --git a/cli/lsp/resolver.rs b/cli/lsp/resolver.rs index 1aa8830722..076d48bb4d 100644 --- a/cli/lsp/resolver.rs +++ b/cli/lsp/resolver.rs @@ -4,9 +4,7 @@ use crate::args::package_json; use crate::args::CacheSetting; use crate::cache::DenoDir; use crate::cache::FastInsecureHasher; -use crate::graph_util::CliJsrUrlProvider; use crate::http_util::HttpClient; -use crate::jsr::JsrCacheResolver; use crate::lsp::config::Config; use crate::lsp::config::ConfigData; use crate::lsp::logging::lsp_warn; @@ -23,14 +21,10 @@ use crate::resolver::CliGraphResolverOptions; use crate::resolver::CliNodeResolver; use crate::util::progress_bar::ProgressBar; use crate::util::progress_bar::ProgressBarStyle; -use deno_cache_dir::HttpCache; use deno_core::error::AnyError; -use deno_core::parking_lot::Mutex; use deno_graph::source::NpmResolver; use deno_graph::source::Resolver; -use deno_graph::GraphImport; use deno_graph::ModuleSpecifier; -use deno_graph::Resolution; use deno_npm::NpmSystemInfo; use deno_runtime::deno_fs; use deno_runtime::deno_node::NodeResolution; @@ -39,13 +33,9 @@ use deno_runtime::deno_node::NodeResolver; use deno_runtime::deno_node::PackageJson; use deno_runtime::fs_util::specifier_to_file_path; use deno_runtime::permissions::PermissionsContainer; -use deno_semver::jsr::JsrPackageReqReference; use deno_semver::npm::NpmPackageReqReference; -use deno_semver::package::PackageNv; use deno_semver::package::PackageReq; -use indexmap::IndexMap; use package_json::PackageJsonDepsProvider; -use std::collections::HashMap; use std::path::Path; use std::rc::Rc; use std::sync::Arc; @@ -53,25 +43,19 @@ use std::sync::Arc; #[derive(Debug, Clone)] pub struct LspResolver { graph_resolver: Arc, - jsr_resolver: Option>, npm_resolver: Option>, node_resolver: Option>, npm_config_hash: LspNpmConfigHash, - redirect_resolver: Option>, - graph_imports: Arc>, config: Arc, } impl Default for LspResolver { fn default() -> Self { Self { - graph_resolver: create_graph_resolver(None, None, None), - jsr_resolver: None, + graph_resolver: create_graph_resolver(&Default::default(), None, None), npm_resolver: None, node_resolver: None, npm_config_hash: LspNpmConfigHash(0), - redirect_resolver: None, - graph_imports: Default::default(), config: Default::default(), } } @@ -81,16 +65,15 @@ impl LspResolver { pub async fn with_new_config( &self, config: &Config, - cache: Arc, global_cache_path: Option<&Path>, http_client: Option<&Arc>, ) -> Arc { let npm_config_hash = LspNpmConfigHash::new(config, global_cache_path); - let config_data = config.tree.root_data(); let mut npm_resolver = None; let mut node_resolver = None; if npm_config_hash != self.npm_config_hash { - if let (Some(http_client), Some(config_data)) = (http_client, config_data) + if let (Some(http_client), Some(config_data)) = + (http_client, config.tree.root_data()) { npm_resolver = create_npm_resolver(config_data, global_cache_path, http_client) @@ -102,44 +85,15 @@ impl LspResolver { node_resolver = self.node_resolver.clone(); } let graph_resolver = create_graph_resolver( - config_data, + config, npm_resolver.as_ref(), node_resolver.as_ref(), ); - let jsr_resolver = Some(Arc::new(JsrCacheResolver::new( - cache.clone(), - config_data.and_then(|d| d.lockfile.clone()), - ))); - let redirect_resolver = Some(Arc::new(RedirectResolver::new(cache))); - let graph_imports = config_data - .and_then(|d| d.config_file.as_ref()) - .and_then(|cf| cf.to_maybe_imports().ok()) - .map(|imports| { - Arc::new( - imports - .into_iter() - .map(|(referrer, imports)| { - let graph_import = GraphImport::new( - &referrer, - imports, - &CliJsrUrlProvider, - Some(graph_resolver.as_ref()), - Some(graph_resolver.as_ref()), - ); - (referrer, graph_import) - }) - .collect(), - ) - }) - .unwrap_or_default(); Arc::new(Self { graph_resolver, - jsr_resolver, npm_resolver, node_resolver, npm_config_hash, - redirect_resolver, - graph_imports, config: Arc::new(config.clone()), }) } @@ -149,18 +103,15 @@ impl LspResolver { self.npm_resolver.as_ref().map(|r| r.clone_snapshotted()); let node_resolver = create_node_resolver(npm_resolver.as_ref()); let graph_resolver = create_graph_resolver( - self.config.tree.root_data(), + &self.config, npm_resolver.as_ref(), node_resolver.as_ref(), ); Arc::new(Self { graph_resolver, - jsr_resolver: self.jsr_resolver.clone(), npm_resolver, node_resolver, npm_config_hash: self.npm_config_hash.clone(), - redirect_resolver: self.redirect_resolver.clone(), - graph_imports: self.graph_imports.clone(), config: self.config.clone(), }) } @@ -185,49 +136,10 @@ impl LspResolver { self.graph_resolver.as_ref() } - pub fn jsr_to_registry_url( - &self, - req_ref: &JsrPackageReqReference, - ) -> Option { - self.jsr_resolver.as_ref()?.jsr_to_registry_url(req_ref) - } - - pub fn jsr_lookup_export_for_path( - &self, - nv: &PackageNv, - path: &str, - ) -> Option { - self.jsr_resolver.as_ref()?.lookup_export_for_path(nv, path) - } - - pub fn jsr_lookup_req_for_nv(&self, nv: &PackageNv) -> Option { - self.jsr_resolver.as_ref()?.lookup_req_for_nv(nv) - } - pub fn maybe_managed_npm_resolver(&self) -> Option<&ManagedCliNpmResolver> { self.npm_resolver.as_ref().and_then(|r| r.as_managed()) } - pub fn graph_import_specifiers( - &self, - ) -> impl Iterator { - self - .graph_imports - .values() - .flat_map(|i| i.dependencies.values()) - .flat_map(|value| value.get_type().or_else(|| value.get_code())) - } - - pub fn resolve_graph_import(&self, specifier: &str) -> Option<&Resolution> { - for graph_imports in self.graph_imports.values() { - let maybe_dep = graph_imports.dependencies.get(specifier); - if maybe_dep.is_some() { - return maybe_dep.map(|d| &d.maybe_type); - } - } - None - } - pub fn in_npm_package(&self, specifier: &ModuleSpecifier) -> bool { if let Some(npm_resolver) = &self.npm_resolver { return npm_resolver.in_npm_package(specifier); @@ -291,16 +203,6 @@ impl LspResolver { node_resolver .get_closest_package_json(referrer, &PermissionsContainer::allow_all()) } - - pub fn resolve_redirects( - &self, - specifier: &ModuleSpecifier, - ) -> Option { - let Some(redirect_resolver) = self.redirect_resolver.as_ref() else { - return Some(specifier.clone()); - }; - redirect_resolver.resolve(specifier) - } } async fn create_npm_resolver( @@ -373,10 +275,11 @@ fn create_node_resolver( } fn create_graph_resolver( - config_data: Option<&ConfigData>, + config: &Config, npm_resolver: Option<&Arc>, node_resolver: Option<&Arc>, ) -> Arc { + let config_data = config.tree.root_data(); let config_file = config_data.and_then(|d| d.config_file.as_deref()); Arc::new(CliGraphResolver::new(CliGraphResolverOptions { node_resolver: node_resolver.cloned(), @@ -393,7 +296,7 @@ fn create_graph_resolver( maybe_import_map: config_data.and_then(|d| d.import_map.clone()), maybe_vendor_dir: config_data.and_then(|d| d.vendor_dir.as_ref()), bare_node_builtins_enabled: config_file - .map(|cf| cf.has_unstable("bare-node-builtins")) + .map(|config| config.has_unstable("bare-node-builtins")) .unwrap_or(false), // Don't set this for the LSP because instead we'll use the OpenDocumentsLoader // because it's much easier and we get diagnostics/quick fixes about a redirected @@ -423,56 +326,3 @@ impl LspNpmConfigHash { Self(hasher.finish()) } } - -#[derive(Debug)] -struct RedirectResolver { - cache: Arc, - redirects: Mutex>, -} - -impl RedirectResolver { - pub fn new(cache: Arc) -> Self { - Self { - cache, - redirects: Mutex::new(HashMap::new()), - } - } - - pub fn resolve( - &self, - specifier: &ModuleSpecifier, - ) -> Option { - if matches!(specifier.scheme(), "http" | "https") { - let mut redirects = self.redirects.lock(); - if let Some(specifier) = redirects.get(specifier) { - Some(specifier.clone()) - } else { - let redirect = self.resolve_remote(specifier, 10)?; - redirects.insert(specifier.clone(), redirect.clone()); - Some(redirect) - } - } else { - Some(specifier.clone()) - } - } - - fn resolve_remote( - &self, - specifier: &ModuleSpecifier, - redirect_limit: usize, - ) -> Option { - if redirect_limit > 0 { - let cache_key = self.cache.cache_item_key(specifier).ok()?; - let headers = self.cache.read_headers(&cache_key).ok().flatten()?; - if let Some(location) = headers.get("location") { - let redirect = - deno_core::resolve_import(location, specifier.as_str()).ok()?; - self.resolve_remote(&redirect, redirect_limit - 1) - } else { - Some(specifier.clone()) - } - } else { - None - } - } -} diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs index 28127c6d75..66e834bc28 100644 --- a/cli/lsp/tsc.rs +++ b/cli/lsp/tsc.rs @@ -4124,9 +4124,9 @@ fn op_script_names(state: &mut OpState) -> Vec { } // inject these next because they're global - for specifier in state.state_snapshot.resolver.graph_import_specifiers() { - if seen.insert(specifier.as_str()) { - result.push(specifier.to_string()); + for import in documents.module_graph_imports() { + if seen.insert(import.as_str()) { + result.push(import.to_string()); } } @@ -5095,7 +5095,7 @@ mod tests { ) .await; let resolver = LspResolver::default() - .with_new_config(&config, cache.clone(), None, None) + .with_new_config(&config, None, None) .await; StateSnapshot { project_version: 0,