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:
parent
4d074fc737
commit
2e72fd210a
28 changed files with 706 additions and 349 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue