#[cfg(test)]mod syntax_map_tests; use crate::{ Grammar, InjectionConfig, Language, LanguageId, LanguageRegistry, QUERY_CURSORS, with_parser,};use collections::HashMap;use futures::FutureExt;use gpui::SharedString;use std::{ borrow::Cow, cmp::{self, Ordering, Reverse}, collections::BinaryHeap, fmt, iter, ops::{ControlFlow, Deref, DerefMut, Range}, sync::{Arc, LazyLock}, time::{Duration, Instant},};use streaming_iterator::StreamingIterator;use sum_tree::{Bias, Dimensions, SeekTarget, SumTree};use text::{Anchor, BufferSnapshot, OffsetRangeExt, Point, Rope, ToOffset, ToPoint};use tree_sitter::{ Node, Query, QueryCapture, QueryCaptures, QueryCursor, QueryMatch, QueryMatches, QueryPredicateArg,}; pub const MAX_BYTES_TO_QUERY: usize = 16 * 1024; pub struct SyntaxMap { snapshot: SyntaxSnapshot, language_registry: Option<Arc<LanguageRegistry>>,} #[derive(Clone)]pub struct SyntaxSnapshot { layers: SumTree<SyntaxLayerEntry>, parsed_version: clock::Global, interpolated_version: clock::Global, language_registry_version: usize, update_count: usize,} // Dropping deep treesitter Trees can be quite slow due to deallocating lots of memory.// To avoid blocking the main thread, we offload the drop operation to a background thread.impl Drop for SyntaxSnapshot { fn drop(&mut self) { static DROP_TX: LazyLock<std::sync::mpsc::Sender<SumTree<SyntaxLayerEntry>>> = LazyLock::new(|| { let (tx, rx) = std::sync::mpsc::channel(); std::thread::Builder::new() .name("SyntaxSnapshot::drop".into()) .spawn(move || while let Ok(_) = rx.recv() {}) .expect("failed to spawn drop thread"); tx }); // This does allocate a new Arc, but it's cheap and avoids blocking the main thread without needing to use an `Option` or `MaybeUninit`. let _ = DROP_TX.send(std::mem::replace( &mut self.layers, SumTree::from_summary(Default::default()), )); }} #[derive(Default)]pub struct SyntaxMapCaptures<'a> { layers: Vec<SyntaxMapCapturesLayer<'a>>, active_layer_count: usize, grammars: Vec<&'a Grammar>,} #[derive(Default)]pub struct SyntaxMapMatches<'a> { layers: Vec<SyntaxMapMatchesLayer<'a>>, active_layer_count: usize, grammars: Vec<&'a Grammar>,} #[derive(Debug)]pub struct SyntaxMapCapture<'a> { pub node: Node<'a>, pub index: u32, pub grammar_index: usize,} #[derive(Debug)]pub struct SyntaxMapMatch<'a> { pub language: Arc<Language>, pub depth: usize, pub pattern_index: usize, pub captures: &'a [QueryCapture<'a>], pub grammar_index: usize,} struct SyntaxMapCapturesLayer<'a> { depth: usize, captures: QueryCaptures<'a, 'a, TextProvider<'a>, &'a [u8]>, next_capture: Option<QueryCapture<'a>>, grammar_index: usize, _query_cursor: QueryCursorHandle,} struct SyntaxMapMatchesLayer<'a> { language: Arc<Language>, depth: usize, next_pattern_index: usize, next_captures: Vec<QueryCapture<'a>>, has_next: bool, matches: QueryMatches<'a, 'a, TextProvider<'a>, &'a [u8]>, query: &'a Query, grammar_index: usize, _query_cursor: QueryCursorHandle,} #[derive(Clone)]struct SyntaxLayerEntry { depth: usize, range: Range<Anchor>, content: SyntaxLayerContent,} #[derive(Clone)]enum SyntaxLayerContent { Parsed { tree: tree_sitter::Tree, language: Arc<Language>, included_sub_ranges: Option<Vec<Range<Anchor>>>, }, Pending { language_name: Arc<str>, },} impl SyntaxLayerContent { fn language_id(&self) -> Option<LanguageId> { match self { SyntaxLayerContent::Parsed { language, .. } => Some(language.id), SyntaxLayerContent::Pending { .. } => None, } } fn tree(&self) -> Option<&tree_sitter::Tree> { match self { SyntaxLayerContent::Parsed { tree, .. } => Some(tree), SyntaxLayerContent::Pending { .. } => None, } }} /// A layer of syntax highlighting, corresponding to a single syntax/// tree in a particular language.#[derive(Debug)]pub struct SyntaxLayer<'a> { /// The language for this layer. pub language: &'a Arc<Language>, pub included_sub_ranges: Option<&'a [Range<Anchor>]>, pub(crate) depth: usize, tree: &'a tree_sitter::Tree, pub(crate) offset: (usize, tree_sitter::Point),} /// A layer of syntax highlighting. Like [SyntaxLayer], but holding/// owned data instead of references.#[derive(Clone)]pub struct OwnedSyntaxLayer { /// The language for this layer. pub language: Arc<Language>, tree: tree_sitter::Tree, pub offset: (usize, tree_sitter::Point),} #[derive(Debug, Clone)]struct SyntaxLayerSummary { min_depth: usize, max_depth: usize, range: Range<Anchor>, last_layer_range: Range<Anchor>, last_layer_language: Option<LanguageId>, contains_unknown_injections: bool,} #[derive(Clone, Debug)]struct SyntaxLayerPosition { depth: usize, range: Range<Anchor>, language: Option<LanguageId>,} #[derive(Clone, Debug)]struct ChangeStartPosition { depth: usize, position: Anchor,} #[derive(Clone, Debug)]struct SyntaxLayerPositionBeforeChange { position: SyntaxLayerPosition, change: ChangeStartPosition,} struct ParseStep { depth: usize, language: ParseStepLanguage, range: Range<Anchor>, included_ranges: Vec<tree_sitter::Range>, mode: ParseMode,} #[derive(Debug)]enum ParseStepLanguage { Loaded { language: Arc<Language> }, Pending { name: Arc<str> },} impl ParseStepLanguage { fn name(&self) -> SharedString { match self { ParseStepLanguage::Loaded { language } => language.name().0, ParseStepLanguage::Pending { name } => name.into(), } } fn id(&self) -> Option<LanguageId> { match self { ParseStepLanguage::Loaded { language } => Some(language.id), ParseStepLanguage::Pending { .. } => None, } }} enum ParseMode { Single, Combined { parent_layer_range: Range<usize>, parent_layer_changed_ranges: Vec<Range<usize>>, },} #[derive(Debug, PartialEq, Eq)]struct ChangedRegion { depth: usize, range: Range<Anchor>,} #[derive(Default)]struct ChangeRegionSet(Vec<ChangedRegion>); struct TextProvider<'a>(&'a Rope); struct ByteChunks<'a>(text::Chunks<'a>); pub(crate) struct QueryCursorHandle(Option<QueryCursor>); impl SyntaxMap { pub fn new(text: &BufferSnapshot) -> Self { Self { snapshot: SyntaxSnapshot::new(text), language_registry: None, } } pub fn set_language_registry(&mut self, registry: Arc<LanguageRegistry>) { self.language_registry = Some(registry); } pub fn snapshot(&self) -> SyntaxSnapshot { self.snapshot.clone() } pub fn language_registry(&self) -> Option<Arc<LanguageRegistry>> { self.language_registry.clone() } pub fn interpolate(&mut self, text: &BufferSnapshot) { self.snapshot.interpolate(text); } #[cfg(test)] pub fn reparse(&mut self, language: Arc<Language>, text: &BufferSnapshot) { self.snapshot .reparse(text, self.language_registry.clone(), language); } pub fn did_parse(&mut self, snapshot: SyntaxSnapshot) { self.snapshot = snapshot; } pub fn clear(&mut self, text: &BufferSnapshot) { let update_count = self.snapshot.update_count + 1; self.snapshot = SyntaxSnapshot::new(text); self.snapshot.update_count = update_count; }} 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, update_count: 0, } } pub fn is_empty(&self) -> bool { self.layers.is_empty() } pub fn root_language(&self) -> Option<Arc<Language>> { match &self.layers.first()?.content { SyntaxLayerContent::Parsed { language, .. } => Some(language.clone()), SyntaxLayerContent::Pending { .. } => None, } } pub fn update_count(&self) -> usize { self.update_count } #[ztracing::instrument(skip_all)] pub fn interpolate(&mut self, text: &BufferSnapshot) { let edits = text .anchored_edits_since::<Dimensions<usize, Point>>(&self.interpolated_version) .collect::<Vec<_>>(); self.interpolated_version = text.version().clone(); if edits.is_empty() { return; } 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>(text); cursor.next(); 'outer: loop { let depth = cursor.end().max_depth; if depth > prev_depth { first_edit_ix_for_depth = 0; prev_depth = depth; } // Preserve any layers at this depth that precede the first edit. if let Some((_, edit_range)) = edits.get(first_edit_ix_for_depth) { let target = ChangeStartPosition { depth, position: edit_range.start, }; if target.cmp(cursor.start(), text).is_gt() { let slice = cursor.slice(&target, Bias::Left); layers.append(slice, text); } } // If this layer follows all of the edits, then preserve it and any // subsequent layers at this same depth. else if cursor.item().is_some() { let slice = cursor.slice( &SyntaxLayerPosition { depth: depth + 1, range: Anchor::min_max_range_for_buffer(text.remote_id()), language: None, }, Bias::Left, ); layers.append(slice, text); continue; }; let Some(layer) = cursor.item() else { break }; let Dimensions(start_byte, start_point, _) = layer.range.start.summary::<Dimensions<usize, Point>>(text); // Ignore edits that end before the start of this layer, and don't consider them // for any subsequent layers at this same depth. loop { let Some((_, edit_range)) = edits.get(first_edit_ix_for_depth) else { continue 'outer; }; if edit_range.end.cmp(&layer.range.start, text).is_le() { first_edit_ix_for_depth += 1; } else { break; } } let mut layer = layer.clone(); if let SyntaxLayerContent::Parsed { tree, .. } = &mut layer.content { for (edit, edit_range) in &edits[first_edit_ix_for_depth..] { // Ignore any edits that follow this layer. if edit_range.start.cmp(&layer.range.end, text).is_ge() { break; } // Apply any edits that intersect this layer to the layer's syntax tree. let tree_edit = if edit_range.start.cmp(&layer.range.start, text).is_ge() { tree_sitter::InputEdit { start_byte: edit.new.start.0 - start_byte, old_end_byte: edit.new.start.0 - start_byte + (edit.old.end.0 - edit.old.start.0), new_end_byte: edit.new.end.0 - start_byte, start_position: (edit.new.start.1 - start_point).to_ts_point(), old_end_position: (edit.new.start.1 - start_point + (edit.old.end.1 - edit.old.start.1)) .to_ts_point(), new_end_position: (edit.new.end.1 - start_point).to_ts_point(), } } else { let node = tree.root_node(); tree_sitter::InputEdit { start_byte: 0, old_end_byte: node.end_byte(), new_end_byte: 0, start_position: Default::default(), old_end_position: node.end_position(), new_end_position: Default::default(), } }; tree.edit(&tree_edit); } debug_assert!( tree.root_node().end_byte() <= text.len(), "tree's size {}, is larger than text size {}", tree.root_node().end_byte(), text.len(), ); } layers.push(layer, text); cursor.next(); } layers.append(cursor.suffix(), text); drop(cursor); self.layers = layers; } #[ztracing::instrument(skip_all)] pub fn reparse( &mut self, text: &BufferSnapshot, registry: Option<Arc<LanguageRegistry>>, root_language: Arc<Language>, ) { self.reparse_(text, registry, root_language, None).ok(); } #[ztracing::instrument(skip_all)] pub fn reparse_with_timeout( &mut self, text: &BufferSnapshot, registry: Option<Arc<LanguageRegistry>>, root_language: Arc<Language>, budget: Duration, ) -> Result<(), ParseTimeout> { self.reparse_(text, registry, root_language, Some(budget)) } #[ztracing::instrument(skip_all, fields(lang = root_language.config.name.0.as_str()))] fn reparse_( &mut self, text: &BufferSnapshot, registry: Option<Arc<LanguageRegistry>>, root_language: Arc<Language>, mut budget: Option<Duration>, ) -> Result<(), ParseTimeout> { let budget = &mut budget; let edit_ranges = text .edits_since::<usize>(&self.parsed_version) .map(|edit| edit.new) .collect::<Vec<_>>(); self.reparse_with_ranges( text, root_language.clone(), edit_ranges, registry.as_ref(), budget, )?; if let Some(registry) = registry && registry.version() != self.language_registry_version { let mut resolved_injection_ranges = Vec::new(); let mut cursor = self .layers .filter::<_, ()>(text, |summary| summary.contains_unknown_injections); cursor.next(); while let Some(layer) = cursor.item() { let SyntaxLayerContent::Pending { language_name } = &layer.content else { unreachable!() }; if registry .language_for_name_or_extension(language_name) .now_or_never() .and_then(|language| language.ok()) .is_some() { let range = layer.range.to_offset(text);Lines 1–500 of 2216. Load more
#[cfg(test)] mod syntax_map_tests; use crate::{ Grammar, InjectionConfig, Language, LanguageId, LanguageRegistry, QUERY_CURSORS, with_parser, }; use collections::HashMap; use futures::FutureExt; use gpui::SharedString; use std::{ borrow::Cow, cmp::{self, Ordering, Reverse}, collections::BinaryHeap, fmt, iter, ops::{ControlFlow, Deref, DerefMut, Range}, sync::{Arc, LazyLock}, time::{Duration, Instant}, }; use streaming_iterator::StreamingIterator; use sum_tree::{Bias, Dimensions, SeekTarget, SumTree}; use text::{Anchor, BufferSnapshot, OffsetRangeExt, Point, Rope, ToOffset, ToPoint}; use tree_sitter::{ Node, Query, QueryCapture, QueryCaptures, QueryCursor, QueryMatch, QueryMatches, QueryPredicateArg, }; pub const MAX_BYTES_TO_QUERY: usize = 16 * 1024; pub struct SyntaxMap { snapshot: SyntaxSnapshot, language_registry: Option<Arc<LanguageRegistry>>, } #[derive(Clone)] pub struct SyntaxSnapshot { layers: SumTree<SyntaxLayerEntry>, parsed_version: clock::Global, interpolated_version: clock::Global, language_registry_version: usize, update_count: usize, } // Dropping deep treesitter Trees can be quite slow due to deallocating lots of memory. // To avoid blocking the main thread, we offload the drop operation to a background thread. impl Drop for SyntaxSnapshot { fn drop(&mut self) { static DROP_TX: LazyLock<std::sync::mpsc::Sender<SumTree<SyntaxLayerEntry>>> = LazyLock::new(|| { let (tx, rx) = std::sync::mpsc::channel(); std::thread::Builder::new() .name("SyntaxSnapshot::drop".into()) .spawn(move || while let Ok(_) = rx.recv() {}) .expect("failed to spawn drop thread"); tx }); // This does allocate a new Arc, but it's cheap and avoids blocking the main thread without needing to use an `Option` or `MaybeUninit`. let _ = DROP_TX.send(std::mem::replace( &mut self.layers, SumTree::from_summary(Default::default()), )); } } #[derive(Default)] pub struct SyntaxMapCaptures<'a> { layers: Vec<SyntaxMapCapturesLayer<'a>>, active_layer_count: usize, grammars: Vec<&'a Grammar>, } #[derive(Default)] pub struct SyntaxMapMatches<'a> { layers: Vec<SyntaxMapMatchesLayer<'a>>, active_layer_count: usize, grammars: Vec<&'a Grammar>, } #[derive(Debug)] pub struct SyntaxMapCapture<'a> { pub node: Node<'a>, pub index: u32, pub grammar_index: usize, } #[derive(Debug)] pub struct SyntaxMapMatch<'a> { pub language: Arc<Language>, pub depth: usize, pub pattern_index: usize, pub captures: &'a [QueryCapture<'a>], pub grammar_index: usize, } struct SyntaxMapCapturesLayer<'a> { depth: usize, captures: QueryCaptures<'a, 'a, TextProvider<'a>, &'a [u8]>, next_capture: Option<QueryCapture<'a>>, grammar_index: usize, _query_cursor: QueryCursorHandle, } struct SyntaxMapMatchesLayer<'a> { language: Arc<Language>, depth: usize, next_pattern_index: usize, next_captures: Vec<QueryCapture<'a>>, has_next: bool, matches: QueryMatches<'a, 'a, TextProvider<'a>, &'a [u8]>, query: &'a Query, grammar_index: usize, _query_cursor: QueryCursorHandle, } #[derive(Clone)] struct SyntaxLayerEntry { depth: usize, range: Range<Anchor>, content: SyntaxLayerContent, } #[derive(Clone)] enum SyntaxLayerContent { Parsed { tree: tree_sitter::Tree, language: Arc<Language>, included_sub_ranges: Option<Vec<Range<Anchor>>>, }, Pending { language_name: Arc<str>, }, } impl SyntaxLayerContent { fn language_id(&self) -> Option<LanguageId> { match self { SyntaxLayerContent::Parsed { language, .. } => Some(language.id), SyntaxLayerContent::Pending { .. } => None, } } fn tree(&self) -> Option<&tree_sitter::Tree> { match self { SyntaxLayerContent::Parsed { tree, .. } => Some(tree), SyntaxLayerContent::Pending { .. } => None, } } } /// A layer of syntax highlighting, corresponding to a single syntax /// tree in a particular language. #[derive(Debug)] pub struct SyntaxLayer<'a> { /// The language for this layer. pub language: &'a Arc<Language>, pub included_sub_ranges: Option<&'a [Range<Anchor>]>, pub(crate) depth: usize, tree: &'a tree_sitter::Tree, pub(crate) offset: (usize, tree_sitter::Point), } /// A layer of syntax highlighting. Like [SyntaxLayer], but holding /// owned data instead of references. #[derive(Clone)] pub struct OwnedSyntaxLayer { /// The language for this layer. pub language: Arc<Language>, tree: tree_sitter::Tree, pub offset: (usize, tree_sitter::Point), } #[derive(Debug, Clone)] struct SyntaxLayerSummary { min_depth: usize, max_depth: usize, range: Range<Anchor>, last_layer_range: Range<Anchor>, last_layer_language: Option<LanguageId>, contains_unknown_injections: bool, } #[derive(Clone, Debug)] struct SyntaxLayerPosition { depth: usize, range: Range<Anchor>, language: Option<LanguageId>, } #[derive(Clone, Debug)] struct ChangeStartPosition { depth: usize, position: Anchor, } #[derive(Clone, Debug)] struct SyntaxLayerPositionBeforeChange { position: SyntaxLayerPosition, change: ChangeStartPosition, } struct ParseStep { depth: usize, language: ParseStepLanguage, range: Range<Anchor>, included_ranges: Vec<tree_sitter::Range>, mode: ParseMode, } #[derive(Debug)] enum ParseStepLanguage { Loaded { language: Arc<Language> }, Pending { name: Arc<str> }, } impl ParseStepLanguage { fn name(&self) -> SharedString { match self { ParseStepLanguage::Loaded { language } => language.name().0, ParseStepLanguage::Pending { name } => name.into(), } } fn id(&self) -> Option<LanguageId> { match self { ParseStepLanguage::Loaded { language } => Some(language.id), ParseStepLanguage::Pending { .. } => None, } } } enum ParseMode { Single, Combined { parent_layer_range: Range<usize>, parent_layer_changed_ranges: Vec<Range<usize>>, }, } #[derive(Debug, PartialEq, Eq)] struct ChangedRegion { depth: usize, range: Range<Anchor>, } #[derive(Default)] struct ChangeRegionSet(Vec<ChangedRegion>); struct TextProvider<'a>(&'a Rope); struct ByteChunks<'a>(text::Chunks<'a>); pub(crate) struct QueryCursorHandle(Option<QueryCursor>); impl SyntaxMap { pub fn new(text: &BufferSnapshot) -> Self { Self { snapshot: SyntaxSnapshot::new(text), language_registry: None, } } pub fn set_language_registry(&mut self, registry: Arc<LanguageRegistry>) { self.language_registry = Some(registry); } pub fn snapshot(&self) -> SyntaxSnapshot { self.snapshot.clone() } pub fn language_registry(&self) -> Option<Arc<LanguageRegistry>> { self.language_registry.clone() } pub fn interpolate(&mut self, text: &BufferSnapshot) { self.snapshot.interpolate(text); } #[cfg(test)] pub fn reparse(&mut self, language: Arc<Language>, text: &BufferSnapshot) { self.snapshot .reparse(text, self.language_registry.clone(), language); } pub fn did_parse(&mut self, snapshot: SyntaxSnapshot) { self.snapshot = snapshot; } pub fn clear(&mut self, text: &BufferSnapshot) { let update_count = self.snapshot.update_count + 1; self.snapshot = SyntaxSnapshot::new(text); self.snapshot.update_count = update_count; } } 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, update_count: 0, } } pub fn is_empty(&self) -> bool { self.layers.is_empty() } pub fn root_language(&self) -> Option<Arc<Language>> { match &self.layers.first()?.content { SyntaxLayerContent::Parsed { language, .. } => Some(language.clone()), SyntaxLayerContent::Pending { .. } => None, } } pub fn update_count(&self) -> usize { self.update_count } #[ztracing::instrument(skip_all)] pub fn interpolate(&mut self, text: &BufferSnapshot) { let edits = text .anchored_edits_since::<Dimensions<usize, Point>>(&self.interpolated_version) .collect::<Vec<_>>(); self.interpolated_version = text.version().clone(); if edits.is_empty() { return; } 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>(text); cursor.next(); 'outer: loop { let depth = cursor.end().max_depth; if depth > prev_depth { first_edit_ix_for_depth = 0; prev_depth = depth; } // Preserve any layers at this depth that precede the first edit. if let Some((_, edit_range)) = edits.get(first_edit_ix_for_depth) { let target = ChangeStartPosition { depth, position: edit_range.start, }; if target.cmp(cursor.start(), text).is_gt() { let slice = cursor.slice(&target, Bias::Left); layers.append(slice, text); } } // If this layer follows all of the edits, then preserve it and any // subsequent layers at this same depth. else if cursor.item().is_some() { let slice = cursor.slice( &SyntaxLayerPosition { depth: depth + 1, range: Anchor::min_max_range_for_buffer(text.remote_id()), language: None, }, Bias::Left, ); layers.append(slice, text); continue; }; let Some(layer) = cursor.item() else { break }; let Dimensions(start_byte, start_point, _) = layer.range.start.summary::<Dimensions<usize, Point>>(text); // Ignore edits that end before the start of this layer, and don't consider them // for any subsequent layers at this same depth. loop { let Some((_, edit_range)) = edits.get(first_edit_ix_for_depth) else { continue 'outer; }; if edit_range.end.cmp(&layer.range.start, text).is_le() { first_edit_ix_for_depth += 1; } else { break; } } let mut layer = layer.clone(); if let SyntaxLayerContent::Parsed { tree, .. } = &mut layer.content { for (edit, edit_range) in &edits[first_edit_ix_for_depth..] { // Ignore any edits that follow this layer. if edit_range.start.cmp(&layer.range.end, text).is_ge() { break; } // Apply any edits that intersect this layer to the layer's syntax tree. let tree_edit = if edit_range.start.cmp(&layer.range.start, text).is_ge() { tree_sitter::InputEdit { start_byte: edit.new.start.0 - start_byte, old_end_byte: edit.new.start.0 - start_byte + (edit.old.end.0 - edit.old.start.0), new_end_byte: edit.new.end.0 - start_byte, start_position: (edit.new.start.1 - start_point).to_ts_point(), old_end_position: (edit.new.start.1 - start_point + (edit.old.end.1 - edit.old.start.1)) .to_ts_point(), new_end_position: (edit.new.end.1 - start_point).to_ts_point(), } } else { let node = tree.root_node(); tree_sitter::InputEdit { start_byte: 0, old_end_byte: node.end_byte(), new_end_byte: 0, start_position: Default::default(), old_end_position: node.end_position(), new_end_position: Default::default(), } }; tree.edit(&tree_edit); } debug_assert!( tree.root_node().end_byte() <= text.len(), "tree's size {}, is larger than text size {}", tree.root_node().end_byte(), text.len(), ); } layers.push(layer, text); cursor.next(); } layers.append(cursor.suffix(), text); drop(cursor); self.layers = layers; } #[ztracing::instrument(skip_all)] pub fn reparse( &mut self, text: &BufferSnapshot, registry: Option<Arc<LanguageRegistry>>, root_language: Arc<Language>, ) { self.reparse_(text, registry, root_language, None).ok(); } #[ztracing::instrument(skip_all)] pub fn reparse_with_timeout( &mut self, text: &BufferSnapshot, registry: Option<Arc<LanguageRegistry>>, root_language: Arc<Language>, budget: Duration, ) -> Result<(), ParseTimeout> { self.reparse_(text, registry, root_language, Some(budget)) } #[ztracing::instrument(skip_all, fields(lang = root_language.config.name.0.as_str()))] fn reparse_( &mut self, text: &BufferSnapshot, registry: Option<Arc<LanguageRegistry>>, root_language: Arc<Language>, mut budget: Option<Duration>, ) -> Result<(), ParseTimeout> { let budget = &mut budget; let edit_ranges = text .edits_since::<usize>(&self.parsed_version) .map(|edit| edit.new) .collect::<Vec<_>>(); self.reparse_with_ranges( text, root_language.clone(), edit_ranges, registry.as_ref(), budget, )?; if let Some(registry) = registry && registry.version() != self.language_registry_version { let mut resolved_injection_ranges = Vec::new(); let mut cursor = self .layers .filter::<_, ()>(text, |summary| summary.contains_unknown_injections); cursor.next(); while let Some(layer) = cursor.item() { let SyntaxLayerContent::Pending { language_name } = &layer.content else { unreachable!() }; if registry .language_for_name_or_extension(language_name) .now_or_never() .and_then(|language| language.ok()) .is_some() { let range = layer.range.to_offset(text);