Verify Anchor::buffer_id before resolving it or comparing it

This commit also verifies some properties about anchor resolution in the
multibuffer randomized test.

Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
Antonio Scandurra 2022-01-11 16:40:12 +01:00
parent 2d5e72251e
commit e70b728758
2 changed files with 114 additions and 75 deletions

View file

@ -1,5 +1,5 @@
use super::{ExcerptId, MultiBufferSnapshot, ToOffset, ToPoint};
use anyhow::{anyhow, Result};
use anyhow::Result;
use std::{
cmp::Ordering,
ops::{Range, Sub},
@ -40,27 +40,41 @@ impl Anchor {
if excerpt_id_cmp.is_eq() {
if self.excerpt_id == ExcerptId::min() || self.excerpt_id == ExcerptId::max() {
Ok(Ordering::Equal)
} else if let Some((buffer_id, buffer_snapshot)) =
snapshot.buffer_snapshot_for_excerpt(&self.excerpt_id)
{
// Even though the anchor refers to a valid excerpt the underlying buffer might have
// changed. In that case, treat the anchor as if it were at the start of that
// excerpt.
if self.buffer_id == buffer_id && other.buffer_id == buffer_id {
self.text_anchor.cmp(&other.text_anchor, buffer_snapshot)
} else if self.buffer_id == buffer_id {
Ok(Ordering::Greater)
} else if other.buffer_id == buffer_id {
Ok(Ordering::Less)
} else {
Ok(Ordering::Equal)
}
} else {
self.text_anchor.cmp(
&other.text_anchor,
snapshot
.buffer_snapshot_for_excerpt(&self.excerpt_id)
.ok_or_else(|| anyhow!("excerpt {:?} not found", self.excerpt_id))?,
)
Ok(Ordering::Equal)
}
} else {
return Ok(excerpt_id_cmp);
Ok(excerpt_id_cmp)
}
}
pub fn bias_left(&self, snapshot: &MultiBufferSnapshot) -> Anchor {
if self.text_anchor.bias != Bias::Left {
if let Some(buffer_snapshot) = snapshot.buffer_snapshot_for_excerpt(&self.excerpt_id) {
return Self {
buffer_id: self.buffer_id,
excerpt_id: self.excerpt_id.clone(),
text_anchor: self.text_anchor.bias_left(buffer_snapshot),
};
if let Some((buffer_id, buffer_snapshot)) =
snapshot.buffer_snapshot_for_excerpt(&self.excerpt_id)
{
if self.buffer_id == buffer_id {
return Self {
buffer_id: self.buffer_id,
excerpt_id: self.excerpt_id.clone(),
text_anchor: self.text_anchor.bias_left(buffer_snapshot),
};
}
}
}
self.clone()
@ -68,12 +82,16 @@ impl Anchor {
pub fn bias_right(&self, snapshot: &MultiBufferSnapshot) -> Anchor {
if self.text_anchor.bias != Bias::Right {
if let Some(buffer_snapshot) = snapshot.buffer_snapshot_for_excerpt(&self.excerpt_id) {
return Self {
buffer_id: self.buffer_id,
excerpt_id: self.excerpt_id.clone(),
text_anchor: self.text_anchor.bias_right(buffer_snapshot),
};
if let Some((buffer_id, buffer_snapshot)) =
snapshot.buffer_snapshot_for_excerpt(&self.excerpt_id)
{
if self.buffer_id == buffer_id {
return Self {
buffer_id: self.buffer_id,
excerpt_id: self.excerpt_id.clone(),
text_anchor: self.text_anchor.bias_right(buffer_snapshot),
};
}
}
}
self.clone()