about summary refs log tree commit diff
diff options
context:
space:
mode:
authorKirill Bulatov <mail4score@gmail.com>2023-09-19 21:34:43 +0300
committerKirill Bulatov <mail4score@gmail.com>2023-09-19 21:40:22 +0300
commit184119258e256b656f30d89ea5e1512fe1d927db (patch)
treee2a81c76ac96b3461be8b867ad1340f14e4c90d0
parent22b18b9f77eb632b58d207f937b7af42216dd62e (diff)
Do not resolve inlayHint.textEdit for VSCode client
VSCode behaves strangely, allowing to navigate into label location, but
not allowing to apply hint's text edit, after hint is resolved.
See https://github.com/microsoft/vscode/issues/193124 for details.

For now, stub hint resolution for VSCode specifically.
-rw-r--r--crates/rust-analyzer/src/bin/main.rs12
-rw-r--r--crates/rust-analyzer/src/config.rs33
-rw-r--r--crates/rust-analyzer/src/diagnostics/to_proto.rs7
-rw-r--r--crates/rust-analyzer/src/lsp/to_proto.rs3
-rw-r--r--crates/rust-analyzer/tests/slow-tests/support.rs1
5 files changed, 43 insertions, 13 deletions
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs
index 2fa14fc7e28..c1d0d24b96d 100644
--- a/crates/rust-analyzer/src/bin/main.rs
+++ b/crates/rust-analyzer/src/bin/main.rs
@@ -190,6 +190,12 @@ fn run_server() -> anyhow::Result<()> {
         }
     };
 
