Repository: denoland/deno
Pull request: fix(lsp): import map lookup for jsr subpath auto import

Fixes bug reported by @lucacasonato.

Changed files:
filename: cli/lsp/analysis.rs
patch: @@ -312,6 +312,16 @@ impl<'a> TsResponseImportMapper<'a> {
         if let Some(result) = import_map.lookup(&specifier, referrer) {
           return Some(result);
         }
+        if let Some(req_ref_str) = specifier.as_str().strip_prefix("jsr:") {
+          if !req_ref_str.starts_with('/') {
+            let specifier_str = format!("jsr:/{req_ref_str}");
+            if let Ok(specifier) = ModuleSpecifier::parse(&specifier_str) {
+              if let Some(result) = import_map.lookup(&specifier, referrer) {
+                return Some(result);
+              }
+            }
+          }
+        }
       }
       return Some(spec_str);
     }

filename: tests/integration/lsp_tests.rs
patch: @@ -5482,6 +5482,80 @@ fn lsp_jsr_auto_import_completion_import_map() {
   client.shutdown();
 }
 
+#[test]
+fn lsp_jsr_auto_import_completion_import_map_sub_path() {
+  let context = TestContextBuilder::new()
+    .use_http_server()
+    .use_temp_cwd()
+    .build();
+  let temp_dir = context.temp_dir();
+  temp_dir.write(
+    "deno.json",
+    json!({
+      "imports": {
+        "@std/path": "jsr:@std/path@^0.220.1",
+      },
+    })
+    .to_string(),
+  );
+  let file = source_file(
+    temp_dir.path().join("file.ts"),
+    r#"
+      // Adds jsr:@std/path@^0.220.1/normalize to the module graph.
+      import "jsr:@std/url@^0.220.1/normalize";
+      normalize
+    "#,
+  );
+  let mut client = context.new_lsp_command().build();
+  client.initialize_default();
+  client.write_request(
+    "workspace/executeCommand",
+    json!({
+      "command": "deno.cache",
+      "arguments": [[], file.uri()],
+    }),
+  );
+  client.read_diagnostics();
+  client.did_open_file(&file);
+  let list = client.get_completion_list(
+    file.uri(),
+    (3, 15),
+    json!({ "triggerKind": 1 }),
+  );
+  let item = list
+    .items
+    .iter()
+    .find(|i| {
+      i.label == "normalize"
+        && json!(&i.label_details)
+          .to_string()
+          .contains("\"@std/path/posix/normalize\"")
+    })
+    .unwrap();
+  let res = client.write_request("completionItem/resolve", json!(item));
+  assert_eq!(
+    res,
+    json!({
+      "label": "normalize",
+      "labelDetails": { "description": "@std/path/posix/normalize" },
+      "kind": 3,
+      "detail": "function normalize(path: string): string",
+      "documentation": { "kind": "markdown", "value": "Normalize the `path`, resolving `'..'` and `'.'` segments.\nNote that resolving these segments does not necessarily mean that all will be eliminated.\nA `'..'` at the top-level will be preserved, and an empty path is canonically `'.'`.\n\n*@param* - path to be normalized" },
+      "sortText": "\u{ffff}16_0",
+      "additionalTextEdits": [
+        {
+          "range": {
+            "start": { "line": 2, "character": 6 },
+            "end": { "line": 2, "character": 6 },
+          },
+          "newText": "import { normalize } from \"@std/path/posix/normalize\";\n",
+        },
+      ],
+    }),
+  );
+  client.shutdown();
+}
+
 #[test]
 fn lsp_jsr_code_action_missing_declaration() {
   let context = TestContextBuilder::new()

filename: tests/registry/jsr/@std/url/0.220.1/join.ts
patch: @@ -1,7 +1,7 @@
 // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
 // This module is browser compatible.
 
-import { join as posixJoin } from "jsr:/@std/path@^0.220.1/posix/join";
+import { join as posixJoin } from "jsr:@std/path@^0.220.1/posix/join";
 
 /**
  * Join a base `URL` and a series of `paths`, then normalizes the resulting URL.

filename: tests/registry/jsr/@std/url/0.220.1/normalize.ts
patch: @@ -1,7 +1,7 @@
 // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
 // This module is browser compatible.
 
-import { normalize as posixNormalize } from "jsr:/@std/path@^0.220.1/posix/normalize";
+import { normalize as posixNormalize } from "jsr:@std/path@^0.220.1/posix/normalize";
 
 /**
  * Normalize the `URL`, resolving `'..'` and `'.'` segments and multiple