diff options
Diffstat (limited to 'cli/lsp')
-rw-r--r-- | cli/lsp/capabilities.rs | 5 | ||||
-rw-r--r-- | cli/lsp/language_server.rs | 55 | ||||
-rw-r--r-- | cli/lsp/tsc.rs | 16 |
3 files changed, 74 insertions, 2 deletions
diff --git a/cli/lsp/capabilities.rs b/cli/lsp/capabilities.rs index e05cc27b8..8f17a6aff 100644 --- a/cli/lsp/capabilities.rs +++ b/cli/lsp/capabilities.rs @@ -27,6 +27,7 @@ use lspower::lsp::SignatureHelpOptions; use lspower::lsp::TextDocumentSyncCapability; use lspower::lsp::TextDocumentSyncKind; use lspower::lsp::TextDocumentSyncOptions; +use lspower::lsp::TypeDefinitionProviderCapability; use lspower::lsp::WorkDoneProgressOptions; use lspower::lsp::WorkspaceFoldersServerCapabilities; use lspower::lsp::WorkspaceServerCapabilities; @@ -109,7 +110,9 @@ pub fn server_capabilities( }), declaration_provider: None, definition_provider: Some(OneOf::Left(true)), - type_definition_provider: None, + type_definition_provider: Some(TypeDefinitionProviderCapability::Simple( + true, + )), implementation_provider: Some(ImplementationProviderCapability::Simple( true, )), diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index fb2b04214..a0d0ee0ad 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -1622,6 +1622,54 @@ impl Inner { } } + async fn goto_type_definition( + &mut self, + params: GotoTypeDefinitionParams, + ) -> LspResult<Option<GotoTypeDefinitionResponse>> { + let specifier = self + .url_map + .normalize_url(¶ms.text_document_position_params.text_document.uri); + if !self.is_diagnosable(&specifier) + || !self.config.specifier_enabled(&specifier) + { + return Ok(None); + } + + let mark = self.performance.mark("goto_definition", Some(¶ms)); + let asset_or_doc = self.get_cached_asset_or_document(&specifier)?; + let line_index = asset_or_doc.line_index(); + let req = tsc::RequestMethod::GetTypeDefinition { + specifier, + position: line_index + .offset_tsc(params.text_document_position_params.position)?, + }; + let maybe_definition_info: Option<Vec<tsc::DefinitionInfo>> = self + .ts_server + .request(self.snapshot()?, req) + .await + .map_err(|err| { + error!("Unable to get type definition from TypeScript: {}", err); + LspError::internal_error() + })?; + + let response = if let Some(definition_info) = maybe_definition_info { + let mut location_links = Vec::new(); + for info in definition_info { + if let Some(link) = + info.document_span.to_link(line_index.clone(), self).await + { + location_links.push(link); + } + } + Some(GotoTypeDefinitionResponse::Link(location_links)) + } else { + None + }; + + self.performance.measure(mark); + Ok(response) + } + async fn completion( &mut self, params: CompletionParams, @@ -2428,6 +2476,13 @@ impl lspower::LanguageServer for LanguageServer { self.0.lock().await.goto_definition(params).await } + async fn goto_type_definition( + &self, + params: GotoTypeDefinitionParams, + ) -> LspResult<Option<GotoTypeDefinitionResponse>> { + self.0.lock().await.goto_type_definition(params).await + } + async fn completion( &self, params: CompletionParams, diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs index e56b7ab68..9647a79fc 100644 --- a/cli/lsp/tsc.rs +++ b/cli/lsp/tsc.rs @@ -2769,6 +2769,11 @@ pub enum RequestMethod { GetSmartSelectionRange((ModuleSpecifier, u32)), /// Get the diagnostic codes that support some form of code fix. GetSupportedCodeFixes, + /// Get the type definition information for a specific position. + GetTypeDefinition { + specifier: ModuleSpecifier, + position: u32, + }, /// Resolve a call hierarchy item for a specific position. PrepareCallHierarchy((ModuleSpecifier, u32)), /// Resolve incoming call hierarchy items for a specific position. @@ -2811,7 +2816,7 @@ impl RequestMethod { "id": id, "method": "getApplicableRefactors", "specifier": state.denormalize_specifier(specifier), - "range": { "pos": span.start, "end": span.start + span.length}, + "range": { "pos": span.start, "end": span.start + span.length }, "kind": kind, }), RequestMethod::GetEditsForRefactor(( @@ -2950,6 +2955,15 @@ impl RequestMethod { "id": id, "method": "getSupportedCodeFixes", }), + RequestMethod::GetTypeDefinition { + specifier, + position, + } => json!({ + "id": id, + "method": "getTypeDefinition", + "specifier": state.denormalize_specifier(specifier), + "position": position + }), RequestMethod::PrepareCallHierarchy((specifier, position)) => { json!({ "id": id, |