diff options
author | hrsh7th <hrsh7th@gmail.com> | 2020-12-30 09:58:20 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-30 11:58:20 +1100 |
commit | 57b0562957f0887611526bf7e878ac34fdcd6393 (patch) | |
tree | cf419c9892b2d0275a7d9ffa79a4e79728fd5b97 /cli/lsp/tsc.rs | |
parent | d5f3a749eb9b86ed24378a3ee39ee443c374da53 (diff) |
feat(lsp): Implement textDocument/rename (#8910)
Diffstat (limited to 'cli/lsp/tsc.rs')
-rw-r--r-- | cli/lsp/tsc.rs | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs index 2a0f7d76c..fde3e37b9 100644 --- a/cli/lsp/tsc.rs +++ b/cli/lsp/tsc.rs @@ -22,6 +22,7 @@ use deno_core::serde::Serialize; use deno_core::serde_json; use deno_core::serde_json::json; use deno_core::serde_json::Value; +use deno_core::url::Url; use deno_core::JsRuntime; use deno_core::ModuleSpecifier; use deno_core::OpFn; @@ -412,6 +413,85 @@ impl QuickInfo { } #[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct RenameLocation { + // inherit from DocumentSpan + text_span: TextSpan, + file_name: String, + original_text_span: Option<TextSpan>, + original_file_name: Option<String>, + context_span: Option<TextSpan>, + original_context_span: Option<TextSpan>, + // RenameLocation props + prefix_text: Option<String>, + suffix_text: Option<String>, +} + +pub struct RenameLocations { + pub locations: Vec<RenameLocation>, +} + +impl RenameLocations { + pub async fn into_workspace_edit<F, Fut>( + self, + snapshot: StateSnapshot, + index_provider: F, + new_name: &str, + ) -> Result<lsp_types::WorkspaceEdit, AnyError> + where + F: Fn(ModuleSpecifier) -> Fut, + Fut: Future<Output = Result<Vec<u32>, AnyError>>, + { + let mut text_document_edit_map: HashMap<Url, lsp_types::TextDocumentEdit> = + HashMap::new(); + for location in self.locations.iter() { + let uri = utils::normalize_file_name(&location.file_name)?; + let specifier = ModuleSpecifier::resolve_url(&location.file_name)?; + + // ensure TextDocumentEdit for `location.file_name`. + if text_document_edit_map.get(&uri).is_none() { + text_document_edit_map.insert( + uri.clone(), + lsp_types::TextDocumentEdit { + text_document: lsp_types::OptionalVersionedTextDocumentIdentifier { + uri: uri.clone(), + version: snapshot + .doc_data + .get(&specifier) + .map_or_else(|| None, |data| data.version), + }, + edits: Vec::< + lsp_types::OneOf< + lsp_types::TextEdit, + lsp_types::AnnotatedTextEdit, + >, + >::new(), + }, + ); + } + + // push TextEdit for ensured `TextDocumentEdit.edits`. + let document_edit = text_document_edit_map.get_mut(&uri).unwrap(); + document_edit + .edits + .push(lsp_types::OneOf::Left(lsp_types::TextEdit { + range: location + .text_span + .to_range(&index_provider(specifier.clone()).await?), + new_text: new_name.to_string(), + })); + } + + Ok(lsp_types::WorkspaceEdit { + changes: None, + document_changes: Some(lsp_types::DocumentChanges::Edits( + text_document_edit_map.values().cloned().collect(), + )), + }) + } +} + +#[derive(Debug, Deserialize)] pub enum HighlightSpanKind { #[serde(rename = "none")] None, @@ -1059,6 +1139,8 @@ pub enum RequestMethod { GetDefinition((ModuleSpecifier, u32)), /// Get completion information at a given position (IntelliSense). GetCompletions((ModuleSpecifier, u32, UserPreferences)), + /// Get rename locations at a given position. + FindRenameLocations((ModuleSpecifier, u32, bool, bool, bool)), } impl RequestMethod { @@ -1127,6 +1209,23 @@ impl RequestMethod { "preferences": preferences, }) } + RequestMethod::FindRenameLocations(( + specifier, + position, + find_in_strings, + find_in_comments, + provide_prefix_and_suffix_text_for_rename, + )) => { + json!({ + "id": id, + "method": "findRenameLocations", + "specifier": specifier, + "position": position, + "findInStrings": find_in_strings, + "findInComments": find_in_comments, + "providePrefixAndSuffixTextForRename": provide_prefix_and_suffix_text_for_rename + }) + } } } } |