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