Replace Default trait bound with a zero function on Summary/Dimension (#17975)

This lets us provide a context when constructing the zero value. We need
it so we can require anchors to be associated with a buffer id, which
we're doing as part of simplifying the multibuffer API.

Release Notes:

- N/A

Co-authored-by: Nathan <nathan@zed.dev>
This commit is contained in:
Antonio Scandurra 2024-09-17 19:43:59 -06:00 committed by GitHub
parent 4d074fc737
commit 2e72fd210a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
28 changed files with 706 additions and 349 deletions

View file

@ -722,7 +722,9 @@ impl Buffer {
capability: Capability,
) -> Self {
let saved_mtime = file.as_ref().and_then(|file| file.mtime());
let snapshot = buffer.snapshot();
let git_diff = git::diff::BufferDiff::new(&snapshot);
let syntax_map = Mutex::new(SyntaxMap::new(&snapshot));
Self {
saved_mtime,
saved_version: buffer.version(),
@ -739,10 +741,10 @@ impl Buffer {
})
.map(Rope::from),
diff_base_version: 0,
git_diff: git::diff::BufferDiff::new(),
git_diff,
file,
capability,
syntax_map: Mutex::new(SyntaxMap::new()),
syntax_map,
parsing_in_background: false,
non_text_state_update_count: 0,
sync_parse_timeout: Duration::from_millis(1),
@ -809,7 +811,7 @@ impl Buffer {
/// Assign a language to the buffer.
pub fn set_language(&mut self, language: Option<Arc<Language>>, cx: &mut ModelContext<Self>) {
self.non_text_state_update_count += 1;
self.syntax_map.lock().clear();
self.syntax_map.lock().clear(&self.text);
self.language = language;
self.reparse(cx);
cx.emit(BufferEvent::LanguageChanged);

View file

@ -15,7 +15,7 @@ use text::{Anchor, FromAnchor, PointUtf16, ToOffset};
/// The diagnostics are stored in a [`SumTree`], which allows this struct
/// to be cheaply copied, and allows for efficient retrieval of the
/// diagnostics that intersect a given range of the buffer.
#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug)]
pub struct DiagnosticSet {
diagnostics: SumTree<DiagnosticEntry<Anchor>>,
}
@ -135,7 +135,7 @@ impl DiagnosticSet {
{
let end_bias = if inclusive { Bias::Right } else { Bias::Left };
let range = buffer.anchor_before(range.start)..buffer.anchor_at(range.end, end_bias);
let mut cursor = self.diagnostics.filter::<_, ()>({
let mut cursor = self.diagnostics.filter::<_, ()>(buffer, {
move |summary: &Summary| {
let start_cmp = range.start.cmp(&summary.max_end, buffer);
let end_cmp = range.end.cmp(&summary.min_start, buffer);
@ -261,6 +261,10 @@ impl Default for Summary {
impl sum_tree::Summary for Summary {
type Context = text::BufferSnapshot;
fn zero(_cx: &Self::Context) -> Self {
Default::default()
}
fn add_summary(&mut self, other: &Self, buffer: &Self::Context) {
if other.min_start.cmp(&self.min_start, buffer).is_lt() {
self.min_start = other.min_start;

View file

@ -18,13 +18,12 @@ use sum_tree::{Bias, SeekTarget, SumTree};
use text::{Anchor, BufferSnapshot, OffsetRangeExt, Point, Rope, ToOffset, ToPoint};
use tree_sitter::{Node, Query, QueryCapture, QueryCaptures, QueryCursor, QueryMatches, Tree};
#[derive(Default)]
pub struct SyntaxMap {
snapshot: SyntaxSnapshot,
language_registry: Option<Arc<LanguageRegistry>>,
}
#[derive(Clone, Default)]
#[derive(Clone)]
pub struct SyntaxSnapshot {
layers: SumTree<SyntaxLayerEntry>,
parsed_version: clock::Global,
@ -212,8 +211,11 @@ struct ByteChunks<'a>(text::Chunks<'a>);
pub(crate) struct QueryCursorHandle(Option<QueryCursor>);
impl SyntaxMap {
pub fn new() -> Self {
Self::default()
pub fn new(text: &BufferSnapshot) -> Self {
Self {
snapshot: SyntaxSnapshot::new(text),
language_registry: None,
}
}
pub fn set_language_registry(&mut self, registry: Arc<LanguageRegistry>) {
@ -242,12 +244,21 @@ impl SyntaxMap {
self.snapshot = snapshot;
}
pub fn clear(&mut self) {
self.snapshot = SyntaxSnapshot::default();
pub fn clear(&mut self, text: &BufferSnapshot) {
self.snapshot = SyntaxSnapshot::new(text);
}
}
impl SyntaxSnapshot {
fn new(text: &BufferSnapshot) -> Self {
Self {
layers: SumTree::new(text),
parsed_version: clock::Global::default(),
interpolated_version: clock::Global::default(),
language_registry_version: 0,
}
}
pub fn is_empty(&self) -> bool {
self.layers.is_empty()
}
@ -262,10 +273,10 @@ impl SyntaxSnapshot {
return;
}
let mut layers = SumTree::new();
let mut layers = SumTree::new(text);
let mut first_edit_ix_for_depth = 0;
let mut prev_depth = 0;
let mut cursor = self.layers.cursor::<SyntaxLayerSummary>();
let mut cursor = self.layers.cursor::<SyntaxLayerSummary>(text);
cursor.next(text);
'outer: loop {
@ -388,7 +399,7 @@ impl SyntaxSnapshot {
let mut resolved_injection_ranges = Vec::new();
let mut cursor = self
.layers
.filter::<_, ()>(|summary| summary.contains_unknown_injections);
.filter::<_, ()>(text, |summary| summary.contains_unknown_injections);
cursor.next(text);
while let Some(layer) = cursor.item() {
let SyntaxLayerContent::Pending { language_name } = &layer.content else {
@ -430,9 +441,9 @@ impl SyntaxSnapshot {
log::trace!("reparse. invalidated ranges:{:?}", invalidated_ranges);
let max_depth = self.layers.summary().max_depth;
let mut cursor = self.layers.cursor::<SyntaxLayerSummary>();
let mut cursor = self.layers.cursor::<SyntaxLayerSummary>(text);
cursor.next(text);
let mut layers = SumTree::new();
let mut layers = SumTree::new(text);
let mut changed_regions = ChangeRegionSet::default();
let mut queue = BinaryHeap::new();
@ -823,7 +834,7 @@ impl SyntaxSnapshot {
let start = buffer.anchor_before(start_offset);
let end = buffer.anchor_after(end_offset);
let mut cursor = self.layers.filter::<_, ()>(move |summary| {
let mut cursor = self.layers.filter::<_, ()>(buffer, move |summary| {
if summary.max_depth > summary.min_depth {
true
} else {
@ -1666,6 +1677,10 @@ impl Default for SyntaxLayerSummary {
impl sum_tree::Summary for SyntaxLayerSummary {
type Context = BufferSnapshot;
fn zero(_cx: &BufferSnapshot) -> Self {
Default::default()
}
fn add_summary(&mut self, other: &Self, buffer: &Self::Context) {
if other.max_depth > self.max_depth {
self.max_depth = other.max_depth;

View file

@ -103,7 +103,7 @@ fn test_syntax_map_layers_for_range(cx: &mut AppContext) {
.unindent(),
);
let mut syntax_map = SyntaxMap::new();
let mut syntax_map = SyntaxMap::new(&buffer);
syntax_map.set_language_registry(registry.clone());
syntax_map.reparse(language.clone(), &buffer);
@ -202,7 +202,7 @@ fn test_dynamic_language_injection(cx: &mut AppContext) {
.unindent(),
);
let mut syntax_map = SyntaxMap::new();
let mut syntax_map = SyntaxMap::new(&buffer);
syntax_map.set_language_registry(registry.clone());
syntax_map.reparse(markdown.clone(), &buffer);
syntax_map.reparse(markdown_inline.clone(), &buffer);
@ -897,11 +897,11 @@ fn test_random_edits(
let mut buffer = Buffer::new(0, BufferId::new(1).unwrap(), text);
let mut syntax_map = SyntaxMap::new();
let mut syntax_map = SyntaxMap::new(&buffer);
syntax_map.set_language_registry(registry.clone());
syntax_map.reparse(language.clone(), &buffer);
let mut reference_syntax_map = SyntaxMap::new();
let mut reference_syntax_map = SyntaxMap::new(&buffer);
reference_syntax_map.set_language_registry(registry.clone());
log::info!("initial text:\n{}", buffer.text());
@ -918,7 +918,7 @@ fn test_random_edits(
syntax_map.reparse(language.clone(), &buffer);
reference_syntax_map.clear();
reference_syntax_map.clear(&buffer);
reference_syntax_map.reparse(language.clone(), &buffer);
}
@ -931,7 +931,7 @@ fn test_random_edits(
syntax_map.interpolate(&buffer);
syntax_map.reparse(language.clone(), &buffer);
reference_syntax_map.clear();
reference_syntax_map.clear(&buffer);
reference_syntax_map.reparse(language.clone(), &buffer);
assert_eq!(
syntax_map.layers(&buffer).len(),
@ -1082,7 +1082,7 @@ fn test_edit_sequence(
.unwrap();
let mut buffer = Buffer::new(0, BufferId::new(1).unwrap(), Default::default());
let mut mutated_syntax_map = SyntaxMap::new();
let mut mutated_syntax_map = SyntaxMap::new(&buffer);
mutated_syntax_map.set_language_registry(registry.clone());
mutated_syntax_map.reparse(language.clone(), &buffer);
@ -1097,7 +1097,7 @@ fn test_edit_sequence(
// Create a second syntax map from scratch
log::info!("fresh parse {i}: {marked_string:?}");
let mut reference_syntax_map = SyntaxMap::new();
let mut reference_syntax_map = SyntaxMap::new(&buffer);
reference_syntax_map.set_language_registry(registry.clone());
reference_syntax_map.reparse(language.clone(), &buffer);