Unnamed repository; edit this file 'description' to name the repository.
internal: Skip code lens resolution for mismatched document versions
Lukas Wirth 2023-04-13
parent dd5c3c3 · commit 0286e46
-rw-r--r--crates/rust-analyzer/src/from_proto.rs18
-rw-r--r--crates/rust-analyzer/src/handlers.rs2
-rw-r--r--crates/rust-analyzer/src/lsp_ext.rs9
-rw-r--r--crates/rust-analyzer/src/to_proto.rs22
-rw-r--r--docs/dev/lsp-extensions.md2
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<AssistKind>
pub(crate) fn annotation(
snap: &GlobalStateSnapshot,
code_lens: lsp_types::CodeLens,
-) -> Result<Annotation> {
+) -> Result<Option<Annotation>> {
let data =
code_lens.data.ok_or_else(|| invalid_params_error("code lens without data".to_string()))?;
let resolve = from_json::<lsp_ext::CodeLensResolveData>("CodeLensResolveData", &data)?;
- match resolve {
- lsp_ext::CodeLensResolveData::Impls(params) => {
+ match resolve.kind {
+ lsp_ext::CodeLensResolveDataKind::Impls(params) => {
+ if matches!(snap.url_file_version(&params.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(&params.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<CodeLens> {
- 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 @@
<!---
-lsp_ext.rs hash: 7269e4cfab906e10
+lsp_ext.rs hash: be2f663a78beb7bd
If you need to change the above hash to make the test pass, please check if you
need to adjust this doc as well and ping this issue: