1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-24 15:19:26 -05:00

feat(lsp): include registry url in jsr import hover text (#22676)

This commit is contained in:
Nayeem Rahman 2024-03-04 15:48:23 +00:00 committed by GitHub
parent d4b3b39cc0
commit 625a9319f6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 105 additions and 38 deletions

View file

@ -92,9 +92,8 @@ impl JsrCacheResolver {
pub fn jsr_to_registry_url(
&self,
specifier: &ModuleSpecifier,
req_ref: &JsrPackageReqReference,
) -> Option<ModuleSpecifier> {
let req_ref = JsrPackageReqReference::from_str(specifier.as_str()).ok()?;
let req = req_ref.req().clone();
let maybe_nv = self.req_to_nv(&req);
let nv = maybe_nv.as_ref()?;

View file

@ -35,7 +35,6 @@ use deno_core::error::AnyError;
use deno_core::futures::future;
use deno_core::futures::FutureExt;
use deno_core::parking_lot::Mutex;
use deno_core::url;
use deno_core::ModuleSpecifier;
use deno_graph::source::ResolutionMode;
use deno_graph::GraphImport;
@ -48,6 +47,7 @@ use deno_runtime::deno_node::NodeResolutionMode;
use deno_runtime::deno_node::NodeResolver;
use deno_runtime::deno_node::PackageJson;
use deno_runtime::permissions::PermissionsContainer;
use deno_semver::jsr::JsrPackageReqReference;
use deno_semver::npm::NpmPackageReqReference;
use deno_semver::package::PackageReq;
use indexmap::IndexMap;
@ -643,26 +643,6 @@ impl Document {
}
}
pub fn to_hover_text(result: &Resolution) -> String {
match result {
Resolution::Ok(resolved) => {
let specifier = &resolved.specifier;
match specifier.scheme() {
"data" => "_(a data url)_".to_string(),
"blob" => "_(a blob url)_".to_string(),
_ => format!(
"{}&#8203;{}",
&specifier[..url::Position::AfterScheme],
&specifier[url::Position::AfterScheme..],
)
.replace('@', "&#8203;@"),
}
}
Resolution::Err(_) => "_[errored]_".to_string(),
Resolution::None => "_[missing]_".to_string(),
}
}
pub fn to_lsp_range(range: &deno_graph::Range) -> lsp::Range {
lsp::Range {
start: lsp::Position {
@ -1086,9 +1066,12 @@ impl Documents {
.into_owned(),
)
} else {
let specifier = match self.jsr_resolver.jsr_to_registry_url(specifier) {
Some(url) => Cow::Owned(url),
None => Cow::Borrowed(specifier),
let specifier = if let Ok(jsr_req_ref) =
JsrPackageReqReference::from_specifier(specifier)
{
Cow::Owned(self.jsr_resolver.jsr_to_registry_url(&jsr_req_ref)?)
} else {
Cow::Borrowed(specifier)
};
self.redirect_resolver.resolve(&specifier)
}

View file

@ -11,8 +11,10 @@ use deno_core::serde_json;
use deno_core::serde_json::json;
use deno_core::serde_json::Value;
use deno_core::unsync::spawn;
use deno_core::url;
use deno_core::ModuleSpecifier;
use deno_graph::GraphKind;
use deno_graph::Resolution;
use deno_lockfile::Lockfile;
use deno_npm::NpmSystemInfo;
use deno_runtime::deno_fs;
@ -20,6 +22,7 @@ use deno_runtime::deno_node::NodeResolver;
use deno_runtime::deno_node::PackageJson;
use deno_runtime::deno_tls::rustls::RootCertStore;
use deno_runtime::deno_tls::RootCertStoreProvider;
use deno_semver::jsr::JsrPackageReqReference;
use import_map::ImportMap;
use indexmap::IndexSet;
use log::error;
@ -62,7 +65,6 @@ use super::diagnostics::DiagnosticDataSpecifier;
use super::diagnostics::DiagnosticServerUpdateMessage;
use super::diagnostics::DiagnosticsServer;
use super::diagnostics::DiagnosticsState;
use super::documents::to_hover_text;
use super::documents::to_lsp_range;
use super::documents::AssetOrDocument;
use super::documents::Document;
@ -1866,32 +1868,32 @@ impl Inner {
let value = match (dep.maybe_code.is_none(), dep.maybe_type.is_none(), &dep_maybe_types_dependency) {
(false, false, None) => format!(
"**Resolved Dependency**\n\n**Code**: {}\n\n**Types**: {}\n",
to_hover_text(&dep.maybe_code),
to_hover_text(&dep.maybe_type)
self.resolution_to_hover_text(&dep.maybe_code),
self.resolution_to_hover_text(&dep.maybe_type),
),
(false, false, Some(types_dep)) if !types_dep.is_none() => format!(
"**Resolved Dependency**\n\n**Code**: {}\n**Types**: {}\n**Import Types**: {}\n",
to_hover_text(&dep.maybe_code),
to_hover_text(&dep.maybe_type),
to_hover_text(types_dep)
self.resolution_to_hover_text(&dep.maybe_code),
self.resolution_to_hover_text(&dep.maybe_type),
self.resolution_to_hover_text(types_dep),
),
(false, false, Some(_)) => format!(
"**Resolved Dependency**\n\n**Code**: {}\n\n**Types**: {}\n",
to_hover_text(&dep.maybe_code),
to_hover_text(&dep.maybe_type)
self.resolution_to_hover_text(&dep.maybe_code),
self.resolution_to_hover_text(&dep.maybe_type),
),
(false, true, Some(types_dep)) if !types_dep.is_none() => format!(
"**Resolved Dependency**\n\n**Code**: {}\n\n**Types**: {}\n",
to_hover_text(&dep.maybe_code),
to_hover_text(types_dep)
self.resolution_to_hover_text(&dep.maybe_code),
self.resolution_to_hover_text(types_dep),
),
(false, true, _) => format!(
"**Resolved Dependency**\n\n**Code**: {}\n",
to_hover_text(&dep.maybe_code)
self.resolution_to_hover_text(&dep.maybe_code),
),
(true, false, _) => format!(
"**Resolved Dependency**\n\n**Types**: {}\n",
to_hover_text(&dep.maybe_type)
self.resolution_to_hover_text(&dep.maybe_type),
),
(true, true, _) => unreachable!("{}", json!(params)),
};
@ -1922,6 +1924,40 @@ impl Inner {
Ok(hover)
}
fn resolution_to_hover_text(&self, resolution: &Resolution) -> String {
match resolution {
Resolution::Ok(resolved) => {
let specifier = &resolved.specifier;
match specifier.scheme() {
"data" => "_(a data url)_".to_string(),
"blob" => "_(a blob url)_".to_string(),
_ => {
let mut result = format!(
"{}&#8203;{}",
&specifier[..url::Position::AfterScheme],
&specifier[url::Position::AfterScheme..],
)
.replace('@', "&#8203;@");
if let Ok(jsr_req_ref) =
JsrPackageReqReference::from_specifier(specifier)
{
if let Some(url) = self
.documents
.get_jsr_resolver()
.jsr_to_registry_url(&jsr_req_ref)
{
result = format!("{result} (<{url}>)");
}
}
result
}
}
}
Resolution::Err(_) => "_[errored]_".to_string(),
Resolution::None => "_[missing]_".to_string(),
}
}
async fn code_action(
&self,
params: CodeActionParams,

View file

@ -2514,6 +2514,55 @@ fn lsp_hover_typescript_types() {
client.shutdown();
}
#[test]
fn lsp_hover_jsr() {
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.uri().join("file.ts").unwrap(),
"languageId": "typescript",
"version": 1,
"text": "import \"jsr:@denotest/add@1.0.0\";\n",
}
}));
client.write_request(
"workspace/executeCommand",
json!({
"command": "deno.cache",
"arguments": [[], temp_dir.uri().join("file.ts").unwrap()],
}),
);
let res = client.write_request(
"textDocument/hover",
json!({
"textDocument": {
"uri": temp_dir.uri().join("file.ts").unwrap(),
},
"position": { "line": 0, "character": 7 },
}),
);
assert_eq!(
res,
json!({
"contents": {
"kind": "markdown",
"value": "**Resolved Dependency**\n\n**Code**: jsr&#8203;:&#8203;@denotest/add&#8203;@1.0.0 (<http://127.0.0.1:4250/@denotest/add/1.0.0/mod.ts>)\n",
},
"range": {
"start": { "line": 0, "character": 7 },
"end": { "line": 0, "character": 32 },
},
}),
);
client.shutdown();
}
#[test]
fn lsp_hover_jsdoc_symbol_link() {
let context = TestContextBuilder::new().use_temp_cwd().build();