mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-28 21:32:39 +00:00
Get things compiling with diagnostics on worktree
Co-Authored-By: Antonio Scandurra <me@as-cii.com> Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
parent
85674ba506
commit
418a9a3d66
6 changed files with 264 additions and 263 deletions
|
@ -15,7 +15,9 @@ impl ProjectDiagnostics {
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut buffer = cx.add_model(|cx| MultiBuffer::new(project.read(cx).replica_id(cx)));
|
let mut buffer = cx.add_model(|cx| MultiBuffer::new(project.read(cx).replica_id(cx)));
|
||||||
for (path, diagnostics) in project.read(cx).diagnostics(cx) {}
|
for diagnostic_summary in project.read(cx).diagnostic_summaries(cx) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
editor: cx.add_view(|cx| {
|
editor: cx.add_view(|cx| {
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
use gpui::{ModelHandle, MutableAppContext, Task};
|
use gpui::{ModelHandle, MutableAppContext};
|
||||||
use std::{
|
use std::{
|
||||||
any::Any,
|
|
||||||
cell::RefCell,
|
cell::RefCell,
|
||||||
ffi::OsString,
|
|
||||||
iter::FromIterator,
|
iter::FromIterator,
|
||||||
ops::Range,
|
ops::Range,
|
||||||
path::PathBuf,
|
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
time::{Duration, Instant, SystemTime},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
use unindent::Unindent as _;
|
use unindent::Unindent as _;
|
||||||
|
|
||||||
|
@ -871,80 +868,3 @@ fn rust_lang() -> Language {
|
||||||
fn empty(point: Point) -> Range<Point> {
|
fn empty(point: Point) -> Range<Point> {
|
||||||
point..point
|
point..point
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
struct FakeFile {
|
|
||||||
abs_path: PathBuf,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FakeFile {
|
|
||||||
fn new(abs_path: impl Into<PathBuf>) -> Self {
|
|
||||||
Self {
|
|
||||||
abs_path: abs_path.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl File for FakeFile {
|
|
||||||
fn worktree_id(&self) -> usize {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn entry_id(&self) -> Option<usize> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mtime(&self) -> SystemTime {
|
|
||||||
SystemTime::now()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn path(&self) -> &Arc<Path> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn abs_path(&self) -> Option<PathBuf> {
|
|
||||||
Some(self.abs_path.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn full_path(&self) -> PathBuf {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn file_name(&self) -> Option<OsString> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_deleted(&self) -> bool {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn save(
|
|
||||||
&self,
|
|
||||||
_: u64,
|
|
||||||
_: Rope,
|
|
||||||
_: clock::Global,
|
|
||||||
_: &mut MutableAppContext,
|
|
||||||
) -> Task<Result<(clock::Global, SystemTime)>> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn load_local(&self, _: &AppContext) -> Option<Task<Result<String>>> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn buffer_updated(&self, _: u64, _: super::Operation, _: &mut MutableAppContext) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn buffer_removed(&self, _: u64, _: &mut MutableAppContext) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn boxed_clone(&self) -> Box<dyn File> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_any(&self) -> &dyn Any {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ use clock::ReplicaId;
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
use fuzzy::{PathMatch, PathMatchCandidate, PathMatchCandidateSet};
|
use fuzzy::{PathMatch, PathMatchCandidate, PathMatchCandidateSet};
|
||||||
use gpui::{AppContext, Entity, ModelContext, ModelHandle, Task};
|
use gpui::{AppContext, Entity, ModelContext, ModelHandle, Task};
|
||||||
use language::{DiagnosticEntry, LanguageRegistry, PointUtf16};
|
use language::LanguageRegistry;
|
||||||
use std::{
|
use std::{
|
||||||
path::Path,
|
path::Path,
|
||||||
sync::{atomic::AtomicBool, Arc},
|
sync::{atomic::AtomicBool, Arc},
|
||||||
|
@ -39,6 +39,14 @@ pub struct ProjectPath {
|
||||||
pub path: Arc<Path>,
|
pub path: Arc<Path>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct DiagnosticSummary {
|
||||||
|
pub project_path: ProjectPath,
|
||||||
|
pub error_count: usize,
|
||||||
|
pub warning_count: usize,
|
||||||
|
pub info_count: usize,
|
||||||
|
pub hint_count: usize,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct ProjectEntry {
|
pub struct ProjectEntry {
|
||||||
pub worktree_id: usize,
|
pub worktree_id: usize,
|
||||||
|
@ -165,10 +173,10 @@ impl Project {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn diagnostics<'a>(
|
pub fn diagnostic_summaries<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
cx: &'a AppContext,
|
cx: &'a AppContext,
|
||||||
) -> impl Iterator<Item = (&'a Path, &'a [DiagnosticEntry<PointUtf16>])> {
|
) -> impl Iterator<Item = DiagnosticSummary> {
|
||||||
std::iter::empty()
|
std::iter::empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use super::{
|
use super::{
|
||||||
fs::{self, Fs},
|
fs::{self, Fs},
|
||||||
ignore::IgnoreStack,
|
ignore::IgnoreStack,
|
||||||
|
DiagnosticSummary,
|
||||||
};
|
};
|
||||||
use ::ignore::gitignore::{Gitignore, GitignoreBuilder};
|
use ::ignore::gitignore::{Gitignore, GitignoreBuilder};
|
||||||
use anyhow::{anyhow, Context, Result};
|
use anyhow::{anyhow, Context, Result};
|
||||||
|
@ -306,6 +307,7 @@ impl Worktree {
|
||||||
updates_tx,
|
updates_tx,
|
||||||
client: client.clone(),
|
client: client.clone(),
|
||||||
open_buffers: Default::default(),
|
open_buffers: Default::default(),
|
||||||
|
diagnostics: Vec::new(),
|
||||||
collaborators,
|
collaborators,
|
||||||
queued_operations: Default::default(),
|
queued_operations: Default::default(),
|
||||||
languages,
|
languages,
|
||||||
|
@ -467,6 +469,13 @@ impl Worktree {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn diagnostic_summaries<'a>(
|
||||||
|
&'a self,
|
||||||
|
cx: &'a AppContext,
|
||||||
|
) -> impl Iterator<Item = DiagnosticSummary> {
|
||||||
|
std::iter::empty()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn open_buffer(
|
pub fn open_buffer(
|
||||||
&mut self,
|
&mut self,
|
||||||
path: impl AsRef<Path>,
|
path: impl AsRef<Path>,
|
||||||
|
@ -754,10 +763,11 @@ impl Worktree {
|
||||||
.uri
|
.uri
|
||||||
.to_file_path()
|
.to_file_path()
|
||||||
.map_err(|_| anyhow!("URI is not a file"))?;
|
.map_err(|_| anyhow!("URI is not a file"))?;
|
||||||
let worktree_path = abs_path
|
let worktree_path = Arc::from(
|
||||||
|
abs_path
|
||||||
.strip_prefix(&this.abs_path)
|
.strip_prefix(&this.abs_path)
|
||||||
.context("path is not within worktree")?
|
.context("path is not within worktree")?,
|
||||||
.to_owned();
|
);
|
||||||
|
|
||||||
let mut group_ids_by_diagnostic_range = HashMap::new();
|
let mut group_ids_by_diagnostic_range = HashMap::new();
|
||||||
let mut diagnostics_by_group_id = HashMap::new();
|
let mut diagnostics_by_group_id = HashMap::new();
|
||||||
|
@ -784,7 +794,10 @@ impl Worktree {
|
||||||
..diagnostic.range.end.to_point_utf16(),
|
..diagnostic.range.end.to_point_utf16(),
|
||||||
diagnostic: Diagnostic {
|
diagnostic: Diagnostic {
|
||||||
source: diagnostic.source.clone(),
|
source: diagnostic.source.clone(),
|
||||||
code: diagnostic.code.clone(),
|
code: diagnostic.code.clone().map(|code| match code {
|
||||||
|
lsp::NumberOrString::Number(code) => code.to_string(),
|
||||||
|
lsp::NumberOrString::String(code) => code,
|
||||||
|
}),
|
||||||
severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
|
severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
|
||||||
message: diagnostic.message.clone(),
|
message: diagnostic.message.clone(),
|
||||||
group_id,
|
group_id,
|
||||||
|
@ -810,12 +823,12 @@ impl Worktree {
|
||||||
if buffer
|
if buffer
|
||||||
.read(cx)
|
.read(cx)
|
||||||
.file()
|
.file()
|
||||||
.map_or(false, |file| file.path().as_ref() == worktree_path)
|
.map_or(false, |file| *file.path() == worktree_path)
|
||||||
{
|
{
|
||||||
let (remote_id, operation) = buffer.update(cx, |buffer, cx| {
|
let (remote_id, operation) = buffer.update(cx, |buffer, cx| {
|
||||||
(
|
(
|
||||||
buffer.remote_id(),
|
buffer.remote_id(),
|
||||||
buffer.update_diagnostics(params.version, params.diagnostics, cx),
|
buffer.update_diagnostics(params.version, diagnostics, cx),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
self.send_buffer_update(remote_id, operation?, cx);
|
self.send_buffer_update(remote_id, operation?, cx);
|
||||||
|
@ -888,7 +901,7 @@ pub struct LocalWorktree {
|
||||||
share: Option<ShareState>,
|
share: Option<ShareState>,
|
||||||
open_buffers: HashMap<usize, WeakModelHandle<Buffer>>,
|
open_buffers: HashMap<usize, WeakModelHandle<Buffer>>,
|
||||||
shared_buffers: HashMap<PeerId, HashMap<u64, ModelHandle<Buffer>>>,
|
shared_buffers: HashMap<PeerId, HashMap<u64, ModelHandle<Buffer>>>,
|
||||||
diagnostics: HashMap<PathBuf, Vec<DiagnosticEntry<PointUtf16>>>,
|
diagnostics: HashMap<Arc<Path>, Vec<DiagnosticEntry<PointUtf16>>>,
|
||||||
collaborators: HashMap<PeerId, Collaborator>,
|
collaborators: HashMap<PeerId, Collaborator>,
|
||||||
queued_operations: Vec<(u64, Operation)>,
|
queued_operations: Vec<(u64, Operation)>,
|
||||||
languages: Arc<LanguageRegistry>,
|
languages: Arc<LanguageRegistry>,
|
||||||
|
@ -1488,6 +1501,7 @@ pub struct RemoteWorktree {
|
||||||
replica_id: ReplicaId,
|
replica_id: ReplicaId,
|
||||||
open_buffers: HashMap<usize, RemoteBuffer>,
|
open_buffers: HashMap<usize, RemoteBuffer>,
|
||||||
collaborators: HashMap<PeerId, Collaborator>,
|
collaborators: HashMap<PeerId, Collaborator>,
|
||||||
|
diagnostics: Vec<DiagnosticSummary>,
|
||||||
languages: Arc<LanguageRegistry>,
|
languages: Arc<LanguageRegistry>,
|
||||||
user_store: ModelHandle<UserStore>,
|
user_store: ModelHandle<UserStore>,
|
||||||
queued_operations: Vec<(u64, Operation)>,
|
queued_operations: Vec<(u64, Operation)>,
|
||||||
|
@ -3105,6 +3119,7 @@ mod tests {
|
||||||
time::{SystemTime, UNIX_EPOCH},
|
time::{SystemTime, UNIX_EPOCH},
|
||||||
};
|
};
|
||||||
use text::Point;
|
use text::Point;
|
||||||
|
use unindent::Unindent as _;
|
||||||
use util::test::temp_tree;
|
use util::test::temp_tree;
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
|
@ -3821,7 +3836,8 @@ mod tests {
|
||||||
severity: lsp::DiagnosticSeverity::ERROR,
|
severity: lsp::DiagnosticSeverity::ERROR,
|
||||||
message: "undefined variable 'A'".to_string(),
|
message: "undefined variable 'A'".to_string(),
|
||||||
group_id: 0,
|
group_id: 0,
|
||||||
is_primary: true
|
is_primary: true,
|
||||||
|
..Default::default()
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
)
|
)
|
||||||
|
@ -3830,105 +3846,149 @@ mod tests {
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_grouped_diagnostics(mut cx: gpui::TestAppContext) {
|
async fn test_grouped_diagnostics(mut cx: gpui::TestAppContext) {
|
||||||
cx.add_model(|cx| {
|
let fs = Arc::new(FakeFs::new());
|
||||||
let text = "
|
let client = Client::new();
|
||||||
|
let http_client = FakeHttpClient::with_404_response();
|
||||||
|
let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http_client, cx));
|
||||||
|
|
||||||
|
fs.insert_tree(
|
||||||
|
"/the-dir",
|
||||||
|
json!({
|
||||||
|
"a.rs": "
|
||||||
fn foo(mut v: Vec<usize>) {
|
fn foo(mut v: Vec<usize>) {
|
||||||
for x in &v {
|
for x in &v {
|
||||||
v.push(1);
|
v.push(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
.unindent();
|
.unindent(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
let file = FakeFile::new("/example.rs");
|
let worktree = Worktree::open_local(
|
||||||
let mut buffer = Buffer::from_file(0, text, Box::new(file.clone()), cx);
|
client.clone(),
|
||||||
buffer.set_language(Some(Arc::new(rust_lang())), None, cx);
|
user_store,
|
||||||
let diagnostics = vec![
|
"/the-dir".as_ref(),
|
||||||
DiagnosticEntry {
|
fs,
|
||||||
range: PointUtf16::new(1, 8)..PointUtf16::new(1, 9),
|
Default::default(),
|
||||||
diagnostic: Diagnostic {
|
&mut cx.to_async(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let buffer = worktree
|
||||||
|
.update(&mut cx, |tree, cx| tree.open_buffer("a.rs", cx))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let buffer_uri = Url::from_file_path("/the-dir/a.rs").unwrap();
|
||||||
|
let message = lsp::PublishDiagnosticsParams {
|
||||||
|
uri: buffer_uri.clone(),
|
||||||
|
diagnostics: vec![
|
||||||
|
lsp::Diagnostic {
|
||||||
|
range: lsp::Range::new(lsp::Position::new(1, 8), lsp::Position::new(1, 9)),
|
||||||
severity: Some(DiagnosticSeverity::WARNING),
|
severity: Some(DiagnosticSeverity::WARNING),
|
||||||
message: "error 1".to_string(),
|
message: "error 1".to_string(),
|
||||||
related_information: Some(vec![lsp::DiagnosticRelatedInformation {
|
related_information: Some(vec![lsp::DiagnosticRelatedInformation {
|
||||||
location: lsp::Location {
|
location: lsp::Location {
|
||||||
uri: lsp::Url::from_file_path(&file.abs_path).unwrap(),
|
uri: buffer_uri.clone(),
|
||||||
range: PointUtf16::new(1, 8)..PointUtf16::new(1, 9),
|
range: lsp::Range::new(
|
||||||
|
lsp::Position::new(1, 8),
|
||||||
|
lsp::Position::new(1, 9),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
message: "error 1 hint 1".to_string(),
|
message: "error 1 hint 1".to_string(),
|
||||||
}]),
|
}]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
},
|
lsp::Diagnostic {
|
||||||
DiagnosticEntry {
|
range: lsp::Range::new(lsp::Position::new(1, 8), lsp::Position::new(1, 9)),
|
||||||
range: PointUtf16::new(1, 8)..PointUtf16::new(1, 9),
|
|
||||||
diagnostic: Diagnostic {},
|
|
||||||
severity: Some(DiagnosticSeverity::HINT),
|
severity: Some(DiagnosticSeverity::HINT),
|
||||||
message: "error 1 hint 1".to_string(),
|
message: "error 1 hint 1".to_string(),
|
||||||
related_information: Some(vec![lsp::DiagnosticRelatedInformation {
|
related_information: Some(vec![lsp::DiagnosticRelatedInformation {
|
||||||
location: lsp::Location {
|
location: lsp::Location {
|
||||||
uri: lsp::Url::from_file_path(&file.abs_path).unwrap(),
|
uri: buffer_uri.clone(),
|
||||||
range: PointUtf16::new(1, 8)..PointUtf16::new(1, 9),
|
range: lsp::Range::new(
|
||||||
|
lsp::Position::new(1, 8),
|
||||||
|
lsp::Position::new(1, 9),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
message: "original diagnostic".to_string(),
|
message: "original diagnostic".to_string(),
|
||||||
}]),
|
}]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
DiagnosticEntry {
|
lsp::Diagnostic {
|
||||||
range: PointUtf16::new(2, 8)..PointUtf16::new(2, 17),
|
range: lsp::Range::new(lsp::Position::new(2, 8), lsp::Position::new(2, 17)),
|
||||||
diagnostic: Diagnostic {},
|
|
||||||
severity: Some(DiagnosticSeverity::ERROR),
|
severity: Some(DiagnosticSeverity::ERROR),
|
||||||
message: "error 2".to_string(),
|
message: "error 2".to_string(),
|
||||||
related_information: Some(vec![
|
related_information: Some(vec![
|
||||||
lsp::DiagnosticRelatedInformation {
|
lsp::DiagnosticRelatedInformation {
|
||||||
location: lsp::Location {
|
location: lsp::Location {
|
||||||
uri: lsp::Url::from_file_path(&file.abs_path).unwrap(),
|
uri: buffer_uri.clone(),
|
||||||
range: PointUtf16::new(1, 13)..PointUtf16::new(1, 15),
|
range: lsp::Range::new(
|
||||||
|
lsp::Position::new(1, 13),
|
||||||
|
lsp::Position::new(1, 15),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
message: "error 2 hint 1".to_string(),
|
message: "error 2 hint 1".to_string(),
|
||||||
},
|
},
|
||||||
lsp::DiagnosticRelatedInformation {
|
lsp::DiagnosticRelatedInformation {
|
||||||
location: lsp::Location {
|
location: lsp::Location {
|
||||||
uri: lsp::Url::from_file_path(&file.abs_path).unwrap(),
|
uri: buffer_uri.clone(),
|
||||||
range: PointUtf16::new(1, 13)..PointUtf16::new(1, 15),
|
range: lsp::Range::new(
|
||||||
|
lsp::Position::new(1, 13),
|
||||||
|
lsp::Position::new(1, 15),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
message: "error 2 hint 2".to_string(),
|
message: "error 2 hint 2".to_string(),
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
DiagnosticEntry {
|
lsp::Diagnostic {
|
||||||
range: PointUtf16::new(1, 13)..PointUtf16::new(1, 15),
|
range: lsp::Range::new(lsp::Position::new(1, 13), lsp::Position::new(1, 15)),
|
||||||
diagnostic: Diagnostic {},
|
|
||||||
severity: Some(DiagnosticSeverity::HINT),
|
severity: Some(DiagnosticSeverity::HINT),
|
||||||
message: "error 2 hint 1".to_string(),
|
message: "error 2 hint 1".to_string(),
|
||||||
related_information: Some(vec![lsp::DiagnosticRelatedInformation {
|
related_information: Some(vec![lsp::DiagnosticRelatedInformation {
|
||||||
location: lsp::Location {
|
location: lsp::Location {
|
||||||
uri: lsp::Url::from_file_path(&file.abs_path).unwrap(),
|
uri: buffer_uri.clone(),
|
||||||
range: PointUtf16::new(2, 8)..PointUtf16::new(2, 17),
|
range: lsp::Range::new(
|
||||||
|
lsp::Position::new(2, 8),
|
||||||
|
lsp::Position::new(2, 17),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
message: "original diagnostic".to_string(),
|
message: "original diagnostic".to_string(),
|
||||||
}]),
|
}]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
DiagnosticEntry {
|
lsp::Diagnostic {
|
||||||
range: PointUtf16::new(1, 13)..PointUtf16::new(1, 15),
|
range: lsp::Range::new(lsp::Position::new(1, 13), lsp::Position::new(1, 15)),
|
||||||
diagnostic: Diagnostic {},
|
|
||||||
severity: Some(DiagnosticSeverity::HINT),
|
severity: Some(DiagnosticSeverity::HINT),
|
||||||
message: "error 2 hint 2".to_string(),
|
message: "error 2 hint 2".to_string(),
|
||||||
related_information: Some(vec![lsp::DiagnosticRelatedInformation {
|
related_information: Some(vec![lsp::DiagnosticRelatedInformation {
|
||||||
location: lsp::Location {
|
location: lsp::Location {
|
||||||
uri: lsp::Url::from_file_path(&file.abs_path).unwrap(),
|
uri: buffer_uri.clone(),
|
||||||
range: PointUtf16::new(2, 8)..PointUtf16::new(2, 17),
|
range: lsp::Range::new(
|
||||||
|
lsp::Position::new(2, 8),
|
||||||
|
lsp::Position::new(2, 17),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
message: "original diagnostic".to_string(),
|
message: "original diagnostic".to_string(),
|
||||||
}]),
|
}]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
];
|
],
|
||||||
buffer.update_diagnostics(None, diagnostics, cx).unwrap();
|
version: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
worktree
|
||||||
|
.update(&mut cx, |tree, cx| tree.update_diagnostics(message, cx))
|
||||||
|
.unwrap();
|
||||||
|
let buffer = buffer.read_with(&cx, |buffer, cx| buffer.snapshot());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
buffer
|
buffer
|
||||||
.snapshot()
|
|
||||||
.diagnostics_in_range::<_, Point>(0..buffer.len())
|
.diagnostics_in_range::<_, Point>(0..buffer.len())
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
&[
|
&[
|
||||||
|
@ -3939,6 +3999,7 @@ mod tests {
|
||||||
message: "error 1".to_string(),
|
message: "error 1".to_string(),
|
||||||
group_id: 0,
|
group_id: 0,
|
||||||
is_primary: true,
|
is_primary: true,
|
||||||
|
..Default::default()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DiagnosticEntry {
|
DiagnosticEntry {
|
||||||
|
@ -3948,6 +4009,7 @@ mod tests {
|
||||||
message: "error 1 hint 1".to_string(),
|
message: "error 1 hint 1".to_string(),
|
||||||
group_id: 0,
|
group_id: 0,
|
||||||
is_primary: false,
|
is_primary: false,
|
||||||
|
..Default::default()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DiagnosticEntry {
|
DiagnosticEntry {
|
||||||
|
@ -3957,6 +4019,7 @@ mod tests {
|
||||||
message: "error 2 hint 1".to_string(),
|
message: "error 2 hint 1".to_string(),
|
||||||
group_id: 1,
|
group_id: 1,
|
||||||
is_primary: false,
|
is_primary: false,
|
||||||
|
..Default::default()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DiagnosticEntry {
|
DiagnosticEntry {
|
||||||
|
@ -3966,6 +4029,7 @@ mod tests {
|
||||||
message: "error 2 hint 2".to_string(),
|
message: "error 2 hint 2".to_string(),
|
||||||
group_id: 1,
|
group_id: 1,
|
||||||
is_primary: false,
|
is_primary: false,
|
||||||
|
..Default::default()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DiagnosticEntry {
|
DiagnosticEntry {
|
||||||
|
@ -3975,16 +4039,14 @@ mod tests {
|
||||||
message: "error 2".to_string(),
|
message: "error 2".to_string(),
|
||||||
group_id: 1,
|
group_id: 1,
|
||||||
is_primary: true,
|
is_primary: true,
|
||||||
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
buffer
|
buffer.diagnostic_group::<Point>(0).collect::<Vec<_>>(),
|
||||||
.snapshot()
|
|
||||||
.diagnostic_group::<Point>(0)
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
&[
|
&[
|
||||||
DiagnosticEntry {
|
DiagnosticEntry {
|
||||||
range: Point::new(1, 8)..Point::new(1, 9),
|
range: Point::new(1, 8)..Point::new(1, 9),
|
||||||
|
@ -3993,6 +4055,7 @@ mod tests {
|
||||||
message: "error 1".to_string(),
|
message: "error 1".to_string(),
|
||||||
group_id: 0,
|
group_id: 0,
|
||||||
is_primary: true,
|
is_primary: true,
|
||||||
|
..Default::default()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DiagnosticEntry {
|
DiagnosticEntry {
|
||||||
|
@ -4002,15 +4065,13 @@ mod tests {
|
||||||
message: "error 1 hint 1".to_string(),
|
message: "error 1 hint 1".to_string(),
|
||||||
group_id: 0,
|
group_id: 0,
|
||||||
is_primary: false,
|
is_primary: false,
|
||||||
|
..Default::default()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
buffer
|
buffer.diagnostic_group::<Point>(1).collect::<Vec<_>>(),
|
||||||
.snapshot()
|
|
||||||
.diagnostic_group::<Point>(1)
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
&[
|
&[
|
||||||
DiagnosticEntry {
|
DiagnosticEntry {
|
||||||
range: Point::new(1, 13)..Point::new(1, 15),
|
range: Point::new(1, 13)..Point::new(1, 15),
|
||||||
|
@ -4019,6 +4080,7 @@ mod tests {
|
||||||
message: "error 2 hint 1".to_string(),
|
message: "error 2 hint 1".to_string(),
|
||||||
group_id: 1,
|
group_id: 1,
|
||||||
is_primary: false,
|
is_primary: false,
|
||||||
|
..Default::default()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DiagnosticEntry {
|
DiagnosticEntry {
|
||||||
|
@ -4028,6 +4090,7 @@ mod tests {
|
||||||
message: "error 2 hint 2".to_string(),
|
message: "error 2 hint 2".to_string(),
|
||||||
group_id: 1,
|
group_id: 1,
|
||||||
is_primary: false,
|
is_primary: false,
|
||||||
|
..Default::default()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DiagnosticEntry {
|
DiagnosticEntry {
|
||||||
|
@ -4037,13 +4100,11 @@ mod tests {
|
||||||
message: "error 2".to_string(),
|
message: "error 2".to_string(),
|
||||||
group_id: 1,
|
group_id: 1,
|
||||||
is_primary: true,
|
is_primary: true,
|
||||||
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
buffer
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test(iterations = 100)]
|
#[gpui::test(iterations = 100)]
|
||||||
|
|
|
@ -40,6 +40,7 @@ message Envelope {
|
||||||
UnshareWorktree unshare_worktree = 35;
|
UnshareWorktree unshare_worktree = 35;
|
||||||
UpdateContacts update_contacts = 36;
|
UpdateContacts update_contacts = 36;
|
||||||
LeaveWorktree leave_worktree = 37;
|
LeaveWorktree leave_worktree = 37;
|
||||||
|
UpdateDiagnosticSummary update_diagnostic_summary = 38;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +139,13 @@ message BufferSaved {
|
||||||
Timestamp mtime = 4;
|
Timestamp mtime = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message UpdateDiagnosticSummary {
|
||||||
|
uint64 worktree_id = 1;
|
||||||
|
string path = 2;
|
||||||
|
uint32 error_count = 3;
|
||||||
|
uint32 warning_count = 4;
|
||||||
|
}
|
||||||
|
|
||||||
message GetChannels {}
|
message GetChannels {}
|
||||||
|
|
||||||
message GetChannelsResponse {
|
message GetChannelsResponse {
|
||||||
|
|
|
@ -1719,7 +1719,8 @@ mod tests {
|
||||||
group_id: 0,
|
group_id: 0,
|
||||||
message: "message 1".to_string(),
|
message: "message 1".to_string(),
|
||||||
severity: lsp::DiagnosticSeverity::ERROR,
|
severity: lsp::DiagnosticSeverity::ERROR,
|
||||||
is_primary: true
|
is_primary: true,
|
||||||
|
..Default::default()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DiagnosticEntry {
|
DiagnosticEntry {
|
||||||
|
@ -1728,7 +1729,8 @@ mod tests {
|
||||||
group_id: 1,
|
group_id: 1,
|
||||||
severity: lsp::DiagnosticSeverity::WARNING,
|
severity: lsp::DiagnosticSeverity::WARNING,
|
||||||
message: "message 2".to_string(),
|
message: "message 2".to_string(),
|
||||||
is_primary: true
|
is_primary: true,
|
||||||
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in a new issue