+    let mut is_visual_studio = false;
+    if let Some(client_info) = client_info {
+        tracing::info!("Client '{}' {}", client_info.name, client_info.version.unwrap_or_default());
+        is_visual_studio = client_info.name == "Visual Studio Code";
+    }
+
     let workspace_roots = workspace_folders
         .map(|workspaces| {
             workspaces
@@ -201,7 +207,7 @@ fn run_server() -> anyhow::Result<()> {
         })
         .filter(|workspaces| !workspaces.is_empty())
         .unwrap_or_else(|| vec![root_path.clone()]);
-    let mut config = Config::new(root_path, capabilities, workspace_roots);
+    let mut config = Config::new(root_path, capabilities, workspace_roots, is_visual_studio);
     if let Some(json) = initialization_options {
         if let Err(e) = config.update(json) {
             use lsp_types::{
@@ -231,10 +237,6 @@ fn run_server() -> anyhow::Result<()> {
 
     connection.initialize_finish(initialize_id, initialize_result)?;
 
-    if let Some(client_info) = client_info {
-        tracing::info!("Client '{}' {}", client_info.name, client_info.version.unwrap_or_default());
-    }
-
     if !config.has_linked_projects() && config.detached_files().is_empty() {
         config.rediscover_workspaces();
     }
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index ea3a21241cb..683b3deb6ee 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -565,6 +565,7 @@ pub struct Config {
     data: ConfigData,
     detached_files: Vec<AbsPathBuf>,
     snippets: Vec<Snippet>,
+    is_visual_studio: bool,
 }
 
 type ParallelCachePrimingNumThreads = u8;
@@ -760,6 +761,7 @@ impl Config {
         root_path: AbsPathBuf,
         caps: ClientCapabilities,
         workspace_roots: Vec<AbsPathBuf>,
+        is_visual_studio: bool,
     ) -> Self {
         Config {
             caps,
@@ -769,6 +771,7 @@ impl Config {
             root_path,
             snippets: Default::default(),
             workspace_roots,
+            is_visual_studio,
         }
     }
 
@@ -1667,6 +1670,12 @@ impl Config {
     pub fn typing_autoclose_angle(&self) -> bool {
         self.data.typing_autoClosingAngleBrackets_enable
     }
+
+    // FIXME: VSCode seems to work wrong sometimes, see https://github.com/microsoft/vscode/issues/193124
+    // hence, distinguish it for now.
+    pub fn is_visual_studio(&self) -> bool {
+        self.is_visual_studio
+    }
 }
 // Deserialization definitions
 
@@ -2555,8 +2564,12 @@ mod tests {
 
     #[test]
     fn proc_macro_srv_null() {
-        let mut config =
-            Config::new(AbsPathBuf::try_from(project_root()).unwrap(), Default::default(), vec![]);
+        let mut config = Config::new(
+            AbsPathBuf::try_from(project_root()).unwrap(),
+            Default::default(),
+            vec![],
+            false,
+        );
         config
             .update(serde_json::json!({
                 "procMacro_server": null,
@@ -2567,8 +2580,12 @@ mod tests {
 
     #[test]
     fn proc_macro_srv_abs() {
-        let mut config =
-            Config::new(AbsPathBuf::try_from(project_root()).unwrap(), Default::default(), vec![]);
+        let mut config = Config::new(
+            AbsPathBuf::try_from(project_root()).unwrap(),
+            Default::default(),
+            vec![],
+            false,
+        );
         config
             .update(serde_json::json!({
                 "procMacro": {"server": project_root().display().to_string()}
@@ -2579,8 +2596,12 @@ mod tests {
 
     #[test]
     fn proc_macro_srv_rel() {
-        let mut config =
-            Config::new(AbsPathBuf::try_from(project_root()).unwrap(), Default::default(), vec![]);
+        let mut config = Config::new(
+            AbsPathBuf::try_from(project_root()).unwrap(),
+            Default::default(),
+            vec![],
+            false,
+        );
         config
             .update(serde_json::json!({
                 "procMacro": {"server": "./server"}
diff --git a/crates/rust-analyzer/src/diagnostics/to_proto.rs b/crates/rust-analyzer/src/diagnostics/to_proto.rs
index 731580557c2..f8bc66ff8e7 100644
--- a/crates/rust-analyzer/src/diagnostics/to_proto.rs
+++ b/crates/rust-analyzer/src/diagnostics/to_proto.rs
@@ -538,7 +538,12 @@ mod tests {
         let (sender, _) = crossbeam_channel::unbounded();
         let state = GlobalState::new(
             sender,
-            Config::new(workspace_root.to_path_buf(), ClientCapabilities::default(), Vec::new()),
+            Config::new(
+                workspace_root.to_path_buf(),
+                ClientCapabilities::default(),
+                Vec::new(),
+                false,
+            ),
         );
         let snap = state.snapshot();
         let mut actual = map_rust_diagnostic_to_lsp(&config, &diagnostic, workspace_root, &snap);
diff --git a/crates/rust-analyzer/src/lsp/to_proto.rs b/crates/rust-analyzer/src/lsp/to_proto.rs
index 23074493aee..9190c203146 100644
--- a/crates/rust-analyzer/src/lsp/to_proto.rs
+++ b/crates/rust-analyzer/src/lsp/to_proto.rs
@@ -443,10 +443,11 @@ pub(crate) fn inlay_hint(
     file_id: FileId,
     inlay_hint: InlayHint,
 ) -> Cancellable<lsp_types::InlayHint> {
+    let is_visual_studio = snap.config.is_visual_studio();
     let needs_resolve = inlay_hint.needs_resolve;
     let (label, tooltip, mut something_to_resolve) =
         inlay_hint_label(snap, fields_to_resolve, needs_resolve, inlay_hint.label)?;
-    let text_edits = if needs_resolve && fields_to_resolve.resolve_text_edits {
+    let text_edits = if !is_visual_studio && needs_resolve && fields_to_resolve.resolve_text_edits {
         something_to_resolve |= inlay_hint.text_edit.is_some();
         None
     } else {
diff --git a/crates/rust-analyzer/tests/slow-tests/support.rs b/crates/rust-analyzer/tests/slow-tests/support.rs
index e49b5768fa4..106b99cb935 100644
--- a/crates/rust-analyzer/tests/slow-tests/support.rs
+++ b/crates/rust-analyzer/tests/slow-tests/support.rs
@@ -150,6 +150,7 @@ impl Project<'_> {
                 ..Default::default()
             },
             roots,
+            false,
         );
         config.update(self.config).expect("invalid config");
         config.rediscover_workspaces();