crates/diagnostics/src/diagnostics_tests.rs 🔗
@@ -954,6 +954,7 @@ fn random_diagnostic(
is_primary,
is_disk_based: false,
is_unnecessary: false,
+ data: None,
},
}
}
Piotr Osiewicz created
Per the LSP spec, we should pass .data field of diagnostics into code
action request:
```
/**
* A data entry field that is preserved between a
* `textDocument/publishDiagnostics` notification and
* `textDocument/codeAction` request. *
* @since 3.16.0 */ data?: LSPAny;
```
Release Notes:
- Fixed rare cases where a code action triggered by diagnostic may not
be available for use.
crates/diagnostics/src/diagnostics_tests.rs | 1 +
crates/language/src/buffer.rs | 4 ++++
crates/language/src/diagnostic_set.rs | 1 +
crates/language/src/proto.rs | 10 +++++++++-
crates/project/src/project.rs | 2 ++
crates/proto/proto/zed.proto | 1 +
6 files changed, 18 insertions(+), 1 deletion(-)
@@ -954,6 +954,7 @@ fn random_diagnostic(
is_primary,
is_disk_based: false,
is_unnecessary: false,
+ data: None,
},
}
}
@@ -27,6 +27,7 @@ use gpui::{
use lazy_static::lazy_static;
use lsp::LanguageServerId;
use parking_lot::Mutex;
+use serde_json::Value;
use similar::{ChangeTag, TextDiff};
use smallvec::SmallVec;
use smol::future::yield_now;
@@ -213,6 +214,8 @@ pub struct Diagnostic {
pub is_disk_based: bool,
/// Whether this diagnostic marks unnecessary code.
pub is_unnecessary: bool,
+ /// Data from language server that produced this diagnostic. Passed back to the LS when we request code actions for this diagnostic.
+ pub data: Option<Value>,
}
/// TODO - move this into the `project` crate and make it private.
@@ -3844,6 +3847,7 @@ impl Default for Diagnostic {
is_primary: false,
is_disk_based: false,
is_unnecessary: false,
+ data: None,
}
}
}
@@ -69,6 +69,7 @@ impl DiagnosticEntry<PointUtf16> {
severity: Some(self.diagnostic.severity),
source: self.diagnostic.source.clone(),
message: self.diagnostic.message.clone(),
+ data: self.diagnostic.data.clone(),
..Default::default()
}
}
@@ -5,7 +5,8 @@ use anyhow::{anyhow, Context as _, Result};
use clock::ReplicaId;
use lsp::{DiagnosticSeverity, LanguageServerId};
use rpc::proto;
-use std::{ops::Range, sync::Arc};
+use serde_json::Value;
+use std::{ops::Range, str::FromStr, sync::Arc};
use text::*;
pub use proto::{BufferState, Operation};
@@ -213,6 +214,7 @@ pub fn serialize_diagnostics<'a>(
code: entry.diagnostic.code.clone(),
is_disk_based: entry.diagnostic.is_disk_based,
is_unnecessary: entry.diagnostic.is_unnecessary,
+ data: entry.diagnostic.data.as_ref().map(|data| data.to_string()),
})
.collect()
}
@@ -396,6 +398,11 @@ pub fn deserialize_diagnostics(
diagnostics
.into_iter()
.filter_map(|diagnostic| {
+ let data = if let Some(data) = diagnostic.data {
+ Some(Value::from_str(&data).ok()?)
+ } else {
+ None
+ };
Some(DiagnosticEntry {
range: deserialize_anchor(diagnostic.start?)?..deserialize_anchor(diagnostic.end?)?,
diagnostic: Diagnostic {
@@ -413,6 +420,7 @@ pub fn deserialize_diagnostics(
is_primary: diagnostic.is_primary,
is_disk_based: diagnostic.is_disk_based,
is_unnecessary: diagnostic.is_unnecessary,
+ data,
},
})
})
@@ -4595,6 +4595,7 @@ impl Project {
is_primary: true,
is_disk_based,
is_unnecessary,
+ data: diagnostic.data.clone(),
},
});
if let Some(infos) = &diagnostic.related_information {
@@ -4612,6 +4613,7 @@ impl Project {
is_primary: false,
is_disk_based,
is_unnecessary: false,
+ data: diagnostic.data.clone(),
},
});
}
@@ -1890,6 +1890,7 @@ message Diagnostic {
Information = 3;
Hint = 4;
}
+ optional string data = 12;
}
message Operation {