Skip to main content

m2_syn/migration/
treesitter.rs

1//! Tree-sitter parser adapter.
2//!
3//! Tree-sitter nodes remain backend-local. Complete-file parsing lowers the
4//! grammar's concrete nodes directly into the generated typed graph; it never
5//! reparses their source through the native precedence engine.
6//! [`TreeSitterNode`] is also the generic [`ExternalCstNode`] adapter used for
7//! migrating leaves, operators, and tokens with the generated machinery.
8
9use std::borrow::Cow;
10use std::error::Error;
11use std::fmt::{Display, Formatter};
12use std::ops::Range;
13use std::sync::Arc;
14use std::vec::IntoIter;
15
16use crate::native::{LambdaArguments, assignment_list, installation_value, lambda_arguments};
17use crate::nodes::*;
18use crate::{
19    CSTNodeClassLabel, CellStream, CellStreamError, DelimiterKind, DelimiterToken, DoubleSpan,
20    ExternalCstChild, ExternalCstNode, LexError, Migrate, MigrateError, Parser, Punctuated,
21    Recovered, Source, SourceFile, Span, Spanned, TextEdit, TokenStream, TokenTree, Tokenize,
22    lex_str, lex_str_recovering,
23};
24
25#[derive(Debug)]
26/// A failure while parsing or migrating a Tree-sitter syntax tree.
27pub enum ParseError {
28    /// The renaming hook could not inspect the source token stream.
29    Lex(LexError),
30    /// The raw token stream could not be partitioned into complete cells.
31    Tokenize(CellStreamError),
32    /// The bundled grammar could not be installed in the parser.
33    Language(tree_sitter::LanguageError),
34    /// Tree-sitter returned no tree.
35    Cancelled,
36    /// A requested source edit did not lie on valid boundaries of the buffer.
37    InvalidEdit,
38    /// Tree-sitter produced an error or missing node at this span.
39    InvalidSyntax(Span),
40    /// The untyped Tree-sitter node could not migrate typed syntax.
41    Migrate(MigrateError),
42    /// A valid concrete node has no representation in the typed schema.
43    UnsupportedNode {
44        /// The Tree-sitter node kind that could not be lowered.
45        kind: String,
46        /// The complete node range.
47        span: Span,
48    },
49}
50
51impl Display for ParseError {
52    fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
53        match self {
54            Self::Lex(error) => error.fmt(formatter),
55            Self::Tokenize(error) => error.fmt(formatter),
56            Self::Language(error) => error.fmt(formatter),
57            Self::Cancelled => formatter.write_str("Tree-sitter parsing was cancelled"),
58            Self::InvalidEdit => formatter.write_str("source edit is outside the current buffer"),
59            Self::InvalidSyntax(span) if span.line_column_range().is_some() => {
60                write!(formatter, "invalid Macaulay2 syntax at {span}")
61            }
62            Self::InvalidSyntax(_) => formatter.write_str("invalid Macaulay2 syntax"),
63            Self::Migrate(error) => error.fmt(formatter),
64            Self::UnsupportedNode { kind, .. } => {
65                write!(
66                    formatter,
67                    "Tree-sitter node `{kind}` has no typed representation"
68                )
69            }
70        }
71    }
72}
73
74impl Error for ParseError {
75    fn source(&self) -> Option<&(dyn Error + 'static)> {
76        match self {
77            Self::Lex(error) => Some(error),
78            Self::Tokenize(error) => Some(error),
79            Self::Language(error) => Some(error),
80            Self::Migrate(error) => Some(error),
81            Self::Cancelled
82            | Self::InvalidEdit
83            | Self::InvalidSyntax(_)
84            | Self::UnsupportedNode { .. } => None,
85        }
86    }
87}
88
89impl From<MigrateError> for ParseError {
90    fn from(error: MigrateError) -> Self {
91        Self::Migrate(error)
92    }
93}
94
95impl From<LexError> for ParseError {
96    fn from(error: LexError) -> Self {
97        Self::Lex(error)
98    }
99}
100
101impl From<CellStreamError> for ParseError {
102    fn from(error: CellStreamError) -> Self {
103        Self::Tokenize(error)
104    }
105}
106
107/// A reusable Tree-sitter parser and direct typed-CST lowerer.
108pub struct TreeSitterParser {
109    /// The parser.
110    parser: tree_sitter::Parser,
111}
112
113/// An incrementally updated Tree-sitter parse for editor-style source changes.
114///
115/// The parser retains its previous Tree-sitter tree, applies each [`TextEdit`]
116/// to that tree, and supplies it to the next parse. Typed syntax is lowered
117/// afresh from the incrementally produced tree, so every public node and span
118/// describes the current source snapshot. Missing group closers are recoverable
119/// and remain available through [`Self::diagnostics`].
120pub struct RealtimeParser {
121    /// The parser.
122    parser: tree_sitter::Parser,
123    /// The source.
124    source: Arc<Source>,
125    /// The parse view.
126    parse_view: String,
127    /// The tree.
128    tree: tree_sitter::Tree,
129    /// The syntax.
130    syntax: SourceFile,
131    /// The diagnostics.
132    diagnostics: Vec<LexError>,
133    /// The changed ranges.
134    changed_ranges: Vec<Span>,
135}
136
137impl RealtimeParser {
138    /// Creates a retained parse of the initial source snapshot.
139    ///
140    /// # Errors
141    ///
142    /// Returns [`ParseError`] when the grammar cannot parse and lower the
143    /// source, apart from recoverable missing group closers.
144    pub fn new(source: impl Into<String>) -> Result<Self, ParseError> {
145        let source = Source::new(source.into());
146        let mut parser = TreeSitterParser::new()?.parser;
147        let ParsedTree {
148            parse_view,
149            tree,
150            syntax,
151            diagnostics,
152        } = parse_recovered_tree(&mut parser, Arc::clone(&source), None)?;
153        Ok(Self {
154            parser,
155            source,
156            parse_view,
157            tree,
158            syntax,
159            diagnostics,
160            changed_ranges: Vec::new(),
161        })
162    }
163
164    /// Applies one source edit and incrementally refreshes the typed syntax.
165    ///
166    /// The update is transactional: a failed edit or parse leaves the previous
167    /// source, tree, syntax, and diagnostics unchanged.
168    ///
169    /// # Errors
170    ///
171    /// Returns [`ParseError::InvalidEdit`] when the edit is outside the current
172    /// UTF-8 buffer, or another [`ParseError`] when the edited source cannot be
173    /// recovered and lowered.
174    pub fn apply_edit(&mut self, edit: &TextEdit) -> Result<(), ParseError> {
175        let source_text = edit
176            .apply(self.source.text())
177            .ok_or(ParseError::InvalidEdit)?;
178        let source = Source::with_file(self.source.file(), source_text);
179        let (view, aliases, diagnostics) = renamed_source_recovering(source.text())?;
180        let parse_view = view.into_owned();
181
182        let mut edited_tree = self.tree.clone();
183        edited_tree.edit(&input_edit_between(&self.parse_view, &parse_view));
184        let tree = self
185            .parser
186            .parse(parse_view.as_bytes(), Some(&edited_tree))
187            .ok_or(ParseError::Cancelled)?;
188        if let Some(error) = first_error(tree.root_node()) {
189            return Err(ParseError::InvalidSyntax(Span::ranged(
190                Arc::clone(&source),
191                error.start_byte().min(source.text().len())
192                    ..error.end_byte().min(source.text().len()),
193            )));
194        }
195        let syntax = Lowerer::new(Arc::clone(&source), source.text(), aliases)
196            .source_file(tree.root_node())?;
197        let changed_ranges = edited_tree
198            .changed_ranges(&tree)
199            .map(|range| {
200                Span::ranged(
201                    Arc::clone(&source),
202                    range.start_byte.min(source.text().len())
203                        ..range.end_byte.min(source.text().len()),
204                )
205            })
206            .collect();
207
208        self.source = source;
209        self.parse_view = parse_view;
210        self.tree = tree;
211        self.syntax = syntax;
212        self.diagnostics = diagnostics;
213        self.changed_ranges = changed_ranges;
214        Ok(())
215    }
216
217    /// Returns the current source snapshot.
218    pub fn source(&self) -> &str {
219        self.source.text()
220    }
221
222    /// Returns the typed syntax for the current snapshot.
223    pub fn syntax(&self) -> &SourceFile {
224        &self.syntax
225    }
226
227    /// Returns the recoverable diagnostics for the current snapshot.
228    pub fn diagnostics(&self) -> &[LexError] {
229        &self.diagnostics
230    }
231
232    /// Returns structural ranges changed by the most recent incremental parse.
233    pub fn changed_ranges(&self) -> &[Span] {
234        &self.changed_ranges
235    }
236
237    /// Consumes the retained parser and returns its current typed syntax.
238    pub fn into_syntax(self) -> SourceFile {
239        self.syntax
240    }
241}
242
243/// Internal state for ParsedTree.
244struct ParsedTree {
245    /// The parse view.
246    parse_view: String,
247    /// The tree.
248    tree: tree_sitter::Tree,
249    /// The syntax.
250    syntax: SourceFile,
251    /// The diagnostics.
252    diagnostics: Vec<LexError>,
253}
254
255/// Parses recovered tree.
256fn parse_recovered_tree(
257    parser: &mut tree_sitter::Parser,
258    source: Arc<Source>,
259    old_tree: Option<&tree_sitter::Tree>,
260) -> Result<ParsedTree, ParseError> {
261    let source_text = source.text();
262    let (view, aliases, diagnostics) = renamed_source_recovering(source_text)?;
263    let parse_view = view.into_owned();
264    let tree = parser
265        .parse(parse_view.as_bytes(), old_tree)
266        .ok_or(ParseError::Cancelled)?;
267    if let Some(error) = first_error(tree.root_node()) {
268        return Err(ParseError::InvalidSyntax(Span::ranged(
269            Arc::clone(&source),
270            error.start_byte().min(source_text.len())..error.end_byte().min(source_text.len()),
271        )));
272    }
273    let syntax =
274        Lowerer::new(Arc::clone(&source), source_text, aliases).source_file(tree.root_node())?;
275    Ok(ParsedTree {
276        parse_view,
277        tree,
278        syntax,
279        diagnostics,
280    })
281}
282
283/// Handles input edit between.
284fn input_edit_between(old: &str, new: &str) -> tree_sitter::InputEdit {
285    let mut start = old
286        .as_bytes()
287        .iter()
288        .zip(new.as_bytes())
289        .take_while(|(old, new)| old == new)
290        .count();
291    while !old.is_char_boundary(start) || !new.is_char_boundary(start) {
292        start -= 1;
293    }
294
295    let available_suffix = old.len().min(new.len()).saturating_sub(start);
296    let mut suffix = old
297        .as_bytes()
298        .iter()
299        .rev()
300        .zip(new.as_bytes().iter().rev())
301        .take(available_suffix)
302        .take_while(|(old, new)| old == new)
303        .count();
304    while !old.is_char_boundary(old.len() - suffix) || !new.is_char_boundary(new.len() - suffix) {
305        suffix -= 1;
306    }
307
308    let old_end = old.len() - suffix;
309    let new_end = new.len() - suffix;
310    tree_sitter::InputEdit {
311        start_byte: start,
312        old_end_byte: old_end,
313        new_end_byte: new_end,
314        start_position: point_at(old, start),
315        old_end_position: point_at(old, old_end),
316        new_end_position: point_at(new, new_end),
317    }
318}
319
320/// Handles point at.
321fn point_at(source: &str, offset: usize) -> tree_sitter::Point {
322    let before = &source[..offset];
323    let row = before.bytes().filter(|byte| *byte == b'\n').count();
324    let column = before
325        .as_bytes()
326        .iter()
327        .rposition(|byte| *byte == b'\n')
328        .map_or(before.len(), |newline| before.len() - newline - 1);
329    tree_sitter::Point { row, column }
330}
331
332impl TreeSitterParser {
333    /// Creates a parser loaded with the bundled Macaulay2 grammar.
334    ///
335    /// # Errors
336    ///
337    /// Returns [`ParseError::Language`] if Tree-sitter rejects the bundled
338    /// language definition.
339    pub fn new() -> Result<Self, ParseError> {
340        let mut parser = tree_sitter::Parser::new();
341        parser
342            .set_language(&tree_sitter_macaulay2::language())
343            .map_err(ParseError::Language)?;
344        Ok(Self { parser })
345    }
346
347    /// Parses source in.
348    fn parse_source_in(&mut self, source: Arc<Source>) -> Result<SourceFile, ParseError> {
349        let source_text = source.text();
350        let (renamed, aliases) = renamed_source(source_text)?;
351        let tree = self
352            .parser
353            .parse(renamed.as_bytes(), None)
354            .ok_or(ParseError::Cancelled)?;
355        if let Some(error) = first_error(tree.root_node()) {
356            return Err(ParseError::InvalidSyntax(Span::ranged(
357                Arc::clone(&source),
358                error.start_byte()..error.end_byte(),
359            )));
360        }
361        Lowerer::new(Arc::clone(&source), source_text, aliases).source_file(tree.root_node())
362    }
363
364    /// Parses incomplete source while retaining syntax inside unclosed groups.
365    ///
366    /// The parsing view is completed only for Tree-sitter; migrated nodes
367    /// retain the original source spans and zero-width missing closers.
368    ///
369    /// # Errors
370    ///
371    /// Returns [`ParseError`] when source has a non-recoverable lexical or
372    /// grammatical failure, parsing is cancelled, or lowering fails.
373    pub fn parse_recovering(
374        &mut self,
375        source: &str,
376    ) -> Result<Recovered<SourceFile, LexError>, ParseError> {
377        let source = Source::new(source);
378        let source_text = source.text();
379        let (renamed, aliases, diagnostics) = renamed_source_recovering(source_text)?;
380        let tree = self
381            .parser
382            .parse(renamed.as_bytes(), None)
383            .ok_or(ParseError::Cancelled)?;
384        if let Some(error) = first_error(tree.root_node()) {
385            return Err(ParseError::InvalidSyntax(Span::ranged(
386                Arc::clone(&source),
387                error.start_byte().min(source_text.len())..error.end_byte().min(source_text.len()),
388            )));
389        }
390        let syntax = Lowerer::new(Arc::clone(&source), source_text, aliases)
391            .source_file(tree.root_node())?;
392        Ok(Recovered::new(syntax, diagnostics))
393    }
394}
395
396impl Parser for TreeSitterParser {
397    type Error = ParseError;
398
399    fn parse_cells(&mut self, cells: CellStream) -> Result<SourceFile, Self::Error> {
400        let (cell_comments, comments) = cells.comment_ownership();
401        let mut source_file = match cells.complete_source() {
402            Some(source) => self.parse_source_in(source),
403            None => self.parse_source_in(Source::new(cells.to_string())),
404        }?;
405        if source_file.cells.len() == cell_comments.len() {
406            for (cell, comments) in source_file.cells.iter_mut().zip(cell_comments) {
407                cell.comments = comments;
408            }
409            source_file.comments = comments;
410        } else {
411            source_file.comments = comments;
412            for comments in cell_comments {
413                source_file.comments.append(comments);
414            }
415        }
416        Ok(source_file)
417    }
418}
419
420/// Parses source with Tree-sitter and lowers its CST into the typed syntax tree.
421///
422/// # Errors
423///
424/// Returns [`ParseError`] when parsing or typed migration fails.
425pub fn parse_file(source: &str) -> Result<SourceFile, ParseError> {
426    let mut parser = TreeSitterParser::new()?;
427    let cells = lex_str(source)?.to_cell_stream()?;
428    parser.parse_cells(cells)
429}
430
431/// Parses incomplete source while retaining syntax inside unclosed groups.
432///
433/// # Errors
434///
435/// Returns [`ParseError`] for failures other than missing closing delimiters or
436/// when the recovered Tree-sitter CST cannot be lowered.
437pub fn parse_file_recovering(source: &str) -> Result<Recovered<SourceFile, LexError>, ParseError> {
438    TreeSitterParser::new()?.parse_recovering(source)
439}
440
441/// Parses an emitted M2 token stream into the complete typed source file.
442///
443/// # Errors
444///
445/// Returns [`ParseError`] when the emitted source is invalid or migration
446/// fails.
447pub fn parse_tokens(tokens: &TokenStream) -> Result<SourceFile, ParseError> {
448    let cells = tokens.to_cell_stream()?;
449    TreeSitterParser::new()?.parse_cells(cells)
450}
451
452/// Handles first error.
453fn first_error(root: tree_sitter::Node<'_>) -> Option<tree_sitter::Node<'_>> {
454    let mut pending = vec![root];
455    while let Some(node) = pending.pop() {
456        if node.is_error() || node.is_missing() {
457            return Some(node);
458        }
459        pending.extend((0..node.child_count()).rev().filter_map(|index| {
460            node.child(u32::try_from(index).expect("Tree-sitter child count fits u32"))
461        }));
462    }
463    None
464}
465
466/// Internal state for Lowerer.
467struct Lowerer<'source> {
468    /// The source.
469    source: &'source [u8],
470    /// The source span.
471    source_span: Span,
472    /// The aliases.
473    aliases: Vec<CoreAlias>,
474}
475
476/// Internal alternatives for IterationDomain.
477enum IterationDomain {
478    /// The Range alternative.
479    Range(Option<RangeBoundFrom>, Option<RangeBoundTo>),
480    /// The In alternative.
481    In(Token![in], Box<Expr>),
482}
483
484impl<'source> Lowerer<'source> {
485    /// Creates a new value.
486    fn new(source_owner: Arc<Source>, source: &'source str, aliases: Vec<CoreAlias>) -> Self {
487        Self {
488            source: source.as_bytes(),
489            source_span: Span::ranged(source_owner, 0..source.len()),
490            aliases,
491        }
492    }
493
494    /// Handles source file.
495    fn source_file(&self, root: tree_sitter::Node<'_>) -> Result<SourceFile, ParseError> {
496        let mut cells = Vec::new();
497        let raw_cells = self.semantic_children(root);
498        for (index, child) in raw_cells.iter().copied().enumerate() {
499            match child.kind() {
500                "cell" | "muted" => {
501                    let next = raw_cells.get(index + 1).copied();
502                    cells.push(self.cell(child, self.eoc_offset(child, next))?);
503                }
504                kind => return Err(self.unsupported(kind, child)),
505            }
506        }
507        let eof_offset = cells
508            .last()
509            .and_then(|cell| cell.eoc.span().start())
510            .unwrap_or(self.source.len());
511        Ok(SourceFile::new(
512            cells,
513            EOF::new("", self.source_span.at(eof_offset)),
514        ))
515    }
516
517    /// Handles cell.
518    fn cell(&self, node: tree_sitter::Node<'_>, eoc_offset: usize) -> Result<Cell, ParseError> {
519        let (content, semicolon) = if node.kind() == "muted" {
520            let semicolon = self.required_kind(node, ";")?;
521            (
522                self.packed_content(self.children(node))?,
523                Some(self.migrate(semicolon)?),
524            )
525        } else {
526            let child = self.only_semantic_child(node)?;
527            let content = if child.kind() == "naked_sequence" {
528                self.expr_pack(self.children(child))?.into()
529            } else {
530                self.expr(child)?.into()
531            };
532            (content, None)
533        };
534        Ok(Cell::new(
535            content,
536            semicolon,
537            EOC::new("", self.source_span.at(eoc_offset)),
538        ))
539    }
540
541    /// Handles end-of-cell offset.
542    fn eoc_offset(
543        &self,
544        _node: tree_sitter::Node<'_>,
545        next: Option<tree_sitter::Node<'_>>,
546    ) -> usize {
547        next.map_or(self.source.len(), |next| next.start_byte())
548            .min(self.source.len())
549    }
550
551    /// Handles expr pack.
552    fn expr_pack(&self, nodes: Vec<tree_sitter::Node<'_>>) -> Result<ExprPack, ParseError> {
553        let pack_span = nodes
554            .iter()
555            .map(|node| self.span(*node))
556            .reduce(|left, right| {
557                left.join(right)
558                    .expect("Tree-sitter nodes share one source snapshot")
559            })
560            .unwrap_or_else(|| Span::unlocated(Arc::clone(self.source_span.source())));
561        let mut values = Vec::new();
562        let mut commas = Vec::new();
563        for node in nodes.into_iter().filter(|node| !node.is_extra()) {
564            match node.kind() {
565                "," => commas.push(self.migrate::<Token![,]>(node)?),
566                "empty_component" => values.push(Component::Empty(Empty::new("", self.span(node)))),
567                ";" | "(" | ")" | "[" | "]" | "{" | "}" | "<|" | "|>" | "muted" => {}
568                _ if node.is_named() => values.push(Component::Expr(Box::new(self.expr(node)?))),
569                _ => {}
570            }
571        }
572        let mut values = values.into_iter();
573        let Some(first) = values.next() else {
574            return Err(self.unsupported_span("empty expression pack", pack_span));
575        };
576        let value_count = values.len() + 1;
577        let comma_count = commas.len();
578        if value_count != comma_count + 1 {
579            return Err(self.unsupported_span("invalid expression pack", pack_span));
580        }
581        let rest = commas
582            .into_iter()
583            .zip(values)
584            .collect::<Vec<(Token![,], Component)>>();
585        let mut rest = rest.into_iter();
586        let Some((punctuation, second)) = rest.next() else {
587            return Err(self.unsupported_span("expression pack without a comma", pack_span));
588        };
589        let mut pack = Punctuated::new(first, punctuation, second);
590        for (punctuation, value) in rest {
591            pack.push(punctuation, value);
592        }
593        Ok(ExprPack::new(pack))
594    }
595
596    /// Handles packed content.
597    fn packed_content(
598        &self,
599        nodes: Vec<tree_sitter::Node<'_>>,
600    ) -> Result<PackedContent, ParseError> {
601        if nodes.iter().any(|node| node.kind() == ",") {
602            return self.expr_pack(nodes).map(Into::into);
603        }
604        let mut expressions = nodes
605            .into_iter()
606            .filter(|node| !node.is_extra() && node.is_named() && node.kind() != "muted");
607        let Some(expression) = expressions.next() else {
608            return Err(self.unsupported_span("empty packed content", self.source_span.clone()));
609        };
610        if expressions.next().is_some() {
611            return Err(self.unsupported("unseparated packed content", expression));
612        }
613        self.expr(expression).map(Into::into)
614    }
615
616    /// Handles expr.
617    fn expr(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
618        match node.kind() {
619            "symbol" => Ok(self.migrate::<Symbol>(node)?.into()),
620            "integer_literal" if self.text(node).contains('p') => {
621                Ok(FloatLiteral::new(self.text(node), self.span(node)).into())
622            }
623            "integer_literal" => Ok(self.migrate::<IntegerLiteral>(node)?.into()),
624            "float_literal" => Ok(self.migrate::<FloatLiteral>(node)?.into()),
625            "string_literal" => self.string_literal(node),
626            "raw_string_literal" => self.raw_string_literal(node),
627            "array" | "list" | "angle_bar_list" | "sequence" | "parenthesized_expression" => {
628                self.collection(node)
629            }
630            "binary_expression" => self.binary_expr(node),
631            "prefix_expression" => self.prefix_expr(node),
632            "postfix_expression" => self.postfix_expr(node),
633            "lambda_expression" => self.lambda_expression(node),
634            "assignment"
635            | "local_assignment"
636            | "binary_assignment"
637            | "prefix_assignment"
638            | "postfix_assignment"
639            | "binary_installation"
640            | "prefix_installation"
641            | "postfix_installation"
642            | "structured_binding"
643            | "local_structured_binding" => self.assignment(node),
644            "evaluated_assignment" => Ok(Expr!(Assign::Evaluated {
645                evaluated_domain: Box::new(self.expr(self.required_field(node, "left")?)?),
646                operator: self.migrate(self.required_field(node, "operator")?)?,
647                value: Box::new(self.expr(self.required_field(node, "right")?)?),
648            })),
649            "option" => Ok(Expr!(Option {
650                key: Box::new(self.expr(self.required_field(node, "left")?)?),
651                operator: self.migrate(self.required_field(node, "operator")?)?,
652                value: Box::new(self.expr(self.required_field(node, "right")?)?),
653            })),
654            "if_statement" => self.if_statement(node),
655            "for_loop" => self.for_loop(node),
656            "while_loop" => self.while_loop(node),
657            "try_statement" => self.try_statement(node),
658            "quote_expression" => self.quote_expression(node),
659            "new_statement" => self.new_statement(node),
660            "break_statement" => Ok(Expr!(Control::Break {
661                break_token: self.migrate(self.required_kind(node, "break")?)?,
662                value: self
663                    .first_expression_child(node)
664                    .map(|child| self.expr(child).map(Box::new))
665                    .transpose()?,
666            })),
667            "continue_statement" => Ok(Expr!(Control::Continue {
668                continue_token: self.migrate(self.required_kind(node, "continue")?)?,
669                value: self
670                    .first_expression_child(node)
671                    .map(|child| self.expr(child).map(Box::new))
672                    .transpose()?,
673            })),
674            "return_statement" => Ok(Expr!(Control::Return {
675                return_token: self.migrate(self.required_kind(node, "return")?)?,
676                value: self
677                    .first_expression_child(node)
678                    .map(|child| self.expr(child).map(Box::new))
679                    .transpose()?,
680            })),
681            "catch_statement" => Ok(Expr!(Catch {
682                catch_token: self.migrate(self.required_kind(node, "catch")?)?,
683                value: Box::new(self.expr(self.required_expression_child(node)?)?),
684            })),
685            "throw_statement" => Ok(Expr!(Throw {
686                throw_token: self.migrate(self.required_kind(node, "throw")?)?,
687                value: Box::new(self.expr(self.required_expression_child(node)?)?),
688            })),
689            "trap_statement" => Ok(Expr!(Trap {
690                trap_token: self.migrate(self.required_kind(node, "trap")?)?,
691                value: Box::new(self.expr(self.required_expression_child(node)?)?),
692            })),
693            "debug_clause" => self.debug_clause(node),
694            kind => Err(self.unsupported(kind, node)),
695        }
696    }
697
698    /// Handles collection.
699    fn collection(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
700        let spans = self.delimiter_spans(node)?;
701        let statements = self
702            .semantic_children(node)
703            .into_iter()
704            .filter(|child| child.kind() == "muted")
705            .map(|child| self.statement(child))
706            .collect::<Result<Vec<_>, _>>()?;
707
708        if node.kind() == "parenthesized_expression" {
709            let value = self
710                .semantic_children(node)
711                .into_iter()
712                .find(|child| child.kind() != "muted")
713                .map(|child| self.expr(child))
714                .transpose()?;
715            let mut holder = Holder::new(statements, value.map(Box::new));
716            holder.delimiter = <Delimiter![()] as DelimiterToken>::new(spans);
717            return Ok(holder.into());
718        }
719
720        let has_elements = self.children(node).into_iter().any(|child| {
721            !child.is_extra()
722                && (child.kind() == ","
723                    || child.kind() == "empty_component"
724                    || (child.is_named() && child.kind() != "muted"))
725        });
726        let elements = has_elements
727            .then(|| self.packed_content(self.children(node)))
728            .transpose()?;
729        Ok(match node.kind() {
730            "array" => {
731                let mut value = Array::new(statements, elements);
732                value.delimiter = <Delimiter![[]] as DelimiterToken>::new(spans);
733                value.into()
734            }
735            "list" => {
736                let mut value = List::new(statements, elements);
737                value.delimiter = <Delimiter![{}] as DelimiterToken>::new(spans);
738                value.into()
739            }
740            "angle_bar_list" => {
741                let mut value = AngleBarList::new(statements, elements);
742                value.delimiter = <Delimiter![<| |>] as DelimiterToken>::new(spans);
743                value.into()
744            }
745            "sequence" => {
746                let mut value = Sequence::new(statements, elements);
747                value.delimiter = <Delimiter![()] as DelimiterToken>::new(spans);
748                value.into()
749            }
750            kind => return Err(self.unsupported(kind, node)),
751        })
752    }
753
754    /// Handles statement.
755    fn statement(&self, node: tree_sitter::Node<'_>) -> Result<Statement, ParseError> {
756        Ok(Statement::new(
757            self.packed_content(self.children(node))?,
758            self.migrate(self.required_kind(node, ";")?)?,
759        ))
760    }
761
762    /// Handles string literal.
763    fn string_literal(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
764        let elements = self
765            .children(node)
766            .into_iter()
767            .filter(|child| child.kind() != "\"")
768            .filter(|child| !child.is_extra())
769            .map(|child| match child.kind() {
770                "escape_sequence" => self.migrate(child).map(StringElement::Escape),
771                "string_content" => self.migrate(child).map(StringElement::Content),
772                _ => Ok(StringElement::Content(StringContent::new(
773                    self.text(child),
774                    self.span(child),
775                ))),
776            })
777            .collect::<Result<Vec<_>, ParseError>>()?;
778        Ok(StringLiteral::new(elements, self.span(node)).into())
779    }
780
781    /// Handles raw string literal.
782    fn raw_string_literal(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
783        let elements = self
784            .children(node)
785            .into_iter()
786            .filter(|child| child.kind() != "///")
787            .filter(|child| !child.is_extra())
788            .map(|child| match child.kind() {
789                "escape_sequence" => self.migrate(child).map(RawStringElement::Escape),
790                "raw_string_content" => self.migrate(child).map(RawStringElement::Content),
791                kind => Err(self.unsupported(kind, child)),
792            })
793            .collect::<Result<Vec<_>, ParseError>>()?;
794        Ok(RawStringLiteral::new(elements, self.span(node)).into())
795    }
796
797    /// Handles binary expr.
798    fn binary_expr(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
799        let left = self.expr(
800            self.child_by_field(node, "left_operand")
801                .or_else(|| self.child_by_field(node, "left"))
802                .ok_or_else(|| self.unsupported("left operand", node))?,
803        )?;
804        let operator = self.required_field(node, "operator")?;
805        let right = self.expr(self.required_field(node, "right")?)?;
806        if operator.kind() == "SPACE" {
807            Ok(Expr!(Op::Bin::Adj {
808                left_operand: Box::new(left),
809                operator: Adj::new("", self.span(operator)),
810                right_operand: Box::new(right),
811            }))
812        } else {
813            match self.text(operator).as_ref() {
814                spelling if GENERATED_AUGMENTED_OPERATOR_SPELLINGS.contains(&spelling) => {
815                    Ok(Expr!(Assign::Augmented {
816                        target: Box::new(left),
817                        operator: self.migrate(operator)?,
818                        value: Box::new(right),
819                    }))
820                }
821                "." => Ok(Expr!(Op::Bin::Member::Dot {
822                    receiver: Box::new(left),
823                    operator: self.migrate(operator)?,
824                    member: Box::new(right),
825                })),
826                ".?" => Ok(Expr!(Op::Bin::Member::Optional {
827                    receiver: Box::new(left),
828                    operator: self.migrate(operator)?,
829                    member: Box::new(right),
830                })),
831                "#" => Ok(Expr!(Op::Bin::Index {
832                    receiver: Box::new(left),
833                    operator: self.migrate(operator)?,
834                    index: Box::new(right),
835                })),
836                _ => Ok(Expr!(Op::Bin::Regular {
837                    left_operand: Box::new(left),
838                    operator: self.migrate(operator)?,
839                    right_operand: Box::new(right),
840                })),
841            }
842        }
843    }
844
845    /// Handles prefix expr.
846    fn prefix_expr(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
847        Ok(Expr!(Op::Prefix {
848            operator: self.migrate(self.required_field(node, "operator")?)?,
849            operand: Box::new(self.expr(self.required_field(node, "operand")?)?),
850        }))
851    }
852
853    /// Handles postfix expr.
854    fn postfix_expr(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
855        Ok(Expr!(Op::Postfix {
856            operand: Box::new(self.expr(self.required_field(node, "operand")?)?),
857            operator: self.migrate(self.required_field(node, "operator")?)?,
858        }))
859    }
860
861    /// Handles lambda expression.
862    fn lambda_expression(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
863        let argument_expr = self.expr(self.required_field(node, "parameters")?)?;
864        let arguments = lambda_arguments(argument_expr)
865            .ok_or_else(|| self.unsupported("lambda arguments", node))?;
866        let operator = self.migrate(self.required_field(node, "operator")?)?;
867        let body = Box::new(self.expr(self.required_field(node, "body")?)?);
868        Ok(match arguments {
869            LambdaArguments::Variadic(argument) => Expr!(Lambda::Variadic {
870                argument,
871                operator,
872                body,
873            }),
874            LambdaArguments::List(arguments) => Expr!(Lambda::List {
875                arguments: *arguments,
876                operator,
877                body,
878            }),
879        })
880    }
881
882    /// Handles assignment.
883    fn assignment(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
884        let right = self.expr(self.required_field(node, "right")?)?;
885        Ok(match node.kind() {
886            "assignment" => Expr!(Assign::Simple::Global {
887                variable: self.migrate(self.required_field(node, "left")?)?,
888                operator: self.migrate(self.required_field(node, "operator")?)?,
889                value: Box::new(right),
890            }),
891            "local_assignment" => Expr!(Assign::Simple::Local {
892                variable: self.migrate(self.required_field(node, "left")?)?,
893                operator: self.migrate(self.required_field(node, "operator")?)?,
894                value: Box::new(right),
895            }),
896            "binary_assignment" | "prefix_assignment" | "postfix_assignment" => {
897                let Expr::Op(left) = self.expr(self.required_field(node, "left")?)? else {
898                    return Err(self.unsupported("operator assignment target", node));
899                };
900                Expr!(Assign::Op {
901                    argument_expr: left,
902                    operator: self.migrate(self.required_field(node, "operator")?)?,
903                    value_expr: Box::new(right),
904                })
905            }
906            "binary_installation" | "prefix_installation" | "postfix_installation" => {
907                let Expr::Op(left) = self.expr(self.required_field(node, "left")?)? else {
908                    return Err(self.unsupported("operator installation target", node));
909                };
910                let (typical_value, function) = installation_value(right);
911                match left {
912                    ExprOp::Bin(ExprOpBin::Adj(application)) => Expr!(Assign::Install::Method {
913                        method: application.left_operand,
914                        operator: application.operator,
915                        signature: application.right_operand,
916                        assign_op: self.migrate(self.required_field(node, "operator")?)?,
917                        typical_value,
918                        function: Box::new(function),
919                    }),
920                    domain_expr => Expr!(Assign::Install::Op {
921                        domain_expr,
922                        assign_op: self.migrate(self.required_field(node, "operator")?)?,
923                        typical_value,
924                        function: Box::new(function),
925                    }),
926                }
927            }
928            "structured_binding" | "local_structured_binding" => {
929                let list_expr = self.expr(self.required_field(node, "binding_pack")?)?;
930                let argument_list = assignment_list(list_expr)
931                    .ok_or_else(|| self.unsupported("assignment argument list", node))?;
932                if node.kind() == "local_structured_binding" {
933                    Expr!(Assign::Parallel::Local {
934                        argument_list: Box::new(argument_list),
935                        operator: self.migrate(self.required_field(node, "operator")?)?,
936                        value: Box::new(right),
937                    })
938                } else {
939                    Expr!(Assign::Parallel::Global {
940                        argument_list: Box::new(argument_list),
941                        operator: self.migrate(self.required_field(node, "operator")?)?,
942                        value: Box::new(right),
943                    })
944                }
945            }
946            kind => return Err(self.unsupported(kind, node)),
947        })
948    }
949
950    /// Handles then clause.
951    fn then_clause(&self, node: tree_sitter::Node<'_>) -> Result<ThenClause, ParseError> {
952        Ok(ThenClause::new(
953            self.migrate(self.required_kind(node, "then")?)?,
954            Box::new(self.expr(self.required_expression_child(node)?)?),
955        ))
956    }
957
958    /// Handles else clause.
959    fn else_clause(&self, node: tree_sitter::Node<'_>) -> Result<ElseClause, ParseError> {
960        Ok(ElseClause::new(
961            self.migrate(self.required_kind(node, "else")?)?,
962            Box::new(self.expr(self.required_expression_child(node)?)?),
963        ))
964    }
965
966    /// Handles if statement.
967    fn if_statement(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
968        Ok(Expr!(If {
969            if_token: self.migrate(self.required_kind(node, "if")?)?,
970            condition: Box::new(self.expr(self.required_field(node, "condition")?)?),
971            then_clause: self.then_clause(self.required_kind(node, "then_clause")?)?,
972            else_clause: self
973                .optional_kind(node, "else_clause")
974                .map(|child| self.else_clause(child))
975                .transpose()?,
976        }))
977    }
978
979    /// Handles loop body.
980    fn loop_body(&self, node: tree_sitter::Node<'_>) -> Result<LoopBody, ParseError> {
981        let list_step = self
982            .optional_kind(node, "list")
983            .map(|token| {
984                Ok::<_, ParseError>(ListStep::new(
985                    self.migrate(token)?,
986                    Box::new(self.expr(self.required_field(node, "listed_value")?)?),
987                ))
988            })
989            .transpose()?;
990        let do_step = self
991            .optional_kind(node, "do")
992            .map(|token| {
993                Ok::<_, ParseError>(DoStep::new(
994                    self.migrate(token)?,
995                    Box::new(self.expr(self.required_field(node, "ignored_value")?)?),
996                ))
997            })
998            .transpose()?;
999        Ok(LoopBody::new(list_step, do_step))
1000    }
1001
1002    /// Handles for loop.
1003    fn for_loop(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
1004        let iteration_domain = self
1005            .optional_kind(node, "iteration_range")
1006            .map(|range| self.iteration_domain(range))
1007            .transpose()?;
1008        let when_condition = self
1009            .optional_kind(node, "when")
1010            .map(|token| {
1011                Ok::<_, ParseError>(WhenCondition::new(
1012                    self.migrate(token)?,
1013                    Box::new(self.expr(self.required_field(node, "filter")?)?),
1014                ))
1015            })
1016            .transpose()?;
1017        let for_token = self.migrate(self.required_kind(node, "for")?)?;
1018        let variable = self.migrate(self.required_field(node, "variable")?)?;
1019        let body = self.loop_body(self.required_kind(node, "loop_body")?)?;
1020        Ok(match iteration_domain {
1021            None => Expr!(For::Bare {
1022                for_token,
1023                variable,
1024                condition: when_condition,
1025                body,
1026            }),
1027            Some(IterationDomain::Range(lower_bound, upper_bound)) => Expr!(For::Range {
1028                for_token,
1029                variable,
1030                lower_bound,
1031                upper_bound,
1032                condition: when_condition,
1033                body,
1034            }),
1035            Some(IterationDomain::In(in_token, collection)) => Expr!(For::In {
1036                for_token,
1037                variable,
1038                in_token,
1039                collection,
1040                condition: when_condition,
1041                body,
1042            }),
1043        })
1044    }
1045
1046    /// Handles iteration domain.
1047    fn iteration_domain(&self, node: tree_sitter::Node<'_>) -> Result<IterationDomain, ParseError> {
1048        if let Some(token) = self.optional_kind(node, "in") {
1049            return Ok(IterationDomain::In(
1050                self.migrate(token)?,
1051                Box::new(self.expr(self.required_field(node, "iterated_collection")?)?),
1052            ));
1053        }
1054        let lower_bound = self
1055            .optional_kind(node, "from")
1056            .map(|token| {
1057                Ok::<_, ParseError>(RangeBoundFrom::new(
1058                    self.migrate(token)?,
1059                    Box::new(self.expr(self.required_field(node, "range_start")?)?),
1060                ))
1061            })
1062            .transpose()?;
1063        let upper_bound = self
1064            .optional_kind(node, "to")
1065            .map(|token| {
1066                Ok::<_, ParseError>(RangeBoundTo::new(
1067                    self.migrate(token)?,
1068                    Box::new(self.expr(self.required_field(node, "range_end")?)?),
1069                ))
1070            })
1071            .transpose()?;
1072        Ok(IterationDomain::Range(lower_bound, upper_bound))
1073    }
1074
1075    /// Handles while loop.
1076    fn while_loop(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
1077        Ok(Expr!(While {
1078            while_token: self.migrate(self.required_kind(node, "while")?)?,
1079            condition: Box::new(self.expr(self.required_field(node, "condition")?)?),
1080            body: self.loop_body(self.required_kind(node, "loop_body")?)?,
1081        }))
1082    }
1083
1084    /// Handles new statement.
1085    fn new_statement(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
1086        let mut installation = None;
1087        let class =
1088            self.new_statement_element(self.required_field(node, "class")?, &mut installation)?;
1089        let parent_class = self
1090            .optional_kind(node, "of")
1091            .map(|token| {
1092                Ok::<_, ParseError>(OfClass::new(
1093                    self.migrate(token)?,
1094                    Box::new(self.new_statement_element(
1095                        self.required_field(node, "parent")?,
1096                        &mut installation,
1097                    )?),
1098                ))
1099            })
1100            .transpose()?;
1101        let instance = self
1102            .optional_kind(node, "from")
1103            .map(|token| {
1104                Ok::<_, ParseError>(FromInstance::new(
1105                    self.migrate(token)?,
1106                    Box::new(self.new_statement_element(
1107                        self.required_field(node, "instance")?,
1108                        &mut installation,
1109                    )?),
1110                ))
1111            })
1112            .transpose()?;
1113        let statement = Expr!(New {
1114            new_token: self.migrate(self.required_kind(node, "new")?)?,
1115            class: Box::new(class),
1116            parent_class,
1117            instance,
1118        });
1119        Ok(match installation {
1120            Some((operator, function)) => {
1121                let Expr::New(new_statement) = statement else {
1122                    unreachable!("the constructor selected the new-statement specialization")
1123                };
1124                Expr!(Assign::Install::New {
1125                    new_statement,
1126                    operator,
1127                    function: Box::new(function),
1128                })
1129            }
1130            None => statement,
1131        })
1132    }
1133
1134    /// Handles new statement element.
1135    fn new_statement_element(
1136        &self,
1137        node: tree_sitter::Node<'_>,
1138        installation: &mut Option<(Token![:=], Expr)>,
1139    ) -> Result<Expr, ParseError> {
1140        match node.kind() {
1141            "assignment" => return Err(self.unsupported("`new` assignment with `=`", node)),
1142            "local_assignment" => {}
1143            _ => return self.expr(node),
1144        }
1145        *installation = Some((
1146            self.migrate(self.required_field(node, "operator")?)?,
1147            self.expr(self.required_field(node, "right")?)?,
1148        ));
1149        self.expr(self.required_field(node, "left")?)
1150    }
1151
1152    /// Attempts to statement.
1153    fn try_statement(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
1154        let value = self
1155            .semantic_children(node)
1156            .into_iter()
1157            .find(|child| {
1158                child.kind() != "then_clause"
1159                    && child.kind() != "else_clause"
1160                    && child.kind() != "except_clause"
1161            })
1162            .ok_or_else(|| self.unsupported("try value", node))?;
1163        let on_success = self
1164            .optional_kind(node, "then_clause")
1165            .map(|child| self.then_clause(child))
1166            .transpose()?;
1167        let fallback = self
1168            .child_by_field(node, "fallback")
1169            .map(|child| match child.kind() {
1170                "else_clause" => self.else_clause(child).map(TryFallback::Else),
1171                "except_clause" => self.except_do(child),
1172                kind => Err(self.unsupported(kind, child)),
1173            })
1174            .transpose()?;
1175        Ok(Expr!(Try {
1176            try_token: self.migrate(self.required_kind(node, "try")?)?,
1177            value: Box::new(self.expr(value)?),
1178            on_success,
1179            fallback,
1180        }))
1181    }
1182
1183    /// Handles except do.
1184    fn except_do(&self, node: tree_sitter::Node<'_>) -> Result<TryFallback, ParseError> {
1185        Ok(TryFallback!(Except {
1186            except_token: self.migrate(self.required_kind(node, "except")?)?,
1187            exception: self.migrate(self.required_field(node, "exception")?)?,
1188            do_token: self.migrate(self.required_kind(node, "do")?)?,
1189            value: Box::new(self.expr(self.required_expression_child(node)?)?),
1190        }))
1191    }
1192
1193    /// Handles quote expression.
1194    fn quote_expression(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
1195        let token = self
1196            .children(node)
1197            .into_iter()
1198            .find(|child| {
1199                matches!(
1200                    child.kind(),
1201                    "symbol" | "local" | "global" | "threadVariable" | "threadLocal"
1202                ) && self.child_by_field(node, "token") != Some(*child)
1203            })
1204            .ok_or_else(|| self.unsupported("quote specifier", node))?;
1205        let quoted = self.required_field(node, "token")?;
1206        let symbol = Symbol::new(self.text(quoted), self.span(quoted));
1207        Ok(match token.kind() {
1208            "symbol" => Expr!(Quote::Symbol {
1209                specifier: self.migrate(token)?,
1210                symbol,
1211            }),
1212            "local" => Expr!(Quote::Local {
1213                specifier: self.migrate(token)?,
1214                symbol,
1215            }),
1216            "global" => Expr!(Quote::Global {
1217                specifier: self.migrate(token)?,
1218                symbol,
1219            }),
1220            "threadVariable" => Expr!(Quote::ThreadVariable {
1221                specifier: self.migrate(token)?,
1222                symbol,
1223            }),
1224            "threadLocal" => Expr!(Quote::ThreadLocal {
1225                specifier: self.migrate(token)?,
1226                symbol,
1227            }),
1228            kind => return Err(self.unsupported(kind, token)),
1229        })
1230    }
1231
1232    /// Handles debug clause.
1233    fn debug_clause(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
1234        let keyword = self.required_field(node, "keyword")?;
1235        let value = self
1236            .first_expression_child(node)
1237            .map(|child| self.expr(child))
1238            .transpose()?;
1239        Ok(match keyword.kind() {
1240            "elapsedTime" => Expr!(Profile::ElapsedTime {
1241                modifier: self.migrate(keyword)?,
1242                value: Box::new(value.ok_or_else(|| self.unsupported("profiling operand", node))?,),
1243            }),
1244            "elapsedTiming" => Expr!(Profile::ElapsedTiming {
1245                modifier: self.migrate(keyword)?,
1246                value: Box::new(value.ok_or_else(|| self.unsupported("profiling operand", node))?,),
1247            }),
1248            "profile" => Expr!(Profile::Profile {
1249                modifier: self.migrate(keyword)?,
1250                value: Box::new(value.ok_or_else(|| self.unsupported("profiling operand", node))?,),
1251            }),
1252            "time" => Expr!(Profile::Time {
1253                modifier: self.migrate(keyword)?,
1254                value: Box::new(value.ok_or_else(|| self.unsupported("profiling operand", node))?,),
1255            }),
1256            "timing" => Expr!(Profile::Timing {
1257                modifier: self.migrate(keyword)?,
1258                value: Box::new(value.ok_or_else(|| self.unsupported("profiling operand", node))?,),
1259            }),
1260            "TEST" => Expr!(Debug::Test {
1261                keyword: self.migrate(keyword)?,
1262                value: value.map(Box::new),
1263            }),
1264            "step" => Expr!(Debug::Step {
1265                keyword: self.migrate(keyword)?,
1266                value: value.map(Box::new),
1267            }),
1268            "finish" => Expr!(Debug::Finish {
1269                keyword: self.migrate(keyword)?,
1270                value: value.map(Box::new),
1271            }),
1272            "shield" => Expr!(Debug::Shield {
1273                keyword: self.migrate(keyword)?,
1274                value: value.map(Box::new),
1275            }),
1276            "breakpoint" => Expr!(Debug::Breakpoint {
1277                keyword: self.migrate(keyword)?,
1278                value: value.map(Box::new),
1279            }),
1280            kind => return Err(self.unsupported(kind, keyword)),
1281        })
1282    }
1283
1284    /// Handles migrate.
1285    fn migrate<T>(&self, node: tree_sitter::Node<'_>) -> Result<T, ParseError>
1286    where
1287        for<'tree> T: Migrate<TreeSitterNode<'tree, 'source>>,
1288    {
1289        T::migrate(TreeSitterNode::with_span(
1290            node,
1291            self.source,
1292            self.span(node),
1293        ))
1294        .map_err(Into::into)
1295    }
1296
1297    /// Handles delimiter spans.
1298    fn delimiter_spans(&self, node: tree_sitter::Node<'_>) -> Result<DoubleSpan, ParseError> {
1299        let kind = match node.kind() {
1300            "parenthesized_expression" | "sequence" => DelimiterKind::Parenthesis,
1301            "array" => DelimiterKind::Bracket,
1302            "list" => DelimiterKind::Brace,
1303            "angle_bar_list" => DelimiterKind::AngleBar,
1304            other => return Err(self.unsupported(other, node)),
1305        };
1306        let opening = self.span(self.required_kind(node, kind.opening())?);
1307        let closing = self.required_kind(node, kind.closing())?;
1308        if closing.start_byte() >= self.source.len() {
1309            Ok(DoubleSpan::unclosed(opening))
1310        } else {
1311            Ok(DoubleSpan::new(opening, self.span(closing)))
1312        }
1313    }
1314
1315    /// Handles children.
1316    fn children<'tree>(&self, node: tree_sitter::Node<'tree>) -> Vec<tree_sitter::Node<'tree>> {
1317        (0..node.child_count())
1318            .filter_map(|index| node.child(u32::try_from(index).expect("child count fits u32")))
1319            .collect()
1320    }
1321
1322    /// Handles semantic children.
1323    fn semantic_children<'tree>(
1324        &self,
1325        node: tree_sitter::Node<'tree>,
1326    ) -> Vec<tree_sitter::Node<'tree>> {
1327        self.children(node)
1328            .into_iter()
1329            .filter(|child| child.is_named() && !child.is_extra())
1330            .collect()
1331    }
1332
1333    /// Handles only semantic child.
1334    fn only_semantic_child<'tree>(
1335        &self,
1336        node: tree_sitter::Node<'tree>,
1337    ) -> Result<tree_sitter::Node<'tree>, ParseError> {
1338        let children = self.semantic_children(node);
1339        match children.as_slice() {
1340            [child] => Ok(*child),
1341            _ => Err(self.unsupported("cell contents", node)),
1342        }
1343    }
1344
1345    /// Handles first expression child.
1346    fn first_expression_child<'tree>(
1347        &self,
1348        node: tree_sitter::Node<'tree>,
1349    ) -> Option<tree_sitter::Node<'tree>> {
1350        self.semantic_children(node).into_iter().find(|child| {
1351            !matches!(
1352                child.kind(),
1353                "then_clause" | "else_clause" | "except_clause" | "iteration_range" | "loop_body"
1354            )
1355        })
1356    }
1357
1358    /// Handles required expression child.
1359    fn required_expression_child<'tree>(
1360        &self,
1361        node: tree_sitter::Node<'tree>,
1362    ) -> Result<tree_sitter::Node<'tree>, ParseError> {
1363        self.first_expression_child(node)
1364            .ok_or_else(|| self.unsupported("expression child", node))
1365    }
1366
1367    /// Handles child by field.
1368    fn child_by_field<'tree>(
1369        &self,
1370        node: tree_sitter::Node<'tree>,
1371        field: &str,
1372    ) -> Option<tree_sitter::Node<'tree>> {
1373        node.child_by_field_name(field)
1374    }
1375
1376    /// Handles required field.
1377    fn required_field<'tree>(
1378        &self,
1379        node: tree_sitter::Node<'tree>,
1380        field: &str,
1381    ) -> Result<tree_sitter::Node<'tree>, ParseError> {
1382        self.child_by_field(node, field)
1383            .ok_or_else(|| self.unsupported(field, node))
1384    }
1385
1386    /// Handles optional kind.
1387    fn optional_kind<'tree>(
1388        &self,
1389        node: tree_sitter::Node<'tree>,
1390        kind: &str,
1391    ) -> Option<tree_sitter::Node<'tree>> {
1392        self.children(node)
1393            .into_iter()
1394            .find(|child| !child.is_extra() && child.kind() == kind)
1395    }
1396
1397    /// Handles required kind.
1398    fn required_kind<'tree>(
1399        &self,
1400        node: tree_sitter::Node<'tree>,
1401        kind: &str,
1402    ) -> Result<tree_sitter::Node<'tree>, ParseError> {
1403        self.optional_kind(node, kind)
1404            .ok_or_else(|| self.unsupported(kind, node))
1405    }
1406
1407    /// Returns the source text.
1408    fn text(&self, node: tree_sitter::Node<'_>) -> Cow<'_, str> {
1409        let range = self
1410            .span(node)
1411            .bounds()
1412            .map_or_else(|| node.byte_range(), |(start, end)| start..end);
1413        String::from_utf8_lossy(&self.source[range])
1414    }
1415
1416    /// Returns the source span.
1417    fn span(&self, node: tree_sitter::Node<'_>) -> Span {
1418        let range = node.byte_range();
1419        self.aliases
1420            .iter()
1421            .find(|alias| alias.bare == range)
1422            .map_or_else(
1423                || {
1424                    self.source_span.subspan(
1425                        node.start_byte().min(self.source.len()),
1426                        node.end_byte().min(self.source.len()),
1427                    )
1428                },
1429                |alias| self.source_span.subspan(alias.full.start, alias.full.end),
1430            )
1431    }
1432
1433    /// Handles unsupported.
1434    fn unsupported(&self, kind: impl Into<String>, node: tree_sitter::Node<'_>) -> ParseError {
1435        self.unsupported_span(kind, self.span(node))
1436    }
1437
1438    /// Handles unsupported span.
1439    fn unsupported_span(&self, kind: impl Into<String>, span: Span) -> ParseError {
1440        ParseError::UnsupportedNode {
1441            kind: kind.into(),
1442            span,
1443        }
1444    }
1445}
1446
1447#[derive(Clone)]
1448/// Internal state for CoreAlias.
1449struct CoreAlias {
1450    /// The full.
1451    full: Range<usize>,
1452    /// The bare.
1453    bare: Range<usize>,
1454}
1455
1456/// Handles renamed source.
1457fn renamed_source(source: &str) -> Result<(Cow<'_, str>, Vec<CoreAlias>), LexError> {
1458    let tokens = lex_str(source)?;
1459    let mut aliases = Vec::new();
1460    collect_core_aliases(&tokens, &mut aliases);
1461    if aliases.is_empty() {
1462        return Ok((Cow::Borrowed(source), aliases));
1463    }
1464
1465    let mut renamed = source.as_bytes().to_vec();
1466    for alias in &aliases {
1467        renamed[alias.full.start..alias.bare.start].fill(b' ');
1468    }
1469    Ok((
1470        Cow::Owned(String::from_utf8(renamed).expect("replacing ASCII bytes preserves UTF-8")),
1471        aliases,
1472    ))
1473}
1474
1475/// Internal alias for RecoveredSource.
1476type RecoveredSource<'source> = (Cow<'source, str>, Vec<CoreAlias>, Vec<LexError>);
1477
1478/// Handles renamed source recovering.
1479fn renamed_source_recovering(source: &str) -> Result<RecoveredSource<'_>, LexError> {
1480    let recovered = lex_str_recovering(source)?;
1481    let (tokens, diagnostics) = recovered.into_parts();
1482    let mut aliases = Vec::new();
1483    collect_core_aliases(&tokens, &mut aliases);
1484    let mut missing = Vec::new();
1485    collect_missing_closers(&tokens, &mut missing);
1486
1487    if aliases.is_empty() && missing.is_empty() {
1488        return Ok((Cow::Borrowed(source), aliases, diagnostics));
1489    }
1490
1491    let mut renamed = source.as_bytes().to_vec();
1492    for alias in &aliases {
1493        renamed[alias.full.start..alias.bare.start].fill(b' ');
1494    }
1495    for kind in missing {
1496        renamed.extend_from_slice(kind.closing().as_bytes());
1497    }
1498    Ok((
1499        Cow::Owned(String::from_utf8(renamed).expect("ASCII recovery preserves UTF-8")),
1500        aliases,
1501        diagnostics,
1502    ))
1503}
1504
1505/// Collects missing closers.
1506fn collect_missing_closers(tokens: &TokenStream, missing: &mut Vec<DelimiterKind>) {
1507    for token in tokens.iter() {
1508        let TokenTree::Group(group) = token else {
1509            continue;
1510        };
1511        collect_missing_closers(group.stream(), missing);
1512        if !group.delimiter().is_closed() {
1513            missing.push(group.delim_kind());
1514        }
1515    }
1516}
1517
1518/// Collects core aliases.
1519fn collect_core_aliases(tokens: &TokenStream, aliases: &mut Vec<CoreAlias>) {
1520    for token in tokens.iter() {
1521        match token {
1522            TokenTree::Group(group) => collect_core_aliases(group.stream(), aliases),
1523            TokenTree::Ident(identifier) => {
1524                let spelling = identifier.text();
1525                let bare = crate::lexer::canonical_word_spelling(spelling);
1526                if bare == spelling {
1527                    continue;
1528                }
1529                let Some((start, end)) = identifier.expect_span().bounds() else {
1530                    continue;
1531                };
1532                aliases.push(CoreAlias {
1533                    full: start..end,
1534                    bare: end - bare.len()..end,
1535                });
1536            }
1537            TokenTree::Literal(_) | TokenTree::Punct(_) => {}
1538        }
1539    }
1540}
1541
1542#[derive(Clone)]
1543/// A borrowed Tree-sitter node paired with the source bytes it spans.
1544pub struct TreeSitterNode<'tree, 'source> {
1545    /// The node.
1546    node: tree_sitter::Node<'tree>,
1547    /// The source.
1548    source: &'source [u8],
1549    /// The span.
1550    span: Option<Span>,
1551}
1552
1553impl<'tree, 'source> TreeSitterNode<'tree, 'source> {
1554    /// Creates an external migration node.
1555    pub fn new(node: tree_sitter::Node<'tree>, source: &'source [u8]) -> Self {
1556        Self {
1557            node,
1558            source,
1559            span: None,
1560        }
1561    }
1562
1563    /// Handles with span.
1564    fn with_span(node: tree_sitter::Node<'tree>, source: &'source [u8], span: Span) -> Self {
1565        Self {
1566            node,
1567            source,
1568            span: Some(span),
1569        }
1570    }
1571}
1572
1573impl ExternalCstNode for TreeSitterNode<'_, '_> {
1574    type Children<'syntax>
1575        = IntoIter<ExternalCstChild<Self>>
1576    where
1577        Self: 'syntax;
1578
1579    fn identity(&self) -> CSTNodeClassLabel<'_> {
1580        CSTNodeClassLabel::new(self.node.kind(), self.node.is_named())
1581    }
1582
1583    fn children(&self) -> Self::Children<'_> {
1584        let parent = self.node;
1585        (0..parent.child_count())
1586            .filter_map(|index| {
1587                let index = u32::try_from(index).expect("Tree-sitter child count fits u32");
1588                parent.child(index).map(|node| ExternalCstChild {
1589                    field: parent.field_name_for_child(index),
1590                    node: Self::new(node, self.source),
1591                })
1592            })
1593            .collect::<Vec<_>>()
1594            .into_iter()
1595    }
1596
1597    fn text(&self) -> Cow<'_, str> {
1598        let range = self
1599            .span
1600            .as_ref()
1601            .and_then(Span::bounds)
1602            .map_or_else(|| self.node.byte_range(), |(start, end)| start..end);
1603        String::from_utf8_lossy(&self.source[range])
1604    }
1605
1606    fn is_extra(&self) -> bool {
1607        self.node.is_extra()
1608    }
1609}
1610
1611impl Spanned for TreeSitterNode<'_, '_> {
1612    fn try_span(&self) -> Option<Span> {
1613        self.span.clone()
1614    }
1615}