Merge branch 'fragment-locators' into project-diagnostics

This commit is contained in:
Antonio Scandurra 2021-12-10 14:01:17 +01:00
commit c8d5e19492
7 changed files with 34 additions and 28 deletions

1
Cargo.lock generated
View file

@ -4857,6 +4857,7 @@ dependencies = [
"ctor", "ctor",
"env_logger", "env_logger",
"gpui", "gpui",
"lazy_static",
"log", "log",
"parking_lot", "parking_lot",
"rand 0.8.3", "rand 0.8.3",

View file

@ -23,7 +23,6 @@ use std::{
ffi::OsString, ffi::OsString,
future::Future, future::Future,
iter::{Iterator, Peekable}, iter::{Iterator, Peekable},
mem,
ops::{Deref, DerefMut, Range}, ops::{Deref, DerefMut, Range},
path::{Path, PathBuf}, path::{Path, PathBuf},
str, str,
@ -794,8 +793,7 @@ impl Buffer {
} }
drop(edits_since_save); drop(edits_since_save);
let mut diagnostics = mem::take(&mut self.diagnostics); let new_diagnostics = DiagnosticSet::new(
diagnostics.reset(
diagnostics_by_group_id diagnostics_by_group_id
.into_values() .into_values()
.flat_map(|mut diagnostics| { .flat_map(|mut diagnostics| {
@ -806,9 +804,9 @@ impl Buffer {
primary.diagnostic.is_primary = true; primary.diagnostic.is_primary = true;
diagnostics diagnostics
}), }),
self, content,
); );
self.diagnostics = diagnostics; self.diagnostics = new_diagnostics;
if let Some(version) = version { if let Some(version) = version {
let language_server = self.language_server.as_mut().unwrap(); let language_server = self.language_server.as_mut().unwrap();

View file

@ -37,20 +37,22 @@ impl DiagnosticSet {
} }
} }
pub fn reset<I>(&mut self, iter: I, buffer: &text::Snapshot) pub fn new<I>(iter: I, buffer: &text::Snapshot) -> Self
where where
I: IntoIterator<Item = DiagnosticEntry<PointUtf16>>, I: IntoIterator<Item = DiagnosticEntry<PointUtf16>>,
{ {
let mut entries = iter.into_iter().collect::<Vec<_>>(); let mut entries = iter.into_iter().collect::<Vec<_>>();
entries.sort_unstable_by_key(|entry| (entry.range.start, Reverse(entry.range.end))); entries.sort_unstable_by_key(|entry| (entry.range.start, Reverse(entry.range.end)));
self.diagnostics = SumTree::from_iter( Self {
diagnostics: SumTree::from_iter(
entries.into_iter().map(|entry| DiagnosticEntry { entries.into_iter().map(|entry| DiagnosticEntry {
range: buffer.anchor_before(entry.range.start) range: buffer.anchor_before(entry.range.start)
..buffer.anchor_after(entry.range.end), ..buffer.anchor_after(entry.range.end),
diagnostic: entry.diagnostic, diagnostic: entry.diagnostic,
}), }),
buffer, buffer,
); ),
}
} }
pub fn iter(&self) -> impl Iterator<Item = &DiagnosticEntry<Anchor>> { pub fn iter(&self) -> impl Iterator<Item = &DiagnosticEntry<Anchor>> {

View file

@ -15,6 +15,7 @@ collections = { path = "../collections" }
sum_tree = { path = "../sum_tree" } sum_tree = { path = "../sum_tree" }
anyhow = "1.0.38" anyhow = "1.0.38"
arrayvec = "0.7.1" arrayvec = "0.7.1"
lazy_static = "1.4"
log = "0.4" log = "0.4"
parking_lot = "0.11" parking_lot = "0.11"
rand = { version = "0.8.3", optional = true } rand = { version = "0.8.3", optional = true }

View file

@ -28,16 +28,18 @@ impl Anchor {
} }
} }
pub fn cmp<'a>(&self, other: &Anchor, buffer: &BufferSnapshot) -> Result<Ordering> { pub fn cmp(&self, other: &Anchor, buffer: &BufferSnapshot) -> Result<Ordering> {
let offset_comparison = if self.timestamp == other.timestamp { let fragment_id_comparison = if self.timestamp == other.timestamp {
self.offset.cmp(&other.offset) Ordering::Equal
} else { } else {
buffer buffer
.full_offset_for_anchor(self) .fragment_id_for_anchor(self)
.cmp(&buffer.full_offset_for_anchor(other)) .cmp(&buffer.fragment_id_for_anchor(other))
}; };
Ok(offset_comparison.then_with(|| self.bias.cmp(&other.bias))) Ok(fragment_id_comparison
.then_with(|| self.offset.cmp(&other.offset))
.then_with(|| self.bias.cmp(&other.bias)))
} }
pub fn bias_left(&self, buffer: &BufferSnapshot) -> Anchor { pub fn bias_left(&self, buffer: &BufferSnapshot) -> Anchor {

View file

@ -1,6 +1,12 @@
use lazy_static::lazy_static;
use smallvec::{smallvec, SmallVec}; use smallvec::{smallvec, SmallVec};
use std::iter; use std::iter;
lazy_static! {
pub static ref MIN: Locator = Locator::min();
pub static ref MAX: Locator = Locator::max();
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Locator(SmallVec<[u64; 4]>); pub struct Locator(SmallVec<[u64; 4]>);

View file

@ -1768,12 +1768,11 @@ impl BufferSnapshot {
} }
} }
fn full_offset_for_anchor(&self, anchor: &Anchor) -> FullOffset { fn fragment_id_for_anchor(&self, anchor: &Anchor) -> &Locator {
if *anchor == Anchor::min() { if *anchor == Anchor::min() {
Default::default() &locator::MIN
} else if *anchor == Anchor::max() { } else if *anchor == Anchor::max() {
let text = self.fragments.summary().text; &locator::MAX
FullOffset(text.visible + text.deleted)
} else { } else {
let anchor_key = InsertionFragmentKey { let anchor_key = InsertionFragmentKey {
timestamp: anchor.timestamp, timestamp: anchor.timestamp,
@ -1795,10 +1794,7 @@ impl BufferSnapshot {
} }
let insertion = insertion_cursor.item().expect("invalid insertion"); let insertion = insertion_cursor.item().expect("invalid insertion");
debug_assert_eq!(insertion.timestamp, anchor.timestamp, "invalid insertion"); debug_assert_eq!(insertion.timestamp, anchor.timestamp, "invalid insertion");
&insertion.fragment_id
let mut fragment_cursor = self.fragments.cursor::<(Option<&Locator>, FullOffset)>();
fragment_cursor.seek(&Some(&insertion.fragment_id), Bias::Left, &None);
fragment_cursor.start().1 + (anchor.offset - insertion.split_offset)
} }
} }