mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-19 18:41:56 +03:00
lsp: Pass back diagnostic .data when querying code actions for it (#14962)
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.
This commit is contained in:
parent
10d2353e07
commit
865904a0c9
@ -954,6 +954,7 @@ fn random_diagnostic(
|
|||||||
is_primary,
|
is_primary,
|
||||||
is_disk_based: false,
|
is_disk_based: false,
|
||||||
is_unnecessary: false,
|
is_unnecessary: false,
|
||||||
|
data: None,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ use gpui::{
|
|||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use lsp::LanguageServerId;
|
use lsp::LanguageServerId;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
|
use serde_json::Value;
|
||||||
use similar::{ChangeTag, TextDiff};
|
use similar::{ChangeTag, TextDiff};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use smol::future::yield_now;
|
use smol::future::yield_now;
|
||||||
@ -213,6 +214,8 @@ pub struct Diagnostic {
|
|||||||
pub is_disk_based: bool,
|
pub is_disk_based: bool,
|
||||||
/// Whether this diagnostic marks unnecessary code.
|
/// Whether this diagnostic marks unnecessary code.
|
||||||
pub is_unnecessary: bool,
|
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.
|
/// TODO - move this into the `project` crate and make it private.
|
||||||
@ -3844,6 +3847,7 @@ impl Default for Diagnostic {
|
|||||||
is_primary: false,
|
is_primary: false,
|
||||||
is_disk_based: false,
|
is_disk_based: false,
|
||||||
is_unnecessary: false,
|
is_unnecessary: false,
|
||||||
|
data: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,7 @@ impl DiagnosticEntry<PointUtf16> {
|
|||||||
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(),
|
||||||
|
data: self.diagnostic.data.clone(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,8 @@ use anyhow::{anyhow, Context as _, Result};
|
|||||||
use clock::ReplicaId;
|
use clock::ReplicaId;
|
||||||
use lsp::{DiagnosticSeverity, LanguageServerId};
|
use lsp::{DiagnosticSeverity, LanguageServerId};
|
||||||
use rpc::proto;
|
use rpc::proto;
|
||||||
use std::{ops::Range, sync::Arc};
|
use serde_json::Value;
|
||||||
|
use std::{ops::Range, str::FromStr, sync::Arc};
|
||||||
use text::*;
|
use text::*;
|
||||||
|
|
||||||
pub use proto::{BufferState, Operation};
|
pub use proto::{BufferState, Operation};
|
||||||
@ -213,6 +214,7 @@ pub fn serialize_diagnostics<'a>(
|
|||||||
code: entry.diagnostic.code.clone(),
|
code: entry.diagnostic.code.clone(),
|
||||||
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()),
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
@ -396,6 +398,11 @@ pub fn deserialize_diagnostics(
|
|||||||
diagnostics
|
diagnostics
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|diagnostic| {
|
.filter_map(|diagnostic| {
|
||||||
|
let data = if let Some(data) = diagnostic.data {
|
||||||
|
Some(Value::from_str(&data).ok()?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
Some(DiagnosticEntry {
|
Some(DiagnosticEntry {
|
||||||
range: deserialize_anchor(diagnostic.start?)?..deserialize_anchor(diagnostic.end?)?,
|
range: deserialize_anchor(diagnostic.start?)?..deserialize_anchor(diagnostic.end?)?,
|
||||||
diagnostic: Diagnostic {
|
diagnostic: Diagnostic {
|
||||||
@ -413,6 +420,7 @@ pub fn deserialize_diagnostics(
|
|||||||
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,
|
||||||
|
data,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -4595,6 +4595,7 @@ impl Project {
|
|||||||
is_primary: true,
|
is_primary: true,
|
||||||
is_disk_based,
|
is_disk_based,
|
||||||
is_unnecessary,
|
is_unnecessary,
|
||||||
|
data: diagnostic.data.clone(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if let Some(infos) = &diagnostic.related_information {
|
if let Some(infos) = &diagnostic.related_information {
|
||||||
@ -4612,6 +4613,7 @@ impl Project {
|
|||||||
is_primary: false,
|
is_primary: false,
|
||||||
is_disk_based,
|
is_disk_based,
|
||||||
is_unnecessary: false,
|
is_unnecessary: false,
|
||||||
|
data: diagnostic.data.clone(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1890,6 +1890,7 @@ message Diagnostic {
|
|||||||
Information = 3;
|
Information = 3;
|
||||||
Hint = 4;
|
Hint = 4;
|
||||||
}
|
}
|
||||||
|
optional string data = 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Operation {
|
message Operation {
|
||||||
|
Loading…
Reference in New Issue
Block a user