diff options
author | Kitson Kelly <me@kitsonkelly.com> | 2022-01-07 11:27:13 +1100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-07 11:27:13 +1100 |
commit | 57bfa87b2c56809eedcc64bf63be9dcdd6c7400f (patch) | |
tree | a93fe2d056323754f8d45d64c5fbc7204b06ee12 /cli | |
parent | 2067820714fea49be1692fa678754488ace8228b (diff) |
feat(lsp): provide registry details on hover if present (#13294)
Closes: #13272
Diffstat (limited to 'cli')
-rw-r--r-- | cli/lsp/documents.rs | 3 | ||||
-rw-r--r-- | cli/lsp/language_server.rs | 6 | ||||
-rw-r--r-- | cli/lsp/registries.rs | 57 | ||||
-rw-r--r-- | cli/tests/integration/lsp_tests.rs | 39 | ||||
-rw-r--r-- | cli/tests/testdata/lsp/did_open_params_import_hover.json | 2 | ||||
-rw-r--r-- | cli/tests/testdata/lsp/initialize_params_registry.json | 4 | ||||
-rw-r--r-- | cli/tests/testdata/lsp/registries/deno-import-intellisense.json | 2 | ||||
-rw-r--r-- | cli/tests/testdata/lsp/registries/doc_a_latest_mod.ts.json | 4 |
8 files changed, 111 insertions, 6 deletions
diff --git a/cli/lsp/documents.rs b/cli/lsp/documents.rs index 1125d381f..3fe14a168 100644 --- a/cli/lsp/documents.rs +++ b/cli/lsp/documents.rs @@ -590,7 +590,8 @@ pub(crate) fn to_hover_text( "{}​{}", specifier[..url::Position::AfterScheme].to_string(), specifier[url::Position::AfterScheme..].to_string() - ), + ) + .replace('@', "​@"), }, Err(_) => "_[errored]_".to_string(), } diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index 5f28365fa..46c61a03e 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -1119,6 +1119,12 @@ impl Inner { ), (None, None, _) => unreachable!("{}", json!(params)), }; + let value = + if let Some(docs) = self.module_registries.get_hover(&dep).await { + format!("{}\n\n---\n\n{}", value, docs) + } else { + value + }; Some(Hover { contents: HoverContents::Markup(MarkupContent { kind: MarkupKind::Markdown, diff --git a/cli/lsp/registries.rs b/cli/lsp/registries.rs index 93333dd92..9b967c3c2 100644 --- a/cli/lsp/registries.rs +++ b/cli/lsp/registries.rs @@ -27,6 +27,7 @@ use deno_core::url::ParseError; use deno_core::url::Position; use deno_core::url::Url; use deno_core::ModuleSpecifier; +use deno_graph::Dependency; use deno_runtime::deno_web::BlobStore; use deno_runtime::permissions::Permissions; use log::error; @@ -565,6 +566,60 @@ impl ModuleRegistry { Ok(()) } + pub(crate) async fn get_hover( + &self, + dependency: &Dependency, + ) -> Option<String> { + let maybe_code = dependency.get_code(); + let maybe_type = dependency.get_type(); + let specifier = match (maybe_code, maybe_type) { + (Some(specifier), _) => Some(specifier), + (_, Some(specifier)) => Some(specifier), + _ => None, + }?; + let origin = base_url(specifier); + let registries = self.origins.get(&origin)?; + let path = &specifier[Position::BeforePath..]; + for registry in registries { + let tokens = parse(®istry.schema, None).ok()?; + let matcher = Matcher::new(&tokens, None).ok()?; + if let Some(match_result) = matcher.matches(path) { + let key = if let Some(Token::Key(key)) = tokens.iter().last() { + Some(key) + } else { + None + }?; + let url = registry.get_documentation_url_for_key(key)?; + let endpoint = get_endpoint_with_match( + key, + url, + specifier, + &tokens, + &match_result, + None, + ) + .ok()?; + let file = self + .file_fetcher + .fetch(&endpoint, &mut Permissions::allow_all()) + .await + .ok()?; + let documentation: lsp::Documentation = + serde_json::from_str(&file.source).ok()?; + return match documentation { + lsp::Documentation::String(doc) => Some(doc), + lsp::Documentation::MarkupContent(lsp::MarkupContent { + value, + .. + }) => Some(value), + _ => None, + }; + } + } + + None + } + /// For a string specifier from the client, provide a set of completions, if /// any, for the specifier. pub(crate) async fn get_completions( @@ -858,7 +913,7 @@ impl ModuleRegistry { self.get_origin_completions(current_specifier, range) } - pub async fn get_documentation( + pub(crate) async fn get_documentation( &self, url: &str, ) -> Option<lsp::Documentation> { diff --git a/cli/tests/integration/lsp_tests.rs b/cli/tests/integration/lsp_tests.rs index a3e1138b6..6a7002b49 100644 --- a/cli/tests/integration/lsp_tests.rs +++ b/cli/tests/integration/lsp_tests.rs @@ -3044,7 +3044,8 @@ fn lsp_cache_location() { let _g = http_server(); let temp_dir = TempDir::new().expect("could not create temp dir"); let mut params: lsp::InitializeParams = - serde_json::from_value(load_fixture("initialize_params.json")).unwrap(); + serde_json::from_value(load_fixture("initialize_params_registry.json")) + .unwrap(); params.root_uri = Some(Url::from_file_path(temp_dir.path()).unwrap()); if let Some(Value::Object(mut map)) = params.initialization_options { @@ -3075,7 +3076,7 @@ fn lsp_cache_location() { load_fixture("did_open_params_import_hover.json"), ); let diagnostics = diagnostics.into_iter().flat_map(|x| x.diagnostics); - assert_eq!(diagnostics.count(), 12); + assert_eq!(diagnostics.count(), 14); let (maybe_res, maybe_err) = client .write_request::<_, _, Value>( "deno/cache", @@ -3123,6 +3124,40 @@ fn lsp_cache_location() { } })) ); + let (maybe_res, maybe_err) = client + .write_request::<_, _, Value>( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + }, + "position": { + "line": 7, + "character": 28 + } + }), + ) + .unwrap(); + assert!(maybe_err.is_none()); + assert_eq!( + maybe_res, + Some(json!({ + "contents": { + "kind": "markdown", + "value": "**Resolved Dependency**\n\n**Code**: http​://localhost:4545/x/a/mod.ts\n\n\n---\n\n**a**\n\nmod.ts" + }, + "range": { + "start": { + "line": 7, + "character": 19 + }, + "end": { + "line": 7, + "character": 53 + } + } + })) + ); let cache_path = temp_dir.path().join(".cache"); assert!(cache_path.is_dir()); assert!(cache_path.join("gen").is_dir()); diff --git a/cli/tests/testdata/lsp/did_open_params_import_hover.json b/cli/tests/testdata/lsp/did_open_params_import_hover.json index e054eef3e..a79ba0d7f 100644 --- a/cli/tests/testdata/lsp/did_open_params_import_hover.json +++ b/cli/tests/testdata/lsp/did_open_params_import_hover.json @@ -3,6 +3,6 @@ "uri": "file:///a/file.ts", "languageId": "typescript", "version": 1, - "text": "import * as a from \"http://127.0.0.1:4545/xTypeScriptTypes.js\";\n// @deno-types=\"http://127.0.0.1:4545/type_definitions/foo.d.ts\"\nimport * as b from \"http://127.0.0.1:4545/type_definitions/foo.js\";\nimport * as c from \"http://127.0.0.1:4545/subdir/type_reference.js\";\nimport * as d from \"http://127.0.0.1:4545/subdir/mod1.ts\";\nimport * as e from \"data:application/typescript;base64,ZXhwb3J0IGNvbnN0IGEgPSAiYSI7CgpleHBvcnQgZW51bSBBIHsKICBBLAogIEIsCiAgQywKfQo=\";\nimport * as f from \"./file_01.ts\";\n\nconsole.log(a, b, c, d, e, f);\n" + "text": "import * as a from \"http://127.0.0.1:4545/xTypeScriptTypes.js\";\n// @deno-types=\"http://127.0.0.1:4545/type_definitions/foo.d.ts\"\nimport * as b from \"http://127.0.0.1:4545/type_definitions/foo.js\";\nimport * as c from \"http://127.0.0.1:4545/subdir/type_reference.js\";\nimport * as d from \"http://127.0.0.1:4545/subdir/mod1.ts\";\nimport * as e from \"data:application/typescript;base64,ZXhwb3J0IGNvbnN0IGEgPSAiYSI7CgpleHBvcnQgZW51bSBBIHsKICBBLAogIEIsCiAgQywKfQo=\";\nimport * as f from \"./file_01.ts\";\nimport * as g from \"http://localhost:4545/x/a/mod.ts\";\n\nconsole.log(a, b, c, d, e, f, g);\n" } } diff --git a/cli/tests/testdata/lsp/initialize_params_registry.json b/cli/tests/testdata/lsp/initialize_params_registry.json index 67559ebb3..286f6085f 100644 --- a/cli/tests/testdata/lsp/initialize_params_registry.json +++ b/cli/tests/testdata/lsp/initialize_params_registry.json @@ -10,8 +10,10 @@ "cache": null, "codeLens": { "implementations": true, - "references": true + "references": true, + "test": true }, + "config": "", "importMap": null, "lint": true, "suggest": { diff --git a/cli/tests/testdata/lsp/registries/deno-import-intellisense.json b/cli/tests/testdata/lsp/registries/deno-import-intellisense.json index 7fe514dc0..5fd87085e 100644 --- a/cli/tests/testdata/lsp/registries/deno-import-intellisense.json +++ b/cli/tests/testdata/lsp/registries/deno-import-intellisense.json @@ -16,6 +16,7 @@ }, { "key": "path", + "documentation": "/lsp/registries/doc_${module}_${{version}}_${path}.json", "url": "/lsp/registries/${module}_${{version}}_${path}.json" } ] @@ -30,6 +31,7 @@ }, { "key": "path", + "documentation": "/lsp/registries/doc_${module}_latest_${path}.json", "url": "/lsp/registries/${module}_latest_${path}.json" } ] diff --git a/cli/tests/testdata/lsp/registries/doc_a_latest_mod.ts.json b/cli/tests/testdata/lsp/registries/doc_a_latest_mod.ts.json new file mode 100644 index 000000000..522f5b271 --- /dev/null +++ b/cli/tests/testdata/lsp/registries/doc_a_latest_mod.ts.json @@ -0,0 +1,4 @@ +{ + "kind": "markdown", + "value": "**a**\n\nmod.ts" +} |