1813 lines · 60.2 KB · Rust
RawDownload
#[cfg(test)]mod syntax_map_tests; use crate::{Grammar, InjectionConfig, Language, LanguageId, LanguageRegistry};use collections::HashMap;use futures::FutureExt;use parking_lot::Mutex;use std::{    borrow::Cow,    cmp::{self, Ordering, Reverse},    collections::BinaryHeap,    fmt, iter,    ops::{Deref, DerefMut, Range},    sync::Arc,};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}; use super::PARSER; static QUERY_CURSORS: Mutex<Vec<QueryCursor>> = Mutex::new(vec![]); #[derive(Default)]pub struct SyntaxMap {    snapshot: SyntaxSnapshot,    language_registry: Option<Arc<LanguageRegistry>>,} #[derive(Clone, Default)]pub struct SyntaxSnapshot {    layers: SumTree<SyntaxLayerEntry>,    parsed_version: clock::Global,    interpolated_version: clock::Global,    language_registry_version: usize,} #[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 depth: usize,    pub node: Node<'a>,    pub index: u32,    pub grammar_index: usize,} #[derive(Debug)]pub struct SyntaxMapMatch<'a> {    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> {    depth: usize,    next_pattern_index: usize,    next_captures: Vec<QueryCapture<'a>>,    has_next: bool,    matches: QueryMatches<'a, 'a, TextProvider<'a>, &'a [u8]>,    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>,    },    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> {        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>,    depth: usize,    tree: &'a Tree,    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,    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 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>); struct QueryCursorHandle(Option<QueryCursor>); impl SyntaxMap {    pub fn new() -> Self {        Self::default()    }     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) {        self.snapshot = SyntaxSnapshot::default();    }} impl SyntaxSnapshot {    pub fn is_empty(&self) -> bool {        self.layers.is_empty()    }     fn interpolate(&mut self, text: &BufferSnapshot) {        let edits = text            .anchored_edits_since::<(usize, Point)>(&self.interpolated_version)            .collect::<Vec<_>>();        self.interpolated_version = text.version().clone();         if edits.is_empty() {            return;        }         let mut layers = SumTree::new();        let mut first_edit_ix_for_depth = 0;        let mut prev_depth = 0;        let mut cursor = self.layers.cursor::<SyntaxLayerSummary>();        cursor.next(text);         'outer: loop {            let depth = cursor.end(text).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, text);                    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..Anchor::MAX,                        language: None,                    },                    Bias::Left,                    text,                );                layers.append(slice, text);                continue;            };             let Some(layer) = cursor.item() else { break };            let (start_byte, start_point) = layer.range.start.summary::<(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(text);        }         layers.append(cursor.suffix(text), text);        drop(cursor);        self.layers = layers;    }     pub fn reparse(        &mut self,        text: &BufferSnapshot,        registry: Option<Arc<LanguageRegistry>>,        root_language: Arc<Language>,    ) {        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());         if let Some(registry) = registry {            if registry.version() != self.language_registry_version {                let mut resolved_injection_ranges = Vec::new();                let mut cursor = self                    .layers                    .filter::<_, ()>(|summary| summary.contains_unknown_injections);                cursor.next(text);                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()                    {                        resolved_injection_ranges.push(layer.range.to_offset(text));                    }                     cursor.next(text);                }                drop(cursor);                 if !resolved_injection_ranges.is_empty() {                    self.reparse_with_ranges(                        text,                        root_language,                        resolved_injection_ranges,                        Some(&registry),                    );                }                self.language_registry_version = registry.version();            }        }    }     fn reparse_with_ranges(        &mut self,        text: &BufferSnapshot,        root_language: Arc<Language>,        invalidated_ranges: Vec<Range<usize>>,        registry: Option<&Arc<LanguageRegistry>>,    ) {        log::trace!("reparse. invalidated ranges:{:?}", invalidated_ranges);         let max_depth = self.layers.summary().max_depth;        let mut cursor = self.layers.cursor::<SyntaxLayerSummary>();        cursor.next(text);        let mut layers = SumTree::new();         let mut changed_regions = ChangeRegionSet::default();        let mut queue = BinaryHeap::new();        let mut combined_injection_ranges = HashMap::default();        queue.push(ParseStep {            depth: 0,            language: ParseStepLanguage::Loaded {                language: root_language,            },            included_ranges: vec![tree_sitter::Range {                start_byte: 0,                end_byte: text.len(),                start_point: Point::zero().to_ts_point(),                end_point: text.max_point().to_ts_point(),            }],            range: Anchor::MIN..Anchor::MAX,            mode: ParseMode::Single,        });         loop {            let step = queue.pop();            let position = if let Some(step) = &step {                SyntaxLayerPosition {                    depth: step.depth,                    range: step.range.clone(),                    language: step.language.id(),                }            } else {                SyntaxLayerPosition {                    depth: max_depth + 1,                    range: Anchor::MAX..Anchor::MAX,                    language: None,                }            };             let mut done = cursor.item().is_none();            while !done && position.cmp(&cursor.end(text), text).is_gt() {                done = true;                 let bounded_position = SyntaxLayerPositionBeforeChange {                    position: position.clone(),                    change: changed_regions.start_position(),                };                if bounded_position.cmp(cursor.start(), text).is_gt() {                    let slice = cursor.slice(&bounded_position, Bias::Left, text);                    if !slice.is_empty() {                        layers.append(slice, text);                        if changed_regions.prune(cursor.end(text), text) {                            done = false;                        }                    }                }                 while position.cmp(&cursor.end(text), text).is_gt() {                    let Some(layer) = cursor.item() else { break };                     if changed_regions.intersects(layer, text) {                        if let SyntaxLayerContent::Parsed { language, .. } = &layer.content {                            log::trace!(                                "discard layer. language:{}, range:{:?}. changed_regions:{:?}",                                language.name(),                                LogAnchorRange(&layer.range, text),                                LogChangedRegions(&changed_regions, text),

Lines 1–500 of 1813.