From fe571f1d70602af24ccb74fd65a292f3ca3918f8 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 13 Dec 2021 16:36:53 -0800 Subject: [PATCH] Store diagnostic summaries on worktrees --- crates/diagnostics/src/diagnostics.rs | 2 +- crates/project/src/project.rs | 40 ++++++++++++++++++++++++--- crates/project/src/worktree.rs | 19 +++++++++---- 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index d04c69611b..1162dccc78 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -15,7 +15,7 @@ impl ProjectDiagnostics { cx: &mut ViewContext, ) -> Self { let mut buffer = cx.add_model(|cx| MultiBuffer::new(project.read(cx).replica_id(cx))); - for diagnostic_summary in project.read(cx).diagnostic_summaries(cx) { + for (project_path, diagnostic_summary) in project.read(cx).diagnostic_summaries(cx) { // } diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index ca15f67377..78c59404a6 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -8,7 +8,8 @@ use clock::ReplicaId; use futures::Future; use fuzzy::{PathMatch, PathMatchCandidate, PathMatchCandidateSet}; use gpui::{AppContext, Entity, ModelContext, ModelHandle, Task}; -use language::LanguageRegistry; +use language::{DiagnosticEntry, LanguageRegistry}; +use lsp::DiagnosticSeverity; use std::{ path::Path, sync::{atomic::AtomicBool, Arc}, @@ -39,14 +40,39 @@ pub struct ProjectPath { pub path: Arc, } +#[derive(Clone)] pub struct DiagnosticSummary { - pub project_path: ProjectPath, pub error_count: usize, pub warning_count: usize, pub info_count: usize, pub hint_count: usize, } +impl DiagnosticSummary { + fn new(diagnostics: &[DiagnosticEntry]) -> Self { + let mut this = Self { + error_count: 0, + warning_count: 0, + info_count: 0, + hint_count: 0, + }; + + for entry in diagnostics { + if entry.diagnostic.is_primary { + match entry.diagnostic.severity { + DiagnosticSeverity::ERROR => this.error_count += 1, + DiagnosticSeverity::WARNING => this.warning_count += 1, + DiagnosticSeverity::INFORMATION => this.info_count += 1, + DiagnosticSeverity::HINT => this.hint_count += 1, + _ => {} + } + } + } + + this + } +} + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct ProjectEntry { pub worktree_id: usize, @@ -176,8 +202,14 @@ impl Project { pub fn diagnostic_summaries<'a>( &'a self, cx: &'a AppContext, - ) -> impl Iterator { - std::iter::empty() + ) -> impl Iterator + 'a { + self.worktrees.iter().flat_map(move |worktree| { + let worktree_id = worktree.id(); + worktree + .read(cx) + .diagnostic_summaries() + .map(move |(path, summary)| (ProjectPath { worktree_id, path }, summary)) + }) } pub fn active_entry(&self) -> Option { diff --git a/crates/project/src/worktree.rs b/crates/project/src/worktree.rs index 4a646cb17b..89eeb4d917 100644 --- a/crates/project/src/worktree.rs +++ b/crates/project/src/worktree.rs @@ -472,9 +472,13 @@ impl Worktree { pub fn diagnostic_summaries<'a>( &'a self, - cx: &'a AppContext, - ) -> impl Iterator { - std::iter::empty() + ) -> impl Iterator, DiagnosticSummary)> + 'a { + match self { + Worktree::Local(worktree) => &worktree.diagnostic_summaries, + Worktree::Remote(worktree) => &worktree.diagnostic_summaries, + } + .iter() + .map(|(path, summary)| (path.clone(), summary.clone())) } pub fn loading_buffers<'a>(&'a mut self) -> &'a mut LoadingBuffers { @@ -879,16 +883,19 @@ impl Worktree { let (remote_id, operation) = buffer.update(cx, |buffer, cx| { ( buffer.remote_id(), - buffer.update_diagnostics(params.version, diagnostics, cx), + buffer.update_diagnostics(params.version, diagnostics.clone(), cx), ) }); self.send_buffer_update(remote_id, operation?, cx); - return Ok(()); + break; } } } - this.diagnostics.insert(worktree_path, diagnostics); + let this = self.as_local_mut().unwrap(); + this.diagnostic_summaries + .insert(worktree_path.clone(), DiagnosticSummary::new(&diagnostics)); + this.diagnostics.insert(worktree_path.clone(), diagnostics); Ok(()) }