summaryrefslogtreecommitdiff
path: root/cli/lsp/tsc.rs
diff options
context:
space:
mode:
authorhrsh7th <hrsh7th@gmail.com>2020-12-30 09:58:20 +0900
committerGitHub <noreply@github.com>2020-12-30 11:58:20 +1100
commit57b0562957f0887611526bf7e878ac34fdcd6393 (patch)
treecf419c9892b2d0275a7d9ffa79a4e79728fd5b97 /cli/lsp/tsc.rs
parentd5f3a749eb9b86ed24378a3ee39ee443c374da53 (diff)
feat(lsp): Implement textDocument/rename (#8910)
Diffstat (limited to 'cli/lsp/tsc.rs')
-rw-r--r--cli/lsp/tsc.rs99
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
+ })
+ }
}
}
}