Remove duplication when assigning diagnostics and hardcode provider names
This commit is contained in:
parent
4f774e2bde
commit
11e3874b4a
8 changed files with 198 additions and 178 deletions
|
@ -23,7 +23,7 @@ use std::{
|
|||
ffi::OsString,
|
||||
future::Future,
|
||||
iter::{Iterator, Peekable},
|
||||
ops::{Deref, DerefMut, Range},
|
||||
ops::{Add, Deref, DerefMut, Range, Sub},
|
||||
path::{Path, PathBuf},
|
||||
str,
|
||||
sync::Arc,
|
||||
|
@ -31,7 +31,7 @@ use std::{
|
|||
vec,
|
||||
};
|
||||
use sum_tree::TreeMap;
|
||||
use text::operation_queue::OperationQueue;
|
||||
use text::{operation_queue::OperationQueue, rope::TextDimension};
|
||||
pub use text::{Buffer as TextBuffer, Operation as _, *};
|
||||
use theme::SyntaxTheme;
|
||||
use tree_sitter::{InputEdit, Parser, QueryCursor, Tree};
|
||||
|
@ -85,6 +85,12 @@ pub struct BufferSnapshot {
|
|||
parse_count: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct GroupId {
|
||||
source: Arc<str>,
|
||||
id: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Diagnostic {
|
||||
pub code: Option<String>,
|
||||
|
@ -740,13 +746,16 @@ impl Buffer {
|
|||
self.diagnostic_sets.iter().flat_map(|set| set.iter())
|
||||
}
|
||||
|
||||
pub fn update_diagnostics(
|
||||
pub fn update_diagnostics<T>(
|
||||
&mut self,
|
||||
provider_name: Arc<str>,
|
||||
version: Option<i32>,
|
||||
mut diagnostics: Vec<DiagnosticEntry<PointUtf16>>,
|
||||
mut diagnostics: Vec<DiagnosticEntry<T>>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Result<Operation> {
|
||||
) -> Result<Operation>
|
||||
where
|
||||
T: ToPoint + Ord + Clip + TextDimension + Add<Output = T> + Sub<Output = T> + Copy,
|
||||
{
|
||||
fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
|
||||
Ordering::Equal
|
||||
.then_with(|| b.is_primary.cmp(&a.is_primary))
|
||||
|
@ -755,13 +764,6 @@ impl Buffer {
|
|||
.then_with(|| a.message.cmp(&b.message))
|
||||
}
|
||||
|
||||
diagnostics.sort_unstable_by(|a, b| {
|
||||
Ordering::Equal
|
||||
.then_with(|| a.range.start.cmp(&b.range.start))
|
||||
.then_with(|| b.range.end.cmp(&a.range.end))
|
||||
.then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
|
||||
});
|
||||
|
||||
let version = version.map(|version| version as usize);
|
||||
let content = if let Some(version) = version {
|
||||
let language_server = self.language_server.as_mut().unwrap();
|
||||
|
@ -777,14 +779,18 @@ impl Buffer {
|
|||
self.deref()
|
||||
};
|
||||
|
||||
let mut edits_since_save = content
|
||||
.edits_since::<PointUtf16>(&self.saved_version)
|
||||
.peekable();
|
||||
let mut last_edit_old_end = PointUtf16::zero();
|
||||
let mut last_edit_new_end = PointUtf16::zero();
|
||||
let mut ix = 0;
|
||||
'outer: while ix < diagnostics.len() {
|
||||
let entry = &mut diagnostics[ix];
|
||||
diagnostics.sort_unstable_by(|a, b| {
|
||||
Ordering::Equal
|
||||
.then_with(|| a.range.start.cmp(&b.range.start))
|
||||
.then_with(|| b.range.end.cmp(&a.range.end))
|
||||
.then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
|
||||
});
|
||||
|
||||
let mut sanitized_diagnostics = Vec::new();
|
||||
let mut edits_since_save = content.edits_since::<T>(&self.saved_version).peekable();
|
||||
let mut last_edit_old_end = T::default();
|
||||
let mut last_edit_new_end = T::default();
|
||||
'outer: for entry in diagnostics {
|
||||
let mut start = entry.range.start;
|
||||
let mut end = entry.range.end;
|
||||
|
||||
|
@ -798,7 +804,6 @@ impl Buffer {
|
|||
last_edit_new_end = edit.new.end;
|
||||
edits_since_save.next();
|
||||
} else if edit.old.start <= end && edit.old.end >= start {
|
||||
diagnostics.remove(ix);
|
||||
continue 'outer;
|
||||
} else {
|
||||
break;
|
||||
|
@ -809,23 +814,26 @@ impl Buffer {
|
|||
end = last_edit_new_end + (end - last_edit_old_end);
|
||||
}
|
||||
|
||||
entry.range = content.clip_point_utf16(start, Bias::Left)
|
||||
..content.clip_point_utf16(end, Bias::Right);
|
||||
|
||||
let range = start.clip(Bias::Left, content)..end.clip(Bias::Right, content);
|
||||
let mut range = range.start.to_point(content)..range.end.to_point(content);
|
||||
// Expand empty ranges by one character
|
||||
if entry.range.start == entry.range.end {
|
||||
entry.range.end.column += 1;
|
||||
entry.range.end = content.clip_point_utf16(entry.range.end, Bias::Right);
|
||||
if entry.range.start == entry.range.end && entry.range.end.column > 0 {
|
||||
entry.range.start.column -= 1;
|
||||
entry.range.start = content.clip_point_utf16(entry.range.start, Bias::Left);
|
||||
if range.start == range.end {
|
||||
range.end.column += 1;
|
||||
range.end = content.clip_point(range.end, Bias::Right);
|
||||
if range.start == range.end && range.end.column > 0 {
|
||||
range.start.column -= 1;
|
||||
range.start = content.clip_point(range.start, Bias::Left);
|
||||
}
|
||||
}
|
||||
ix += 1;
|
||||
|
||||
sanitized_diagnostics.push(DiagnosticEntry {
|
||||
range,
|
||||
diagnostic: entry.diagnostic,
|
||||
});
|
||||
}
|
||||
drop(edits_since_save);
|
||||
|
||||
let set = DiagnosticSet::new(provider_name, diagnostics, content);
|
||||
let set = DiagnosticSet::new(provider_name, sanitized_diagnostics, content);
|
||||
self.apply_diagnostic_update(set.clone(), cx);
|
||||
Ok(Operation::UpdateDiagnostics {
|
||||
provider_name: set.provider_name().to_string(),
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::{
|
|||
sync::Arc,
|
||||
};
|
||||
use sum_tree::{self, Bias, SumTree};
|
||||
use text::{Anchor, FromAnchor, PointUtf16, ToOffset};
|
||||
use text::{Anchor, FromAnchor, Point, ToOffset};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DiagnosticSet {
|
||||
|
@ -56,7 +56,7 @@ impl DiagnosticSet {
|
|||
|
||||
pub fn new<I>(provider_name: Arc<str>, iter: I, buffer: &text::BufferSnapshot) -> Self
|
||||
where
|
||||
I: IntoIterator<Item = DiagnosticEntry<PointUtf16>>,
|
||||
I: IntoIterator<Item = DiagnosticEntry<Point>>,
|
||||
{
|
||||
let mut entries = iter.into_iter().collect::<Vec<_>>();
|
||||
entries.sort_unstable_by_key(|entry| (entry.range.start, Reverse(entry.range.end)));
|
||||
|
|
|
@ -65,9 +65,7 @@ pub struct BracketPair {
|
|||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait DiagnosticSource: 'static + Send + Sync {
|
||||
fn name(&self) -> Arc<str>;
|
||||
|
||||
pub trait DiagnosticProvider: 'static + Send + Sync {
|
||||
async fn diagnose(
|
||||
&self,
|
||||
path: Arc<Path>,
|
||||
|
@ -77,7 +75,7 @@ pub trait DiagnosticSource: 'static + Send + Sync {
|
|||
pub struct Language {
|
||||
pub(crate) config: LanguageConfig,
|
||||
pub(crate) grammar: Option<Arc<Grammar>>,
|
||||
pub(crate) diagnostic_source: Option<Arc<dyn DiagnosticSource>>,
|
||||
pub(crate) diagnostic_provider: Option<Arc<dyn DiagnosticProvider>>,
|
||||
}
|
||||
|
||||
pub struct Grammar {
|
||||
|
@ -142,7 +140,7 @@ impl Language {
|
|||
highlight_map: Default::default(),
|
||||
})
|
||||
}),
|
||||
diagnostic_source: None,
|
||||
diagnostic_provider: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,8 +174,8 @@ impl Language {
|
|||
Ok(self)
|
||||
}
|
||||
|
||||
pub fn with_diagnostic_source(mut self, source: impl DiagnosticSource) -> Self {
|
||||
self.diagnostic_source = Some(Arc::new(source));
|
||||
pub fn with_diagnostic_provider(mut self, source: impl DiagnosticProvider) -> Self {
|
||||
self.diagnostic_provider = Some(Arc::new(source));
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -214,8 +212,8 @@ impl Language {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn diagnostic_source(&self) -> Option<&Arc<dyn DiagnosticSource>> {
|
||||
self.diagnostic_source.as_ref()
|
||||
pub fn diagnostic_provider(&self) -> Option<&Arc<dyn DiagnosticProvider>> {
|
||||
self.diagnostic_provider.as_ref()
|
||||
}
|
||||
|
||||
pub fn disk_based_diagnostic_sources(&self) -> Option<&HashSet<String>> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue