From 318f524c5c72feaffe4a76e2e8cbc8fca27fb75f Mon Sep 17 00:00:00 2001 From: Nayeem Rahman Date: Thu, 9 Jan 2025 17:54:14 +0000 Subject: [PATCH] fix(lsp): use verbatim specifier for URL auto-imports (#27605) --- cli/lsp/tsc.rs | 5 ++ tests/integration/lsp_tests.rs | 68 +++++++++++++++++++ .../imports_declaration/imports_interface.ts | 3 + .../subdir/imports_declaration/interface.d.ts | 3 + 4 files changed, 79 insertions(+) create mode 100644 tests/testdata/subdir/imports_declaration/imports_interface.ts create mode 100644 tests/testdata/subdir/imports_declaration/interface.d.ts diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs index 826021a288..cd1a724f5e 100644 --- a/cli/lsp/tsc.rs +++ b/cli/lsp/tsc.rs @@ -3972,6 +3972,11 @@ impl CompletionEntry { if let Some(mut new_specifier) = import_mapper .check_specifier(&import_data.normalized, specifier) .or_else(|| relative_specifier(specifier, &import_data.normalized)) + .or_else(|| { + ModuleSpecifier::parse(&import_data.raw.module_specifier) + .is_ok() + .then(|| import_data.normalized.to_string()) + }) { if new_specifier.contains("/node_modules/") { return None; diff --git a/tests/integration/lsp_tests.rs b/tests/integration/lsp_tests.rs index 9efb34f337..247851da9c 100644 --- a/tests/integration/lsp_tests.rs +++ b/tests/integration/lsp_tests.rs @@ -9937,6 +9937,74 @@ fn lsp_auto_imports_npm_auto() { client.shutdown(); } +// Regression test for https://github.com/denoland/deno/issues/23869. +#[test] +fn lsp_auto_imports_remote_dts() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let temp_dir = context.temp_dir(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": temp_dir.url().join("file.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": r#" + import "http://localhost:4545/subdir/imports_declaration/imports_interface.ts"; + const a: SomeInterface + "#, + }, + })); + client.write_request( + "workspace/executeCommand", + json!({ + "command": "deno.cache", + "arguments": [[], temp_dir.url().join("file.ts").unwrap()], + }), + ); + let list = client.get_completion_list( + temp_dir.url().join("file.ts").unwrap(), + (2, 21), + json!({ "triggerKind": 2 }), + ); + assert!(!list.is_incomplete); + let item = list + .items + .iter() + .find(|item| item.label == "SomeInterface") + .unwrap(); + let res = client.write_request("completionItem/resolve", json!(item)); + assert_eq!( + res, + json!({ + "label": "SomeInterface", + "labelDetails": { + "description": "http://localhost:4545/subdir/imports_declaration/interface.d.ts", + }, + "kind": 8, + "detail": "interface SomeInterface", + "documentation": { + "kind": "markdown", + "value": "", + }, + "sortText": "￿16_1", + "additionalTextEdits": [ + { + "range": { + "start": { "line": 2, "character": 0 }, + "end": { "line": 2, "character": 0 }, + }, + "newText": " import { SomeInterface } from \"http://localhost:4545/subdir/imports_declaration/interface.d.ts\";\n", + }, + ], + }), + ); + client.shutdown(); +} + #[test] fn lsp_npm_specifier_unopened_file() { let context = TestContextBuilder::new() diff --git a/tests/testdata/subdir/imports_declaration/imports_interface.ts b/tests/testdata/subdir/imports_declaration/imports_interface.ts new file mode 100644 index 0000000000..5eb2e64d51 --- /dev/null +++ b/tests/testdata/subdir/imports_declaration/imports_interface.ts @@ -0,0 +1,3 @@ +import type { SomeInterface } from "./interface.d.ts"; + +export const someObject: SomeInterface = { someField: "someValue" }; diff --git a/tests/testdata/subdir/imports_declaration/interface.d.ts b/tests/testdata/subdir/imports_declaration/interface.d.ts new file mode 100644 index 0000000000..e1531905b9 --- /dev/null +++ b/tests/testdata/subdir/imports_declaration/interface.d.ts @@ -0,0 +1,3 @@ +export interface SomeInterface { + someField: string; +}