diff options
-rw-r--r-- | cli/lsp/resolver.rs | 38 | ||||
-rw-r--r-- | tests/integration/lsp_tests.rs | 57 |
2 files changed, 93 insertions, 2 deletions
diff --git a/cli/lsp/resolver.rs b/cli/lsp/resolver.rs index 2568dc3a2..1ec93bab3 100644 --- a/cli/lsp/resolver.rs +++ b/cli/lsp/resolver.rs @@ -26,10 +26,12 @@ use dashmap::DashMap; use deno_ast::MediaType; use deno_cache_dir::HttpCache; use deno_core::error::AnyError; +use deno_core::parking_lot::Mutex; use deno_core::url::Url; use deno_graph::source::Resolver; use deno_graph::GraphImport; use deno_graph::ModuleSpecifier; +use deno_lockfile::Lockfile; use deno_npm::NpmSystemInfo; use deno_runtime::deno_fs; use deno_runtime::deno_node::NodeResolution; @@ -108,6 +110,7 @@ impl LspScopeResolver { ))); let redirect_resolver = Some(Arc::new(RedirectResolver::new( cache.for_specifier(config_data.map(|d| &d.scope)), + config_data.and_then(|d| d.lockfile.as_deref()), ))); let npm_graph_resolver = graph_resolver.create_graph_npm_resolver(); let graph_imports = config_data @@ -220,6 +223,10 @@ impl LspResolver { std::iter::once(&self.unscoped).chain(self.by_scope.values()) { resolver.jsr_resolver.as_ref().inspect(|r| r.did_cache()); + resolver + .redirect_resolver + .as_ref() + .inspect(|r| r.did_cache()); } } @@ -543,13 +550,36 @@ impl std::fmt::Debug for RedirectResolver { } impl RedirectResolver { - fn new(cache: Arc<dyn HttpCache>) -> Self { + fn new( + cache: Arc<dyn HttpCache>, + lockfile: Option<&Mutex<Lockfile>>, + ) -> Self { + let entries = DashMap::new(); + if let Some(lockfile) = lockfile { + for (source, destination) in &lockfile.lock().content.redirects { + let Ok(source) = ModuleSpecifier::parse(source) else { + continue; + }; + let Ok(destination) = ModuleSpecifier::parse(destination) else { + continue; + }; + entries.insert( + source, + Some(Arc::new(RedirectEntry { + headers: Default::default(), + target: destination.clone(), + destination: Some(destination.clone()), + })), + ); + entries.insert(destination, None); + } + } Self { get_headers: Box::new(move |specifier| { let cache_key = cache.cache_item_key(specifier).ok()?; cache.read_headers(&cache_key).ok().flatten() }), - entries: Default::default(), + entries, } } @@ -629,6 +659,10 @@ impl RedirectResolver { } result } + + fn did_cache(&self) { + self.entries.retain(|_, entry| entry.is_some()); + } } #[cfg(test)] diff --git a/tests/integration/lsp_tests.rs b/tests/integration/lsp_tests.rs index bfb15ecb9..0ebe03711 100644 --- a/tests/integration/lsp_tests.rs +++ b/tests/integration/lsp_tests.rs @@ -9189,6 +9189,63 @@ fn lsp_redirect_quick_fix() { } #[test] +fn lsp_lockfile_redirect_resolution() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let temp_dir = context.temp_dir(); + temp_dir.write("deno.json", json!({}).to_string()); + temp_dir.write("deno.lock", json!({ + "version": "3", + "redirects": { + "http://localhost:4545/subdir/mod1.ts": "http://localhost:4545/subdir/mod2.ts", + }, + "remote": {}, + }).to_string()); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": temp_dir.uri().join("file.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": "import \"http://localhost:4545/subdir/mod1.ts\";\n", + }, + })); + client.write_request( + "workspace/executeCommand", + json!({ + "command": "deno.cache", + "arguments": [[], temp_dir.uri().join("file.ts").unwrap()], + }), + ); + client.read_diagnostics(); + let res = client.write_request( + "textDocument/definition", + json!({ + "textDocument": { "uri": temp_dir.uri().join("file.ts").unwrap() }, + "position": { "line": 0, "character": 7 }, + }), + ); + assert_eq!( + res, + json!([{ + "targetUri": "deno:/http/localhost%3A4545/subdir/mod2.ts", + "targetRange": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 1, "character": 0 }, + }, + "targetSelectionRange": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 1, "character": 0 }, + }, + }]), + ); + client.shutdown(); +} + +#[test] fn lsp_diagnostics_deprecated() { let context = TestContextBuilder::new().use_temp_cwd().build(); let mut client = context.new_lsp_command().build(); |