Fix #24081 - lsp diagnostic code type conversion (#24347)

- **store `buffer::Diagnostic`as NumberOrString instead of assuming
String**
- **update zed-industries/lsp-types rev**

Closes #24081

Release Notes:

- Fixed an issue where language server diagnostic codes would be converted to strings leading to errors with some language servers
This commit is contained in:
Ben Kunkle 2025-02-05 21:23:46 -06:00 committed by GitHub
parent 10b6bc2508
commit 8b3d315e40
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 12 additions and 22 deletions

View file

@ -933,7 +933,7 @@ fn diagnostic_header_renderer(diagnostic: Diagnostic) -> RenderBlock {
.when_some(diagnostic.code.as_ref(), |stack, code| { .when_some(diagnostic.code.as_ref(), |stack, code| {
stack.child( stack.child(
div() div()
.child(SharedString::from(format!("({code})"))) .child(SharedString::from(format!("({code:?})")))
.text_color(color.text_muted), .text_color(color.text_muted),
) )
}), }),

View file

@ -28,7 +28,7 @@ use gpui::{
AnyElement, App, AppContext as _, Context, Entity, EventEmitter, HighlightStyle, Pixels, AnyElement, App, AppContext as _, Context, Entity, EventEmitter, HighlightStyle, Pixels,
SharedString, StyledText, Task, TaskLabel, TextStyle, Window, SharedString, StyledText, Task, TaskLabel, TextStyle, Window,
}; };
use lsp::LanguageServerId; use lsp::{LanguageServerId, NumberOrString};
use parking_lot::Mutex; use parking_lot::Mutex;
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -202,7 +202,7 @@ pub struct Diagnostic {
/// The name of the service that produced this diagnostic. /// The name of the service that produced this diagnostic.
pub source: Option<String>, pub source: Option<String>,
/// A machine-readable code that identifies this diagnostic. /// A machine-readable code that identifies this diagnostic.
pub code: Option<String>, pub code: Option<NumberOrString>,
/// Whether this diagnostic is a hint, warning, or error. /// Whether this diagnostic is a hint, warning, or error.
pub severity: DiagnosticSeverity, pub severity: DiagnosticSeverity,
/// The human-readable message associated with this diagnostic. /// The human-readable message associated with this diagnostic.

View file

@ -56,17 +56,11 @@ impl DiagnosticEntry<PointUtf16> {
/// Returns a raw LSP diagnostic used to provide diagnostic context to LSP /// Returns a raw LSP diagnostic used to provide diagnostic context to LSP
/// codeAction request /// codeAction request
pub fn to_lsp_diagnostic_stub(&self) -> Result<lsp::Diagnostic> { pub fn to_lsp_diagnostic_stub(&self) -> Result<lsp::Diagnostic> {
let code = self
.diagnostic
.code
.clone()
.map(lsp::NumberOrString::String);
let range = range_to_lsp(self.range.clone())?; let range = range_to_lsp(self.range.clone())?;
Ok(lsp::Diagnostic { Ok(lsp::Diagnostic {
code,
range, range,
code: self.diagnostic.code.clone(),
severity: Some(self.diagnostic.severity), severity: Some(self.diagnostic.severity),
source: self.diagnostic.source.clone(), source: self.diagnostic.source.clone(),
message: self.diagnostic.message.clone(), message: self.diagnostic.message.clone(),

View file

@ -213,7 +213,7 @@ pub fn serialize_diagnostics<'a>(
group_id: entry.diagnostic.group_id as u64, group_id: entry.diagnostic.group_id as u64,
is_primary: entry.diagnostic.is_primary, is_primary: entry.diagnostic.is_primary,
is_valid: true, is_valid: true,
code: entry.diagnostic.code.clone(), code: entry.diagnostic.code.as_ref().map(|s| s.to_string()),
is_disk_based: entry.diagnostic.is_disk_based, is_disk_based: entry.diagnostic.is_disk_based,
is_unnecessary: entry.diagnostic.is_unnecessary, is_unnecessary: entry.diagnostic.is_unnecessary,
data: entry.diagnostic.data.as_ref().map(|data| data.to_string()), data: entry.diagnostic.data.as_ref().map(|data| data.to_string()),
@ -419,7 +419,7 @@ pub fn deserialize_diagnostics(
}, },
message: diagnostic.message, message: diagnostic.message,
group_id: diagnostic.group_id as usize, group_id: diagnostic.group_id as usize,
code: diagnostic.code, code: diagnostic.code.map(lsp::NumberOrString::from_string),
is_primary: diagnostic.is_primary, is_primary: diagnostic.is_primary,
is_disk_based: diagnostic.is_disk_based, is_disk_based: diagnostic.is_disk_based,
is_unnecessary: diagnostic.is_unnecessary, is_unnecessary: diagnostic.is_unnecessary,

View file

@ -22,7 +22,7 @@ collections.workspace = true
futures.workspace = true futures.workspace = true
gpui.workspace = true gpui.workspace = true
log.workspace = true log.workspace = true
lsp-types = { git = "https://github.com/zed-industries/lsp-types", rev = "72357d6f6d212bdffba3b5ef4b31d8ca856058e7" } lsp-types = { git = "https://github.com/zed-industries/lsp-types", rev = "1fff0dd12e2071c5667327394cfec163d2a466ab" }
parking_lot.workspace = true parking_lot.workspace = true
postage.workspace = true postage.workspace = true
serde.workspace = true serde.workspace = true

View file

@ -7366,10 +7366,6 @@ impl LspStore {
for diagnostic in &params.diagnostics { for diagnostic in &params.diagnostics {
let source = diagnostic.source.as_ref(); let source = diagnostic.source.as_ref();
let code = diagnostic.code.as_ref().map(|code| match code {
lsp::NumberOrString::Number(code) => code.to_string(),
lsp::NumberOrString::String(code) => code.clone(),
});
let range = range_from_lsp(diagnostic.range); let range = range_from_lsp(diagnostic.range);
let is_supporting = diagnostic let is_supporting = diagnostic
.related_information .related_information
@ -7378,7 +7374,7 @@ impl LspStore {
infos.iter().any(|info| { infos.iter().any(|info| {
primary_diagnostic_group_ids.contains_key(&( primary_diagnostic_group_ids.contains_key(&(
source, source,
code.clone(), diagnostic.code.clone(),
range_from_lsp(info.location.range), range_from_lsp(info.location.range),
)) ))
}) })
@ -7390,7 +7386,7 @@ impl LspStore {
if is_supporting { if is_supporting {
supporting_diagnostics.insert( supporting_diagnostics.insert(
(source, code.clone(), range), (source, diagnostic.code.clone(), range),
(diagnostic.severity, is_unnecessary), (diagnostic.severity, is_unnecessary),
); );
} else { } else {
@ -7400,13 +7396,13 @@ impl LspStore {
sources_by_group_id.insert(group_id, source); sources_by_group_id.insert(group_id, source);
primary_diagnostic_group_ids primary_diagnostic_group_ids
.insert((source, code.clone(), range.clone()), group_id); .insert((source, diagnostic.code.clone(), range.clone()), group_id);
diagnostics.push(DiagnosticEntry { diagnostics.push(DiagnosticEntry {
range, range,
diagnostic: Diagnostic { diagnostic: Diagnostic {
source: diagnostic.source.clone(), source: diagnostic.source.clone(),
code: code.clone(), code: diagnostic.code.clone(),
severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR), severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
message: diagnostic.message.trim().to_string(), message: diagnostic.message.trim().to_string(),
group_id, group_id,
@ -7424,7 +7420,7 @@ impl LspStore {
range, range,
diagnostic: Diagnostic { diagnostic: Diagnostic {
source: diagnostic.source.clone(), source: diagnostic.source.clone(),
code: code.clone(), code: diagnostic.code.clone(),
severity: DiagnosticSeverity::INFORMATION, severity: DiagnosticSeverity::INFORMATION,
message: info.message.trim().to_string(), message: info.message.trim().to_string(),
group_id, group_id,