syntax_map.rs

   1use crate::{
   2    Grammar, InjectionConfig, Language, LanguageRegistry, QueryCursorHandle, TextProvider,
   3    ToTreeSitterPoint,
   4};
   5use std::{
   6    borrow::Cow, cell::RefCell, cmp::Ordering, collections::BinaryHeap, ops::Range, sync::Arc,
   7};
   8use sum_tree::{Bias, SeekTarget, SumTree};
   9use text::{Anchor, BufferSnapshot, OffsetRangeExt, Point, Rope, ToOffset, ToPoint};
  10use tree_sitter::{Node, Parser, Tree};
  11
  12thread_local! {
  13    static PARSER: RefCell<Parser> = RefCell::new(Parser::new());
  14}
  15
  16#[derive(Default)]
  17pub struct SyntaxMap {
  18    parsed_version: clock::Global,
  19    interpolated_version: clock::Global,
  20    snapshot: SyntaxSnapshot,
  21    language_registry: Option<Arc<LanguageRegistry>>,
  22}
  23
  24#[derive(Clone, Default)]
  25pub struct SyntaxSnapshot {
  26    layers: SumTree<SyntaxLayer>,
  27}
  28
  29#[derive(Clone)]
  30struct SyntaxLayer {
  31    depth: usize,
  32    range: Range<Anchor>,
  33    tree: tree_sitter::Tree,
  34    language: Arc<Language>,
  35}
  36
  37#[derive(Debug, Clone)]
  38struct SyntaxLayerSummary {
  39    max_depth: usize,
  40    range: Range<Anchor>,
  41    last_layer_range: Range<Anchor>,
  42}
  43
  44#[derive(Clone, Debug)]
  45struct DepthAndRange(usize, Range<Anchor>);
  46
  47#[derive(Clone, Debug)]
  48struct DepthAndMaxPosition(usize, Anchor);
  49
  50#[derive(Clone, Debug)]
  51struct DepthAndRangeOrMaxPosition(DepthAndRange, DepthAndMaxPosition);
  52
  53struct ReparseStep {
  54    depth: usize,
  55    language: Arc<Language>,
  56    ranges: Vec<tree_sitter::Range>,
  57    range: Range<Anchor>,
  58}
  59
  60#[derive(Debug, PartialEq, Eq)]
  61struct ChangedRegion {
  62    depth: usize,
  63    range: Range<Anchor>,
  64}
  65
  66#[derive(Default)]
  67struct ChangeRegionSet(Vec<ChangedRegion>);
  68
  69impl SyntaxMap {
  70    pub fn new() -> Self {
  71        Self::default()
  72    }
  73
  74    pub fn set_language_registry(&mut self, registry: Arc<LanguageRegistry>) {
  75        self.language_registry = Some(registry);
  76    }
  77
  78    pub fn snapshot(&self) -> SyntaxSnapshot {
  79        self.snapshot.clone()
  80    }
  81
  82    pub fn interpolate(&mut self, text: &BufferSnapshot) {
  83        self.snapshot.interpolate(&self.interpolated_version, text);
  84        self.interpolated_version = text.version.clone();
  85    }
  86
  87    pub fn reparse(&mut self, language: Arc<Language>, text: &BufferSnapshot) {
  88        if !self.interpolated_version.observed_all(&text.version) {
  89            self.interpolate(text);
  90        }
  91
  92        self.snapshot.reparse(
  93            &self.parsed_version,
  94            text,
  95            self.language_registry.clone(),
  96            language,
  97        );
  98        self.parsed_version = text.version.clone();
  99    }
 100}
 101
 102impl SyntaxSnapshot {
 103    pub fn interpolate(&mut self, from_version: &clock::Global, text: &BufferSnapshot) {
 104        let edits = text
 105            .edits_since::<(usize, Point)>(&from_version)
 106            .collect::<Vec<_>>();
 107        if edits.is_empty() {
 108            return;
 109        }
 110
 111        let mut layers = SumTree::new();
 112        let mut edits_for_depth = &edits[..];
 113        let mut cursor = self.layers.cursor::<SyntaxLayerSummary>();
 114        cursor.next(text);
 115
 116        'outer: loop {
 117            let depth = cursor.end(text).max_depth;
 118
 119            // Preserve any layers at this depth that precede the first edit.
 120            if let Some(first_edit) = edits_for_depth.first() {
 121                let target = DepthAndMaxPosition(depth, text.anchor_before(first_edit.new.start.0));
 122                if target.cmp(&cursor.start(), text).is_gt() {
 123                    let slice = cursor.slice(&target, Bias::Left, text);
 124                    layers.push_tree(slice, text);
 125                }
 126            }
 127            // If this layer follows all of the edits, then preserve it and any
 128            // subsequent layers at this same depth.
 129            else {
 130                let slice = cursor.slice(
 131                    &DepthAndRange(depth + 1, Anchor::MIN..Anchor::MAX),
 132                    Bias::Left,
 133                    text,
 134                );
 135                layers.push_tree(slice, text);
 136                edits_for_depth = &edits[..];
 137                continue;
 138            };
 139
 140            let layer = if let Some(layer) = cursor.item() {
 141                layer
 142            } else {
 143                break;
 144            };
 145
 146            let mut endpoints = text
 147                .summaries_for_anchors::<(usize, Point), _>([&layer.range.start, &layer.range.end]);
 148            let layer_range = endpoints.next().unwrap()..endpoints.next().unwrap();
 149            let start_byte = layer_range.start.0;
 150            let start_point = layer_range.start.1;
 151            let end_byte = layer_range.end.0;
 152
 153            // Ignore edits that end before the start of this layer, and don't consider them
 154            // for any subsequent layers at this same depth.
 155            loop {
 156                if let Some(edit) = edits_for_depth.first() {
 157                    if edit.new.end.0 < start_byte {
 158                        edits_for_depth = &edits_for_depth[1..];
 159                    } else {
 160                        break;
 161                    }
 162                } else {
 163                    continue 'outer;
 164                }
 165            }
 166
 167            let mut layer = layer.clone();
 168            for edit in edits_for_depth {
 169                // Ignore any edits that follow this layer.
 170                if edit.new.start.0 > end_byte {
 171                    break;
 172                }
 173
 174                // Apply any edits that intersect this layer to the layer's syntax tree.
 175                let tree_edit = if edit.new.start.0 >= start_byte {
 176                    tree_sitter::InputEdit {
 177                        start_byte: edit.new.start.0 - start_byte,
 178                        old_end_byte: edit.new.start.0 - start_byte
 179                            + (edit.old.end.0 - edit.old.start.0),
 180                        new_end_byte: edit.new.end.0 - start_byte,
 181                        start_position: (edit.new.start.1 - start_point).to_ts_point(),
 182                        old_end_position: (edit.new.start.1 - start_point
 183                            + (edit.old.end.1 - edit.old.start.1))
 184                            .to_ts_point(),
 185                        new_end_position: (edit.new.end.1 - start_point).to_ts_point(),
 186                    }
 187                } else {
 188                    tree_sitter::InputEdit {
 189                        start_byte: 0,
 190                        old_end_byte: edit.new.end.0 - start_byte,
 191                        new_end_byte: 0,
 192                        start_position: Default::default(),
 193                        old_end_position: (edit.new.end.1 - start_point).to_ts_point(),
 194                        new_end_position: Default::default(),
 195                    }
 196                };
 197
 198                layer.tree.edit(&tree_edit);
 199                if edit.new.start.0 < start_byte {
 200                    break;
 201                }
 202            }
 203
 204            layers.push(layer, text);
 205            cursor.next(text);
 206        }
 207
 208        layers.push_tree(cursor.suffix(&text), &text);
 209        drop(cursor);
 210        self.layers = layers;
 211    }
 212
 213    pub fn reparse(
 214        &mut self,
 215        from_version: &clock::Global,
 216        text: &BufferSnapshot,
 217        registry: Option<Arc<LanguageRegistry>>,
 218        language: Arc<Language>,
 219    ) {
 220        let edits = text.edits_since::<usize>(from_version).collect::<Vec<_>>();
 221        if edits.is_empty() {
 222            return;
 223        }
 224
 225        let max_depth = self.layers.summary().max_depth;
 226        let mut cursor = self.layers.cursor::<SyntaxLayerSummary>();
 227        cursor.next(&text);
 228        let mut layers = SumTree::new();
 229
 230        let mut changed_regions = ChangeRegionSet::default();
 231        let mut queue = BinaryHeap::new();
 232        queue.push(ReparseStep {
 233            depth: 0,
 234            language: language.clone(),
 235            ranges: Vec::new(),
 236            range: Anchor::MIN..Anchor::MAX,
 237        });
 238
 239        loop {
 240            let step = queue.pop();
 241            let (depth, range) = if let Some(step) = &step {
 242                (step.depth, step.range.clone())
 243            } else {
 244                (max_depth + 1, Anchor::MAX..Anchor::MAX)
 245            };
 246
 247            let target = DepthAndRange(depth, range.clone());
 248            let mut done = cursor.item().is_none();
 249            while !done && target.cmp(&cursor.end(text), &text).is_gt() {
 250                done = true;
 251
 252                let bounded_target =
 253                    DepthAndRangeOrMaxPosition(target.clone(), changed_regions.start_position());
 254                if bounded_target.cmp(&cursor.start(), &text).is_gt() {
 255                    let slice = cursor.slice(&bounded_target, Bias::Left, text);
 256                    if !slice.is_empty() {
 257                        layers.push_tree(slice, &text);
 258                        if changed_regions.prune(cursor.end(text), text) {
 259                            done = false;
 260                        }
 261                    }
 262                }
 263
 264                while target.cmp(&cursor.end(text), text).is_gt() {
 265                    let layer = if let Some(layer) = cursor.item() {
 266                        layer
 267                    } else {
 268                        break;
 269                    };
 270
 271                    if changed_regions.intersects(&layer, text) {
 272                        changed_regions.insert(
 273                            ChangedRegion {
 274                                depth: depth + 1,
 275                                range: layer.range.clone(),
 276                            },
 277                            text,
 278                        );
 279                    } else {
 280                        layers.push(layer.clone(), text);
 281                    }
 282
 283                    cursor.next(text);
 284                    if changed_regions.prune(cursor.end(text), text) {
 285                        done = false;
 286                    }
 287                }
 288            }
 289
 290            let (ranges, language) = if let Some(step) = step {
 291                (step.ranges, step.language)
 292            } else {
 293                break;
 294            };
 295
 296            let start_point;
 297            let start_byte;
 298            let end_byte;
 299            if let Some((first, last)) = ranges.first().zip(ranges.last()) {
 300                start_point = first.start_point;
 301                start_byte = first.start_byte;
 302                end_byte = last.end_byte;
 303            } else {
 304                start_point = Point::zero().to_ts_point();
 305                start_byte = 0;
 306                end_byte = text.len();
 307            };
 308
 309            let mut old_layer = cursor.item();
 310            if let Some(layer) = old_layer {
 311                if layer.range.to_offset(text) == (start_byte..end_byte) {
 312                    cursor.next(&text);
 313                } else {
 314                    old_layer = None;
 315                }
 316            }
 317
 318            let grammar = if let Some(grammar) = language.grammar.as_deref() {
 319                grammar
 320            } else {
 321                continue;
 322            };
 323
 324            let tree;
 325            let changed_ranges;
 326            if let Some(old_layer) = old_layer {
 327                tree = parse_text(
 328                    grammar,
 329                    text.as_rope(),
 330                    Some(old_layer.tree.clone()),
 331                    ranges,
 332                );
 333                changed_ranges = join_ranges(
 334                    edits
 335                        .iter()
 336                        .map(|e| e.new.clone())
 337                        .filter(|range| range.start < end_byte && range.end > start_byte),
 338                    old_layer
 339                        .tree
 340                        .changed_ranges(&tree)
 341                        .map(|r| start_byte + r.start_byte..start_byte + r.end_byte),
 342                );
 343            } else {
 344                tree = parse_text(grammar, text.as_rope(), None, ranges);
 345                changed_ranges = vec![start_byte..end_byte];
 346            }
 347
 348            layers.push(
 349                SyntaxLayer {
 350                    depth,
 351                    range,
 352                    tree: tree.clone(),
 353                    language: language.clone(),
 354                },
 355                &text,
 356            );
 357
 358            if let (Some((config, registry)), false) = (
 359                grammar.injection_config.as_ref().zip(registry.as_ref()),
 360                changed_ranges.is_empty(),
 361            ) {
 362                let depth = depth + 1;
 363                for range in &changed_ranges {
 364                    changed_regions.insert(
 365                        ChangedRegion {
 366                            depth,
 367                            range: text.anchor_before(range.start)..text.anchor_after(range.end),
 368                        },
 369                        text,
 370                    );
 371                }
 372                get_injections(
 373                    config,
 374                    text,
 375                    tree.root_node_with_offset(start_byte, start_point),
 376                    registry,
 377                    depth,
 378                    &changed_ranges,
 379                    &mut queue,
 380                );
 381            }
 382        }
 383
 384        drop(cursor);
 385        self.layers = layers;
 386    }
 387
 388    pub fn layers(&self, buffer: &BufferSnapshot) -> Vec<(&Grammar, Node)> {
 389        self.layers
 390            .iter()
 391            .filter_map(|layer| {
 392                if let Some(grammar) = &layer.language.grammar {
 393                    Some((
 394                        grammar.as_ref(),
 395                        layer.tree.root_node_with_offset(
 396                            layer.range.start.to_offset(buffer),
 397                            layer.range.start.to_point(buffer).to_ts_point(),
 398                        ),
 399                    ))
 400                } else {
 401                    None
 402                }
 403            })
 404            .collect()
 405    }
 406
 407    pub fn layers_for_range<'a, T: ToOffset>(
 408        &self,
 409        range: Range<T>,
 410        buffer: &BufferSnapshot,
 411    ) -> Vec<(&Grammar, Node)> {
 412        let start = buffer.anchor_before(range.start.to_offset(buffer));
 413        let end = buffer.anchor_after(range.end.to_offset(buffer));
 414
 415        let mut cursor = self.layers.filter::<_, ()>(|summary| {
 416            let is_before_start = summary.range.end.cmp(&start, buffer).is_lt();
 417            let is_after_end = summary.range.start.cmp(&end, buffer).is_gt();
 418            !is_before_start && !is_after_end
 419        });
 420
 421        let mut result = Vec::new();
 422        cursor.next(buffer);
 423        while let Some(layer) = cursor.item() {
 424            if let Some(grammar) = &layer.language.grammar {
 425                result.push((
 426                    grammar.as_ref(),
 427                    layer.tree.root_node_with_offset(
 428                        layer.range.start.to_offset(buffer),
 429                        layer.range.start.to_point(buffer).to_ts_point(),
 430                    ),
 431                ));
 432            }
 433            cursor.next(buffer)
 434        }
 435
 436        result
 437    }
 438}
 439
 440fn join_ranges(
 441    a: impl Iterator<Item = Range<usize>>,
 442    b: impl Iterator<Item = Range<usize>>,
 443) -> Vec<Range<usize>> {
 444    let mut result = Vec::<Range<usize>>::new();
 445    let mut a = a.peekable();
 446    let mut b = b.peekable();
 447    loop {
 448        let range = match (a.peek(), b.peek()) {
 449            (Some(range_a), Some(range_b)) => {
 450                if range_a.start < range_b.start {
 451                    a.next().unwrap()
 452                } else {
 453                    b.next().unwrap()
 454                }
 455            }
 456            (None, Some(_)) => b.next().unwrap(),
 457            (Some(_), None) => a.next().unwrap(),
 458            (None, None) => break,
 459        };
 460
 461        if let Some(last) = result.last_mut() {
 462            if range.start <= last.end {
 463                last.end = last.end.max(range.end);
 464                continue;
 465            }
 466        }
 467        result.push(range);
 468    }
 469    result
 470}
 471
 472fn parse_text(
 473    grammar: &Grammar,
 474    text: &Rope,
 475    old_tree: Option<Tree>,
 476    mut ranges: Vec<tree_sitter::Range>,
 477) -> Tree {
 478    let (start_byte, start_point) = ranges
 479        .first()
 480        .map(|range| (range.start_byte, Point::from_ts_point(range.start_point)))
 481        .unwrap_or_default();
 482
 483    for range in &mut ranges {
 484        range.start_byte -= start_byte;
 485        range.end_byte -= start_byte;
 486        range.start_point = (Point::from_ts_point(range.start_point) - start_point).to_ts_point();
 487        range.end_point = (Point::from_ts_point(range.end_point) - start_point).to_ts_point();
 488    }
 489
 490    PARSER.with(|parser| {
 491        let mut parser = parser.borrow_mut();
 492        let mut chunks = text.chunks_in_range(start_byte..text.len());
 493        parser
 494            .set_included_ranges(&ranges)
 495            .expect("overlapping ranges");
 496        parser
 497            .set_language(grammar.ts_language)
 498            .expect("incompatible grammar");
 499        parser
 500            .parse_with(
 501                &mut move |offset, _| {
 502                    chunks.seek(start_byte + offset);
 503                    chunks.next().unwrap_or("").as_bytes()
 504                },
 505                old_tree.as_ref(),
 506            )
 507            .expect("invalid language")
 508    })
 509}
 510
 511fn get_injections(
 512    config: &InjectionConfig,
 513    text: &BufferSnapshot,
 514    node: Node,
 515    language_registry: &LanguageRegistry,
 516    depth: usize,
 517    query_ranges: &[Range<usize>],
 518    queue: &mut BinaryHeap<ReparseStep>,
 519) -> bool {
 520    let mut result = false;
 521    let mut query_cursor = QueryCursorHandle::new();
 522    let mut prev_match = None;
 523    for query_range in query_ranges {
 524        query_cursor.set_byte_range(query_range.start..query_range.end);
 525        for mat in query_cursor.matches(&config.query, node, TextProvider(text.as_rope())) {
 526            let content_ranges = mat
 527                .nodes_for_capture_index(config.content_capture_ix)
 528                .map(|node| node.range())
 529                .collect::<Vec<_>>();
 530            if content_ranges.is_empty() {
 531                continue;
 532            }
 533
 534            // Avoid duplicate matches if two changed ranges intersect the same injection.
 535            let content_range =
 536                content_ranges.first().unwrap().start_byte..content_ranges.last().unwrap().end_byte;
 537            if let Some((last_pattern_ix, last_range)) = &prev_match {
 538                if mat.pattern_index == *last_pattern_ix && content_range == *last_range {
 539                    continue;
 540                }
 541            }
 542            prev_match = Some((mat.pattern_index, content_range.clone()));
 543
 544            let language_name = config.languages_by_pattern_ix[mat.pattern_index]
 545                .as_ref()
 546                .map(|s| Cow::Borrowed(s.as_ref()))
 547                .or_else(|| {
 548                    let ix = config.language_capture_ix?;
 549                    let node = mat.nodes_for_capture_index(ix).next()?;
 550                    Some(Cow::Owned(text.text_for_range(node.byte_range()).collect()))
 551                });
 552
 553            if let Some(language_name) = language_name {
 554                if let Some(language) = language_registry.get_language(language_name.as_ref()) {
 555                    result = true;
 556                    let range = text.anchor_before(content_range.start)
 557                        ..text.anchor_after(content_range.end);
 558                    queue.push(ReparseStep {
 559                        depth,
 560                        language,
 561                        ranges: content_ranges,
 562                        range,
 563                    })
 564                }
 565            }
 566        }
 567    }
 568    result
 569}
 570
 571impl std::ops::Deref for SyntaxMap {
 572    type Target = SyntaxSnapshot;
 573
 574    fn deref(&self) -> &Self::Target {
 575        &self.snapshot
 576    }
 577}
 578
 579impl PartialEq for ReparseStep {
 580    fn eq(&self, _: &Self) -> bool {
 581        false
 582    }
 583}
 584
 585impl Eq for ReparseStep {}
 586
 587impl PartialOrd for ReparseStep {
 588    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
 589        Some(self.cmp(&other))
 590    }
 591}
 592
 593impl Ord for ReparseStep {
 594    fn cmp(&self, other: &Self) -> Ordering {
 595        let range_a = self.range();
 596        let range_b = other.range();
 597        Ord::cmp(&other.depth, &self.depth)
 598            .then_with(|| Ord::cmp(&range_b.start, &range_a.start))
 599            .then_with(|| Ord::cmp(&range_a.end, &range_b.end))
 600    }
 601}
 602
 603impl ReparseStep {
 604    fn range(&self) -> Range<usize> {
 605        let start = self.ranges.first().map_or(0, |r| r.start_byte);
 606        let end = self.ranges.last().map_or(0, |r| r.end_byte);
 607        start..end
 608    }
 609}
 610
 611impl ChangedRegion {
 612    fn cmp(&self, other: &Self, buffer: &BufferSnapshot) -> Ordering {
 613        let range_a = &self.range;
 614        let range_b = &other.range;
 615        Ord::cmp(&self.depth, &other.depth)
 616            .then_with(|| range_a.start.cmp(&range_b.start, buffer))
 617            .then_with(|| range_b.end.cmp(&range_a.end, buffer))
 618    }
 619}
 620
 621impl ChangeRegionSet {
 622    fn start_position(&self) -> DepthAndMaxPosition {
 623        self.0
 624            .first()
 625            .map_or(DepthAndMaxPosition(usize::MAX, Anchor::MAX), |region| {
 626                DepthAndMaxPosition(region.depth, region.range.start)
 627            })
 628    }
 629
 630    fn intersects(&self, layer: &SyntaxLayer, text: &BufferSnapshot) -> bool {
 631        for region in &self.0 {
 632            if region.depth < layer.depth {
 633                continue;
 634            }
 635            if region.depth > layer.depth {
 636                break;
 637            }
 638            if region.range.end.cmp(&layer.range.start, text).is_le() {
 639                continue;
 640            }
 641            if region.range.start.cmp(&layer.range.end, text).is_ge() {
 642                break;
 643            }
 644            return true;
 645        }
 646        false
 647    }
 648
 649    fn insert(&mut self, region: ChangedRegion, text: &BufferSnapshot) {
 650        if let Err(ix) = self.0.binary_search_by(|probe| probe.cmp(&region, text)) {
 651            self.0.insert(ix, region);
 652        }
 653    }
 654
 655    fn prune(&mut self, summary: SyntaxLayerSummary, text: &BufferSnapshot) -> bool {
 656        let prev_len = self.0.len();
 657        self.0.retain(|region| {
 658            region.depth > summary.max_depth
 659                || (region.depth == summary.max_depth
 660                    && region
 661                        .range
 662                        .end
 663                        .cmp(&summary.last_layer_range.start, text)
 664                        .is_gt())
 665        });
 666        self.0.len() < prev_len
 667    }
 668}
 669
 670impl Default for SyntaxLayerSummary {
 671    fn default() -> Self {
 672        Self {
 673            max_depth: 0,
 674            range: Anchor::MAX..Anchor::MIN,
 675            last_layer_range: Anchor::MIN..Anchor::MAX,
 676        }
 677    }
 678}
 679
 680impl sum_tree::Summary for SyntaxLayerSummary {
 681    type Context = BufferSnapshot;
 682
 683    fn add_summary(&mut self, other: &Self, buffer: &Self::Context) {
 684        if other.max_depth > self.max_depth {
 685            *self = other.clone();
 686        } else {
 687            if other.range.start.cmp(&self.range.start, buffer).is_lt() {
 688                self.range.start = other.range.start;
 689            }
 690            if other.range.end.cmp(&self.range.end, buffer).is_gt() {
 691                self.range.end = other.range.end;
 692            }
 693            self.last_layer_range = other.last_layer_range.clone();
 694        }
 695    }
 696}
 697
 698impl<'a> SeekTarget<'a, SyntaxLayerSummary, SyntaxLayerSummary> for DepthAndRange {
 699    fn cmp(&self, cursor_location: &SyntaxLayerSummary, buffer: &BufferSnapshot) -> Ordering {
 700        Ord::cmp(&self.0, &cursor_location.max_depth)
 701            .then_with(|| {
 702                self.1
 703                    .start
 704                    .cmp(&cursor_location.last_layer_range.start, buffer)
 705            })
 706            .then_with(|| {
 707                cursor_location
 708                    .last_layer_range
 709                    .end
 710                    .cmp(&self.1.end, buffer)
 711            })
 712    }
 713}
 714
 715impl<'a> SeekTarget<'a, SyntaxLayerSummary, SyntaxLayerSummary> for DepthAndMaxPosition {
 716    fn cmp(&self, cursor_location: &SyntaxLayerSummary, text: &BufferSnapshot) -> Ordering {
 717        Ord::cmp(&self.0, &cursor_location.max_depth)
 718            .then_with(|| self.1.cmp(&cursor_location.range.end, text))
 719    }
 720}
 721
 722impl<'a> SeekTarget<'a, SyntaxLayerSummary, SyntaxLayerSummary> for DepthAndRangeOrMaxPosition {
 723    fn cmp(&self, cursor_location: &SyntaxLayerSummary, buffer: &BufferSnapshot) -> Ordering {
 724        if self.1.cmp(cursor_location, buffer).is_le() {
 725            return Ordering::Less;
 726        } else {
 727            self.0.cmp(cursor_location, buffer)
 728        }
 729    }
 730}
 731
 732impl sum_tree::Item for SyntaxLayer {
 733    type Summary = SyntaxLayerSummary;
 734
 735    fn summary(&self) -> Self::Summary {
 736        SyntaxLayerSummary {
 737            max_depth: self.depth,
 738            range: self.range.clone(),
 739            last_layer_range: self.range.clone(),
 740        }
 741    }
 742}
 743
 744impl std::fmt::Debug for SyntaxLayer {
 745    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 746        f.debug_struct("SyntaxLayer")
 747            .field("depth", &self.depth)
 748            .field("range", &self.range)
 749            .field("tree", &self.tree)
 750            .finish()
 751    }
 752}
 753
 754#[cfg(test)]
 755mod tests {
 756    use super::*;
 757    use crate::LanguageConfig;
 758    use text::{Buffer, Point};
 759    use tree_sitter::Query;
 760    use unindent::Unindent as _;
 761    use util::test::marked_text_ranges;
 762
 763    #[gpui::test]
 764    fn test_syntax_map_layers_for_range() {
 765        let registry = Arc::new(LanguageRegistry::test());
 766        let language = Arc::new(rust_lang());
 767        registry.add(language.clone());
 768
 769        let mut buffer = Buffer::new(
 770            0,
 771            0,
 772            r#"
 773                fn a() {
 774                    assert_eq!(
 775                        b(vec![C {}]),
 776                        vec![d.e],
 777                    );
 778                    println!("{}", f(|_| true));
 779                }
 780            "#
 781            .unindent(),
 782        );
 783
 784        let mut syntax_map = SyntaxMap::new();
 785        syntax_map.set_language_registry(registry.clone());
 786        syntax_map.reparse(language.clone(), &buffer);
 787
 788        assert_layers_for_range(
 789            &syntax_map,
 790            &buffer,
 791            Point::new(2, 0)..Point::new(2, 0),
 792            &[
 793                "...(function_item ... (block (expression_statement (macro_invocation...",
 794                "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...",
 795            ],
 796        );
 797        assert_layers_for_range(
 798            &syntax_map,
 799            &buffer,
 800            Point::new(2, 14)..Point::new(2, 16),
 801            &[
 802                "...(function_item ...",
 803                "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...",
 804                "...(array_expression (struct_expression ...",
 805            ],
 806        );
 807        assert_layers_for_range(
 808            &syntax_map,
 809            &buffer,
 810            Point::new(3, 14)..Point::new(3, 16),
 811            &[
 812                "...(function_item ...",
 813                "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...",
 814                "...(array_expression (field_expression ...",
 815            ],
 816        );
 817        assert_layers_for_range(
 818            &syntax_map,
 819            &buffer,
 820            Point::new(5, 12)..Point::new(5, 16),
 821            &[
 822                "...(function_item ...",
 823                "...(call_expression ... (arguments (closure_expression ...",
 824            ],
 825        );
 826
 827        // Replace a vec! macro invocation with a plain slice, removing a syntactic layer.
 828        let macro_name_range = range_for_text(&buffer, "vec!");
 829        buffer.edit([(macro_name_range, "&")]);
 830        syntax_map.interpolate(&buffer);
 831        syntax_map.reparse(language.clone(), &buffer);
 832
 833        assert_layers_for_range(
 834            &syntax_map,
 835            &buffer,
 836            Point::new(2, 14)..Point::new(2, 16),
 837            &[
 838                "...(function_item ...",
 839                "...(tuple_expression (call_expression ... arguments: (arguments (reference_expression value: (array_expression...",
 840            ],
 841        );
 842
 843        // Put the vec! macro back, adding back the syntactic layer.
 844        buffer.undo();
 845        syntax_map.interpolate(&buffer);
 846        syntax_map.reparse(language.clone(), &buffer);
 847
 848        assert_layers_for_range(
 849            &syntax_map,
 850            &buffer,
 851            Point::new(2, 14)..Point::new(2, 16),
 852            &[
 853                "...(function_item ...",
 854                "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...",
 855                "...(array_expression (struct_expression ...",
 856            ],
 857        );
 858    }
 859
 860    #[gpui::test]
 861    fn test_typing_multiple_new_injections() {
 862        let (buffer, syntax_map) = test_edit_sequence(&[
 863            "fn a() { dbg }",
 864            "fn a() { dbg«!» }",
 865            "fn a() { dbg!«()» }",
 866            "fn a() { dbg!(«b») }",
 867            "fn a() { dbg!(b«.») }",
 868            "fn a() { dbg!(b.«c») }",
 869            "fn a() { dbg!(b.c«()») }",
 870            "fn a() { dbg!(b.c(«vec»)) }",
 871            "fn a() { dbg!(b.c(vec«!»)) }",
 872            "fn a() { dbg!(b.c(vec!«[]»)) }",
 873            "fn a() { dbg!(b.c(vec![«d»])) }",
 874            "fn a() { dbg!(b.c(vec![d«.»])) }",
 875            "fn a() { dbg!(b.c(vec![d.«e»])) }",
 876        ]);
 877
 878        assert_node_ranges(
 879            &syntax_map,
 880            &buffer,
 881            "(field_identifier) @_",
 882            "fn a() { dbg!(b.«c»(vec![d.«e»])) }",
 883        );
 884    }
 885
 886    #[gpui::test]
 887    fn test_pasting_new_injection_line_between_others() {
 888        let (buffer, syntax_map) = test_edit_sequence(&[
 889            "
 890                fn a() {
 891                    b!(B {});
 892                    c!(C {});
 893                    d!(D {});
 894                    e!(E {});
 895                    f!(F {});
 896                    g!(G {});
 897                }
 898            ",
 899            "
 900                fn a() {
 901                    b!(B {});
 902                    c!(C {});
 903                    d!(D {});
 904                «    h!(H {});
 905                »    e!(E {});
 906                    f!(F {});
 907                    g!(G {});
 908                }
 909            ",
 910        ]);
 911
 912        assert_node_ranges(
 913            &syntax_map,
 914            &buffer,
 915            "(struct_expression) @_",
 916            "
 917            fn a() {
 918                b!(«B {}»);
 919                c!(«C {}»);
 920                d!(«D {}»);
 921                h!(«H {}»);
 922                e!(«E {}»);
 923                f!(«F {}»);
 924                g!(«G {}»);
 925            }
 926            ",
 927        );
 928    }
 929
 930    #[gpui::test]
 931    fn test_joining_injections_with_child_injections() {
 932        let (buffer, syntax_map) = test_edit_sequence(&[
 933            "
 934                fn a() {
 935                    b!(
 936                        c![one.two.three],
 937                        d![four.five.six],
 938                    );
 939                    e!(
 940                        f![seven.eight],
 941                    );
 942                }
 943            ",
 944            "
 945                fn a() {
 946                    b!(
 947                        c![one.two.three],
 948                        d![four.five.six],
 949                    ˇ    f![seven.eight],
 950                    );
 951                }
 952            ",
 953        ]);
 954
 955        assert_node_ranges(
 956            &syntax_map,
 957            &buffer,
 958            "(field_identifier) @_",
 959            "
 960            fn a() {
 961                b!(
 962                    c![one.«two».«three»],
 963                    d![four.«five».«six»],
 964                    f![seven.«eight»],
 965                );
 966            }
 967            ",
 968        );
 969    }
 970
 971    #[gpui::test]
 972    fn test_editing_edges_of_injection() {
 973        test_edit_sequence(&[
 974            "
 975                fn a() {
 976                    b!(c!())
 977                }
 978            ",
 979            "
 980                fn a() {
 981                    «d»!(c!())
 982                }
 983            ",
 984            "
 985                fn a() {
 986                    «e»d!(c!())
 987                }
 988            ",
 989            "
 990                fn a() {
 991                    ed!«[»c!()«]»
 992                }
 993            ",
 994        ]);
 995    }
 996
 997    #[gpui::test]
 998    fn test_edits_preceding_and_intersecting_injection() {
 999        test_edit_sequence(&[
1000            //
1001            "const aaaaaaaaaaaa: B = c!(d(e.f));",
1002            "const aˇa: B = c!(d(eˇ));",
1003        ]);
1004    }
1005
1006    #[gpui::test]
1007    fn test_non_local_changes_create_injections() {
1008        test_edit_sequence(&[
1009            "
1010                // a! {
1011                    static B: C = d;
1012                // }
1013            ",
1014            "
1015                ˇa! {
1016                    static B: C = d;
1017                ˇ}
1018            ",
1019        ]);
1020    }
1021
1022    #[gpui::test]
1023    fn test_creating_many_injections_in_one_edit() {
1024        test_edit_sequence(&[
1025            "
1026                fn a() {
1027                    one(Two::three(3));
1028                    four(Five::six(6));
1029                    seven(Eight::nine(9));
1030                }
1031            ",
1032            "
1033                fn a() {
1034                    one«!»(Two::three(3));
1035                    four«!»(Five::six(6));
1036                    seven«!»(Eight::nine(9));
1037                }
1038            ",
1039            "
1040                fn a() {
1041                    one!(Two::three«!»(3));
1042                    four!(Five::six«!»(6));
1043                    seven!(Eight::nine«!»(9));
1044                }
1045            ",
1046        ]);
1047    }
1048
1049    #[gpui::test]
1050    fn test_editing_across_injection_boundary() {
1051        test_edit_sequence(&[
1052            "
1053                fn one() {
1054                    two();
1055                    three!(
1056                        three.four,
1057                        five.six,
1058                    );
1059                }
1060            ",
1061            "
1062                fn one() {
1063                    two();
1064                    th«irty_five![»
1065                        three.four,
1066                        five.six,
1067                    «   seven.eight,
1068                    ];»
1069                }
1070            ",
1071        ]);
1072    }
1073
1074    fn test_edit_sequence(steps: &[&str]) -> (Buffer, SyntaxMap) {
1075        let registry = Arc::new(LanguageRegistry::test());
1076        let language = Arc::new(rust_lang());
1077        registry.add(language.clone());
1078        let mut buffer = Buffer::new(0, 0, Default::default());
1079
1080        let mut mutated_syntax_map = SyntaxMap::new();
1081        mutated_syntax_map.set_language_registry(registry.clone());
1082        mutated_syntax_map.reparse(language.clone(), &buffer);
1083
1084        for (i, marked_string) in steps.into_iter().enumerate() {
1085            edit_buffer(&mut buffer, &marked_string.unindent());
1086
1087            // Reparse the syntax map
1088            mutated_syntax_map.interpolate(&buffer);
1089            mutated_syntax_map.reparse(language.clone(), &buffer);
1090
1091            // Create a second syntax map from scratch
1092            let mut reference_syntax_map = SyntaxMap::new();
1093            reference_syntax_map.set_language_registry(registry.clone());
1094            reference_syntax_map.reparse(language.clone(), &buffer);
1095
1096            // Compare the mutated syntax map to the new syntax map
1097            let mutated_layers = mutated_syntax_map.layers(&buffer);
1098            let reference_layers = reference_syntax_map.layers(&buffer);
1099            assert_eq!(
1100                mutated_layers.len(),
1101                reference_layers.len(),
1102                "wrong number of layers at step {i}"
1103            );
1104            for (edited_layer, reference_layer) in
1105                mutated_layers.into_iter().zip(reference_layers.into_iter())
1106            {
1107                assert_eq!(
1108                    edited_layer.1.to_sexp(),
1109                    reference_layer.1.to_sexp(),
1110                    "different layer at step {i}"
1111                );
1112                assert_eq!(
1113                    edited_layer.1.range(),
1114                    reference_layer.1.range(),
1115                    "different layer at step {i}"
1116                );
1117            }
1118        }
1119
1120        (buffer, mutated_syntax_map)
1121    }
1122
1123    fn rust_lang() -> Language {
1124        Language::new(
1125            LanguageConfig {
1126                name: "Rust".into(),
1127                path_suffixes: vec!["rs".to_string()],
1128                ..Default::default()
1129            },
1130            Some(tree_sitter_rust::language()),
1131        )
1132        .with_injection_query(
1133            r#"
1134                (macro_invocation
1135                    (token_tree) @content
1136                    (#set! "language" "rust"))
1137            "#,
1138        )
1139        .unwrap()
1140    }
1141
1142    fn range_for_text(buffer: &Buffer, text: &str) -> Range<usize> {
1143        let start = buffer.as_rope().to_string().find(text).unwrap();
1144        start..start + text.len()
1145    }
1146
1147    fn assert_layers_for_range(
1148        syntax_map: &SyntaxMap,
1149        buffer: &BufferSnapshot,
1150        range: Range<Point>,
1151        expected_layers: &[&str],
1152    ) {
1153        let layers = syntax_map.layers_for_range(range, &buffer);
1154        assert_eq!(
1155            layers.len(),
1156            expected_layers.len(),
1157            "wrong number of layers"
1158        );
1159        for (i, ((_, node), expected_s_exp)) in
1160            layers.iter().zip(expected_layers.iter()).enumerate()
1161        {
1162            let actual_s_exp = node.to_sexp();
1163            assert!(
1164                string_contains_sequence(
1165                    &actual_s_exp,
1166                    &expected_s_exp.split("...").collect::<Vec<_>>()
1167                ),
1168                "layer {i}:\n\nexpected: {expected_s_exp}\nactual:   {actual_s_exp}",
1169            );
1170        }
1171    }
1172
1173    fn assert_node_ranges(
1174        syntax_map: &SyntaxMap,
1175        buffer: &BufferSnapshot,
1176        query: &str,
1177        marked_string: &str,
1178    ) {
1179        let mut cursor = QueryCursorHandle::new();
1180        let mut actual_ranges = Vec::<Range<usize>>::new();
1181        for (grammar, node) in syntax_map.layers(buffer) {
1182            let query = Query::new(grammar.ts_language, query).unwrap();
1183            for (mat, ix) in cursor.captures(&query, node, TextProvider(buffer.as_rope())) {
1184                actual_ranges.push(mat.captures[ix].node.byte_range());
1185            }
1186        }
1187
1188        let (text, expected_ranges) = marked_text_ranges(&marked_string.unindent(), false);
1189        assert_eq!(text, buffer.text());
1190        assert_eq!(actual_ranges, expected_ranges);
1191    }
1192
1193    fn edit_buffer(buffer: &mut Buffer, marked_string: &str) {
1194        let old_text = buffer.text();
1195        let (new_text, mut ranges) = marked_text_ranges(marked_string, false);
1196        if ranges.is_empty() {
1197            ranges.push(0..new_text.len());
1198        }
1199
1200        assert_eq!(
1201            old_text[..ranges[0].start],
1202            new_text[..ranges[0].start],
1203            "invalid edit"
1204        );
1205
1206        let mut delta = 0;
1207        let mut edits = Vec::new();
1208        let mut ranges = ranges.into_iter().peekable();
1209
1210        while let Some(inserted_range) = ranges.next() {
1211            let new_start = inserted_range.start;
1212            let old_start = (new_start as isize - delta) as usize;
1213
1214            let following_text = if let Some(next_range) = ranges.peek() {
1215                &new_text[inserted_range.end..next_range.start]
1216            } else {
1217                &new_text[inserted_range.end..]
1218            };
1219
1220            let inserted_len = inserted_range.len();
1221            let deleted_len = old_text[old_start..]
1222                .find(following_text)
1223                .expect("invalid edit");
1224
1225            let old_range = old_start..old_start + deleted_len;
1226            edits.push((old_range, new_text[inserted_range].to_string()));
1227            delta += inserted_len as isize - deleted_len as isize;
1228        }
1229
1230        assert_eq!(
1231            old_text.len() as isize + delta,
1232            new_text.len() as isize,
1233            "invalid edit"
1234        );
1235
1236        buffer.edit(edits);
1237    }
1238
1239    pub fn string_contains_sequence(text: &str, parts: &[&str]) -> bool {
1240        let mut last_part_end = 0;
1241        for part in parts {
1242            if let Some(start_ix) = text[last_part_end..].find(part) {
1243                last_part_end = start_ix + part.len();
1244            } else {
1245                return false;
1246            }
1247        }
1248        true
1249    }
1250}