From 0286e46e5f4365e1f83793919e1e960ad4960996 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 13 Apr 2023 10:32:48 +0200 Subject: [PATCH] internal: Skip code lens resolution for mismatched document versions --- crates/rust-analyzer/src/from_proto.rs | 18 +++++++++++++----- crates/rust-analyzer/src/handlers.rs | 2 +- crates/rust-analyzer/src/lsp_ext.rs | 9 ++++++++- crates/rust-analyzer/src/to_proto.rs | 22 ++++++++++++++++++++-- docs/dev/lsp-extensions.md | 2 +- 5 files changed, 43 insertions(+), 10 deletions(-) diff --git a/crates/rust-analyzer/src/from_proto.rs b/crates/rust-analyzer/src/from_proto.rs index 50af38cd6f..1482183926 100644 --- a/crates/rust-analyzer/src/from_proto.rs +++ b/crates/rust-analyzer/src/from_proto.rs @@ -98,13 +98,17 @@ pub(crate) fn assist_kind(kind: lsp_types::CodeActionKind) -> Option pub(crate) fn annotation( snap: &GlobalStateSnapshot, code_lens: lsp_types::CodeLens, -) -> Result { +) -> Result> { let data = code_lens.data.ok_or_else(|| invalid_params_error("code lens without data".to_string()))?; let resolve = from_json::("CodeLensResolveData", &data)?; - match resolve { - lsp_ext::CodeLensResolveData::Impls(params) => { + match resolve.kind { + lsp_ext::CodeLensResolveDataKind::Impls(params) => { + if matches!(snap.url_file_version(¶ms.text_document_position_params.text_document.uri), Some(version) if version == resolve.version) + { + return Ok(None); + } let pos @ FilePosition { file_id, .. } = file_position(snap, params.text_document_position_params)?; let line_index = snap.file_line_index(file_id)?; @@ -114,7 +118,11 @@ pub(crate) fn annotation( kind: AnnotationKind::HasImpls { pos, data: None }, }) } - lsp_ext::CodeLensResolveData::References(params) => { + lsp_ext::CodeLensResolveDataKind::References(params) => { + if matches!(snap.url_file_version(¶ms.text_document.uri), Some(version) if version == resolve.version) + { + return Ok(None); + } let pos @ FilePosition { file_id, .. } = file_position(snap, params)?; let line_index = snap.file_line_index(file_id)?; @@ -123,5 +131,5 @@ pub(crate) fn annotation( kind: AnnotationKind::HasReferences { pos, data: None }, }) } - } + }.map(Some) } diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index 2dae2c82b9..54df01580a 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs @@ -1270,7 +1270,7 @@ pub(crate) fn handle_code_lens_resolve( snap: GlobalStateSnapshot, code_lens: CodeLens, ) -> Result { - let annotation = from_proto::annotation(&snap, code_lens.clone())?; + let Some(annotation) = from_proto::annotation(&snap, code_lens.clone())? else { return Ok(code_lens) }; let annotation = snap.analysis.resolve_annotation(annotation)?; let mut acc = Vec::new(); diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs index 2adefcc5e8..7530946676 100644 --- a/crates/rust-analyzer/src/lsp_ext.rs +++ b/crates/rust-analyzer/src/lsp_ext.rs @@ -495,7 +495,14 @@ pub struct OpenCargoTomlParams { /// Information about CodeLens, that is to be resolved. #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub(crate) enum CodeLensResolveData { +pub struct CodeLensResolveData { + pub version: i32, + pub kind: CodeLensResolveDataKind, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub enum CodeLensResolveDataKind { Impls(lsp_types::request::GotoImplementationParams), References(lsp_types::TextDocumentPositionParams), } diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 2b9dfeccef..9d2629e697 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -1257,7 +1257,16 @@ pub(crate) fn code_lens( acc.push(lsp_types::CodeLens { range: annotation_range, command, - data: Some(to_value(lsp_ext::CodeLensResolveData::Impls(goto_params)).unwrap()), + data: (|| { + let version = snap.url_file_version(&url)?; + Some( + to_value(lsp_ext::CodeLensResolveData { + version, + kind: lsp_ext::CodeLensResolveDataKind::Impls(goto_params), + }) + .unwrap(), + ) + })(), }) } AnnotationKind::HasReferences { pos: file_range, data } => { @@ -1287,7 +1296,16 @@ pub(crate) fn code_lens( acc.push(lsp_types::CodeLens { range: annotation_range, command, - data: Some(to_value(lsp_ext::CodeLensResolveData::References(doc_pos)).unwrap()), + data: (|| { + let version = snap.url_file_version(&url)?; + Some( + to_value(lsp_ext::CodeLensResolveData { + version, + kind: lsp_ext::CodeLensResolveDataKind::References(doc_pos), + }) + .unwrap(), + ) + })(), }) } } diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md index bb5c658948..9df6b0ff28 100644 --- a/docs/dev/lsp-extensions.md +++ b/docs/dev/lsp-extensions.md @@ -1,5 +1,5 @@