1use 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::{assignment_pack, installation_value, lambda_parameters};
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)]
26pub enum ParseError {
28 Lex(LexError),
30 Tokenize(CellStreamError),
32 Language(tree_sitter::LanguageError),
34 Cancelled,
36 InvalidEdit,
38 InvalidSyntax(Span),
40 Migrate(MigrateError),
42 UnsupportedNode {
44 kind: String,
46 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
107pub struct TreeSitterParser {
109 parser: tree_sitter::Parser,
110}
111
112pub struct RealtimeParser {
120 parser: tree_sitter::Parser,
121 source: Arc<Source>,
122 parse_view: String,
123 tree: tree_sitter::Tree,
124 syntax: SourceFile,
125 diagnostics: Vec<LexError>,
126 changed_ranges: Vec<Span>,
127}
128
129impl RealtimeParser {
130 pub fn new(source: impl Into<String>) -> Result<Self, ParseError> {
137 let source = Source::new(source.into());
138 let mut parser = TreeSitterParser::new()?.parser;
139 let ParsedTree {
140 parse_view,
141 tree,
142 syntax,
143 diagnostics,
144 } = parse_recovered_tree(&mut parser, Arc::clone(&source), None)?;
145 Ok(Self {
146 parser,
147 source,
148 parse_view,
149 tree,
150 syntax,
151 diagnostics,
152 changed_ranges: Vec::new(),
153 })
154 }
155
156 pub fn apply_edit(&mut self, edit: &TextEdit) -> Result<(), ParseError> {
167 let source_text = edit
168 .apply(self.source.text())
169 .ok_or(ParseError::InvalidEdit)?;
170 let source = Source::with_file(self.source.file(), source_text);
171 let (view, aliases, diagnostics) = renamed_source_recovering(source.text())?;
172 let parse_view = view.into_owned();
173
174 let mut edited_tree = self.tree.clone();
175 edited_tree.edit(&input_edit_between(&self.parse_view, &parse_view));
176 let tree = self
177 .parser
178 .parse(parse_view.as_bytes(), Some(&edited_tree))
179 .ok_or(ParseError::Cancelled)?;
180 if let Some(error) = first_error(tree.root_node()) {
181 return Err(ParseError::InvalidSyntax(Span::ranged(
182 Arc::clone(&source),
183 error.start_byte().min(source.text().len())
184 ..error.end_byte().min(source.text().len()),
185 )));
186 }
187 let syntax = Lowerer::new(Arc::clone(&source), source.text(), aliases)
188 .source_file(tree.root_node())?;
189 let changed_ranges = edited_tree
190 .changed_ranges(&tree)
191 .map(|range| {
192 Span::ranged(
193 Arc::clone(&source),
194 range.start_byte.min(source.text().len())
195 ..range.end_byte.min(source.text().len()),
196 )
197 })
198 .collect();
199
200 self.source = source;
201 self.parse_view = parse_view;
202 self.tree = tree;
203 self.syntax = syntax;
204 self.diagnostics = diagnostics;
205 self.changed_ranges = changed_ranges;
206 Ok(())
207 }
208
209 pub fn source(&self) -> &str {
211 self.source.text()
212 }
213
214 pub fn syntax(&self) -> &SourceFile {
216 &self.syntax
217 }
218
219 pub fn diagnostics(&self) -> &[LexError] {
221 &self.diagnostics
222 }
223
224 pub fn changed_ranges(&self) -> &[Span] {
226 &self.changed_ranges
227 }
228
229 pub fn into_syntax(self) -> SourceFile {
231 self.syntax
232 }
233}
234
235struct ParsedTree {
236 parse_view: String,
237 tree: tree_sitter::Tree,
238 syntax: SourceFile,
239 diagnostics: Vec<LexError>,
240}
241
242fn parse_recovered_tree(
243 parser: &mut tree_sitter::Parser,
244 source: Arc<Source>,
245 old_tree: Option<&tree_sitter::Tree>,
246) -> Result<ParsedTree, ParseError> {
247 let source_text = source.text();
248 let (view, aliases, diagnostics) = renamed_source_recovering(source_text)?;
249 let parse_view = view.into_owned();
250 let tree = parser
251 .parse(parse_view.as_bytes(), old_tree)
252 .ok_or(ParseError::Cancelled)?;
253 if let Some(error) = first_error(tree.root_node()) {
254 return Err(ParseError::InvalidSyntax(Span::ranged(
255 Arc::clone(&source),
256 error.start_byte().min(source_text.len())..error.end_byte().min(source_text.len()),
257 )));
258 }
259 let syntax =
260 Lowerer::new(Arc::clone(&source), source_text, aliases).source_file(tree.root_node())?;
261 Ok(ParsedTree {
262 parse_view,
263 tree,
264 syntax,
265 diagnostics,
266 })
267}
268
269fn input_edit_between(old: &str, new: &str) -> tree_sitter::InputEdit {
270 let mut start = old
271 .as_bytes()
272 .iter()
273 .zip(new.as_bytes())
274 .take_while(|(old, new)| old == new)
275 .count();
276 while !old.is_char_boundary(start) || !new.is_char_boundary(start) {
277 start -= 1;
278 }
279
280 let available_suffix = old.len().min(new.len()).saturating_sub(start);
281 let mut suffix = old
282 .as_bytes()
283 .iter()
284 .rev()
285 .zip(new.as_bytes().iter().rev())
286 .take(available_suffix)
287 .take_while(|(old, new)| old == new)
288 .count();
289 while !old.is_char_boundary(old.len() - suffix) || !new.is_char_boundary(new.len() - suffix) {
290 suffix -= 1;
291 }
292
293 let old_end = old.len() - suffix;
294 let new_end = new.len() - suffix;
295 tree_sitter::InputEdit {
296 start_byte: start,
297 old_end_byte: old_end,
298 new_end_byte: new_end,
299 start_position: point_at(old, start),
300 old_end_position: point_at(old, old_end),
301 new_end_position: point_at(new, new_end),
302 }
303}
304
305fn point_at(source: &str, offset: usize) -> tree_sitter::Point {
306 let before = &source[..offset];
307 let row = before.bytes().filter(|byte| *byte == b'\n').count();
308 let column = before
309 .as_bytes()
310 .iter()
311 .rposition(|byte| *byte == b'\n')
312 .map_or(before.len(), |newline| before.len() - newline - 1);
313 tree_sitter::Point { row, column }
314}
315
316impl TreeSitterParser {
317 pub fn new() -> Result<Self, ParseError> {
324 let mut parser = tree_sitter::Parser::new();
325 parser
326 .set_language(&tree_sitter_macaulay2::language())
327 .map_err(ParseError::Language)?;
328 Ok(Self { parser })
329 }
330
331 fn parse_source_in(&mut self, source: Arc<Source>) -> Result<SourceFile, ParseError> {
332 let source_text = source.text();
333 let (renamed, aliases) = renamed_source(source_text)?;
334 let tree = self
335 .parser
336 .parse(renamed.as_bytes(), None)
337 .ok_or(ParseError::Cancelled)?;
338 if let Some(error) = first_error(tree.root_node()) {
339 return Err(ParseError::InvalidSyntax(Span::ranged(
340 Arc::clone(&source),
341 error.start_byte()..error.end_byte(),
342 )));
343 }
344 Lowerer::new(Arc::clone(&source), source_text, aliases).source_file(tree.root_node())
345 }
346
347 pub fn parse_recovering(
357 &mut self,
358 source: &str,
359 ) -> Result<Recovered<SourceFile, LexError>, ParseError> {
360 let source = Source::new(source);
361 let source_text = source.text();
362 let (renamed, aliases, diagnostics) = renamed_source_recovering(source_text)?;
363 let tree = self
364 .parser
365 .parse(renamed.as_bytes(), None)
366 .ok_or(ParseError::Cancelled)?;
367 if let Some(error) = first_error(tree.root_node()) {
368 return Err(ParseError::InvalidSyntax(Span::ranged(
369 Arc::clone(&source),
370 error.start_byte().min(source_text.len())..error.end_byte().min(source_text.len()),
371 )));
372 }
373 let syntax = Lowerer::new(Arc::clone(&source), source_text, aliases)
374 .source_file(tree.root_node())?;
375 Ok(Recovered::new(syntax, diagnostics))
376 }
377}
378
379impl Parser for TreeSitterParser {
380 type Error = ParseError;
381
382 fn parse_cells(&mut self, cells: CellStream) -> Result<SourceFile, Self::Error> {
383 let (cell_comments, comments) = cells.comment_ownership();
384 let mut source_file = match cells.complete_source() {
385 Some(source) => self.parse_source_in(source),
386 None => self.parse_source_in(Source::new(cells.to_string())),
387 }?;
388 if source_file.cells.len() == cell_comments.len() {
389 for (cell, comments) in source_file.cells.iter_mut().zip(cell_comments) {
390 cell.comments = comments;
391 }
392 source_file.comments = comments;
393 } else {
394 source_file.comments = comments;
395 for comments in cell_comments {
396 source_file.comments.append(comments);
397 }
398 }
399 Ok(source_file)
400 }
401}
402
403pub fn parse_file(source: &str) -> Result<SourceFile, ParseError> {
409 let mut parser = TreeSitterParser::new()?;
410 let cells = lex_str(source)?.to_cell_stream()?;
411 parser.parse_cells(cells)
412}
413
414pub fn parse_file_recovering(source: &str) -> Result<Recovered<SourceFile, LexError>, ParseError> {
421 TreeSitterParser::new()?.parse_recovering(source)
422}
423
424pub fn parse_tokens(tokens: &TokenStream) -> Result<SourceFile, ParseError> {
431 let cells = tokens.to_cell_stream()?;
432 TreeSitterParser::new()?.parse_cells(cells)
433}
434
435fn first_error(root: tree_sitter::Node<'_>) -> Option<tree_sitter::Node<'_>> {
436 let mut pending = vec![root];
437 while let Some(node) = pending.pop() {
438 if node.is_error() || node.is_missing() {
439 return Some(node);
440 }
441 pending.extend((0..node.child_count()).rev().filter_map(|index| {
442 node.child(u32::try_from(index).expect("Tree-sitter child count fits u32"))
443 }));
444 }
445 None
446}
447
448struct Lowerer<'source> {
449 source: &'source [u8],
450 source_span: Span,
451 aliases: Vec<CoreAlias>,
452}
453
454impl<'source> Lowerer<'source> {
455 fn new(source_owner: Arc<Source>, source: &'source str, aliases: Vec<CoreAlias>) -> Self {
456 Self {
457 source: source.as_bytes(),
458 source_span: Span::ranged(source_owner, 0..source.len()),
459 aliases,
460 }
461 }
462
463 fn source_file(&self, root: tree_sitter::Node<'_>) -> Result<SourceFile, ParseError> {
464 let mut cells = Vec::new();
465 let raw_cells = self.semantic_children(root);
466 for (index, child) in raw_cells.iter().copied().enumerate() {
467 match child.kind() {
468 "cell" | "muted" => {
469 let next = raw_cells.get(index + 1).copied();
470 cells.push(self.cell(child, self.eoc_offset(child, next))?);
471 }
472 kind => return Err(self.unsupported(kind, child)),
473 }
474 }
475 let eof_offset = cells
476 .last()
477 .and_then(|cell| cell.eoc.span().start())
478 .unwrap_or(self.source.len());
479 Ok(SourceFile::new(
480 cells,
481 EOF::new("", self.source_span.at(eof_offset)),
482 ))
483 }
484
485 fn cell(&self, node: tree_sitter::Node<'_>, eoc_offset: usize) -> Result<Cell, ParseError> {
486 let (content, semicolon) = if node.kind() == "muted" {
487 let semicolon = self.required_kind(node, ";")?;
488 (
489 self.expr_pack(self.children(node))?,
490 Some(self.migrate(semicolon)?),
491 )
492 } else {
493 let child = self.only_semantic_child(node)?;
494 let pack = if child.kind() == "naked_sequence" {
495 self.expr_pack(self.children(child))?
496 } else {
497 ExprPack::new(Punctuated::from_single(Component::Expr(Box::new(
498 self.expr(child)?,
499 ))))
500 };
501 (pack, None)
502 };
503 Ok(Cell::new(
504 content,
505 semicolon,
506 EOC::new("", self.source_span.at(eoc_offset)),
507 ))
508 }
509
510 fn eoc_offset(
511 &self,
512 _node: tree_sitter::Node<'_>,
513 next: Option<tree_sitter::Node<'_>>,
514 ) -> usize {
515 next.map_or(self.source.len(), |next| next.start_byte())
516 .min(self.source.len())
517 }
518
519 fn expr_pack(&self, nodes: Vec<tree_sitter::Node<'_>>) -> Result<ExprPack, ParseError> {
520 let pack_span = nodes
521 .iter()
522 .map(|node| self.span(*node))
523 .reduce(|left, right| {
524 left.join(right)
525 .expect("Tree-sitter nodes share one source snapshot")
526 })
527 .unwrap_or_else(|| Span::unlocated(Arc::clone(self.source_span.source())));
528 let mut values = Vec::new();
529 let mut commas = Vec::new();
530 for node in nodes.into_iter().filter(|node| !node.is_extra()) {
531 match node.kind() {
532 "," => commas.push(self.migrate::<Token![,]>(node)?),
533 "empty_component" => values.push(Component::Empty(Empty::new("", self.span(node)))),
534 ";" | "(" | ")" | "[" | "]" | "{" | "}" | "<|" | "|>" | "muted" => {}
535 _ if node.is_named() => values.push(Component::Expr(Box::new(self.expr(node)?))),
536 _ => {}
537 }
538 }
539 let mut values = values.into_iter();
540 let Some(first) = values.next() else {
541 return Err(self.unsupported_span("empty expression pack", pack_span));
542 };
543 let value_count = values.len() + 1;
544 let comma_count = commas.len();
545 if value_count != comma_count + 1 {
546 return Err(self.unsupported_span("invalid expression pack", pack_span));
547 }
548 let rest = commas
549 .into_iter()
550 .zip(values)
551 .collect::<Vec<(Token![,], Component)>>();
552 Ok(ExprPack::new(Punctuated::new(first, rest)))
553 }
554
555 fn expr(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
556 match node.kind() {
557 "symbol" => Ok(self.migrate::<Symbol>(node)?.into()),
558 "integer_literal" if self.text(node).contains('p') => {
559 Ok(FloatLiteral::new(self.text(node), self.span(node)).into())
560 }
561 "integer_literal" => Ok(self.migrate::<IntegerLiteral>(node)?.into()),
562 "float_literal" => Ok(self.migrate::<FloatLiteral>(node)?.into()),
563 "string_literal" => self.string_literal(node),
564 "raw_string_literal" => self.raw_string_literal(node),
565 "array" | "list" | "angle_bar_list" | "sequence" | "parenthesized_expression" => {
566 self.collection(node)
567 }
568 "binary_expression" => self.binary_expr(node),
569 "prefix_expression" => self.prefix_expr(node),
570 "postfix_expression" => self.postfix_expr(node),
571 "lambda_expression" => self.lambda_expression(node),
572 "assignment"
573 | "local_assignment"
574 | "binary_assignment"
575 | "prefix_assignment"
576 | "postfix_assignment"
577 | "binary_installation"
578 | "prefix_installation"
579 | "postfix_installation"
580 | "structured_binding"
581 | "local_structured_binding" => self.assignment(node),
582 "evaluated_assignment" => Ok(EvaluatedAssignment::new(
583 self.expr(self.required_field(node, "left")?)?,
584 self.migrate(self.required_field(node, "operator")?)?,
585 self.expr(self.required_field(node, "right")?)?,
586 )
587 .into()),
588 "option" => Ok(OptionExpression::new(
589 self.expr(self.required_field(node, "left")?)?,
590 self.migrate(self.required_field(node, "operator")?)?,
591 self.expr(self.required_field(node, "right")?)?,
592 )
593 .into()),
594 "if_statement" => self.if_statement(node),
595 "for_loop" => self.for_loop(node),
596 "while_loop" => self.while_loop(node),
597 "try_statement" => self.try_statement(node),
598 "quote_expression" => self.quote_expression(node),
599 "new_statement" => self.new_statement(node),
600 "break_statement" => Ok(BreakExpr::new(
601 self.migrate(self.required_kind(node, "break")?)?,
602 self.first_expression_child(node)
603 .map(|child| self.expr(child))
604 .transpose()?,
605 )
606 .into()),
607 "continue_statement" => Ok(ContinueExpr::new(
608 self.migrate(self.required_kind(node, "continue")?)?,
609 self.first_expression_child(node)
610 .map(|child| self.expr(child))
611 .transpose()?,
612 )
613 .into()),
614 "return_statement" => Ok(ReturnExpr::new(
615 self.migrate(self.required_kind(node, "return")?)?,
616 self.first_expression_child(node)
617 .map(|child| self.expr(child))
618 .transpose()?,
619 )
620 .into()),
621 "catch_statement" => Ok(Catch::new(
622 self.migrate(self.required_kind(node, "catch")?)?,
623 self.expr(self.required_expression_child(node)?)?,
624 )
625 .into()),
626 "throw_statement" => Ok(Throw::new(
627 self.migrate(self.required_kind(node, "throw")?)?,
628 self.expr(self.required_expression_child(node)?)?,
629 )
630 .into()),
631 "trap_statement" => Ok(Trap::new(
632 self.migrate(self.required_kind(node, "trap")?)?,
633 self.expr(self.required_expression_child(node)?)?,
634 )
635 .into()),
636 "debug_clause" => self.debug_clause(node),
637 kind => Err(self.unsupported(kind, node)),
638 }
639 }
640
641 fn collection(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
642 let spans = self.delimiter_spans(node)?;
643 let statements = self
644 .semantic_children(node)
645 .into_iter()
646 .filter(|child| child.kind() == "muted")
647 .map(|child| self.statement(child))
648 .collect::<Result<Vec<_>, _>>()?;
649
650 if node.kind() == "parenthesized_expression" {
651 let value = self
652 .semantic_children(node)
653 .into_iter()
654 .find(|child| child.kind() != "muted")
655 .map(|child| self.expr(child))
656 .transpose()?;
657 let mut holder = Holder::new(statements, value);
658 holder.delimiter = <Delimiter![()] as DelimiterToken>::new(spans);
659 return Ok(holder.into());
660 }
661
662 let has_elements = self.children(node).into_iter().any(|child| {
663 !child.is_extra()
664 && (child.kind() == ","
665 || child.kind() == "empty_component"
666 || (child.is_named() && child.kind() != "muted"))
667 });
668 let elements = has_elements
669 .then(|| self.expr_pack(self.children(node)))
670 .transpose()?;
671 Ok(match node.kind() {
672 "array" => {
673 let mut value = Array::new(statements, elements);
674 value.delimiter = <Delimiter![[]] as DelimiterToken>::new(spans);
675 value.into()
676 }
677 "list" => {
678 let mut value = List::new(statements, elements);
679 value.delimiter = <Delimiter![{}] as DelimiterToken>::new(spans);
680 value.into()
681 }
682 "angle_bar_list" => {
683 let mut value = AngleBarList::new(statements, elements);
684 value.delimiter = <Delimiter![<| |>] as DelimiterToken>::new(spans);
685 value.into()
686 }
687 "sequence" => {
688 let mut value = Sequence::new(statements, elements);
689 value.delimiter = <Delimiter![()] as DelimiterToken>::new(spans);
690 value.into()
691 }
692 kind => return Err(self.unsupported(kind, node)),
693 })
694 }
695
696 fn statement(&self, node: tree_sitter::Node<'_>) -> Result<Statement, ParseError> {
697 Ok(Statement::new(
698 self.expr_pack(self.children(node))?,
699 self.migrate(self.required_kind(node, ";")?)?,
700 ))
701 }
702
703 fn string_literal(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
704 let elements = self
705 .children(node)
706 .into_iter()
707 .filter(|child| child.kind() != "\"")
708 .filter(|child| !child.is_extra())
709 .map(|child| match child.kind() {
710 "escape_sequence" => self.migrate(child).map(StringElement::EscapeSequence),
711 "string_content" => self.migrate(child).map(StringElement::StringContent),
712 _ => Ok(StringElement::StringContent(StringContent::new(
713 self.text(child),
714 self.span(child),
715 ))),
716 })
717 .collect::<Result<Vec<_>, ParseError>>()?;
718 Ok(StringLiteral::new(elements, self.span(node)).into())
719 }
720
721 fn raw_string_literal(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
722 let elements = self
723 .children(node)
724 .into_iter()
725 .filter(|child| child.kind() != "///")
726 .filter(|child| !child.is_extra())
727 .map(|child| match child.kind() {
728 "escape_sequence" => self.migrate(child).map(RawStringElement::EscapeSequence),
729 "raw_string_content" => self.migrate(child).map(RawStringElement::RawStringContent),
730 kind => Err(self.unsupported(kind, child)),
731 })
732 .collect::<Result<Vec<_>, ParseError>>()?;
733 Ok(RawStringLiteral::new(elements, self.span(node)).into())
734 }
735
736 fn binary_expr(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
737 let left = self.expr(self.required_field(node, "left")?)?;
738 let operator = self.required_field(node, "operator")?;
739 let right = self.expr(self.required_field(node, "right")?)?;
740 if operator.kind() == "SPACE" {
741 Ok(AdjacentExpr::new(left, Adj::new("", self.span(operator)), right).into())
742 } else {
743 Ok(BinaryExpr::new(left, self.migrate(operator)?, right).into())
744 }
745 }
746
747 fn prefix_expr(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
748 Ok(PrefixExpr::new(
749 self.migrate(self.required_field(node, "operator")?)?,
750 self.expr(self.required_field(node, "operand")?)?,
751 )
752 .into())
753 }
754
755 fn postfix_expr(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
756 Ok(PostfixExpr::new(
757 self.expr(self.required_field(node, "operand")?)?,
758 self.migrate(self.required_field(node, "operator")?)?,
759 )
760 .into())
761 }
762
763 fn lambda_expression(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
764 let parameter_expr = self.expr(self.required_field(node, "parameters")?)?;
765 let parameters = lambda_parameters(parameter_expr)
766 .ok_or_else(|| self.unsupported("lambda parameters", node))?;
767 Ok(LambdaExpression::new(
768 parameters,
769 self.migrate(self.required_field(node, "operator")?)?,
770 self.expr(self.required_field(node, "body")?)?,
771 )
772 .into())
773 }
774
775 fn assignment(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
776 let right = self.expr(self.required_field(node, "right")?)?;
777 Ok(match node.kind() {
778 "assignment" => GlobalBinding::new(
779 self.migrate(self.required_field(node, "left")?)?,
780 self.migrate(self.required_field(node, "operator")?)?,
781 right,
782 )
783 .into(),
784 "local_assignment" => LocalBinding::new(
785 self.migrate(self.required_field(node, "left")?)?,
786 self.migrate(self.required_field(node, "operator")?)?,
787 right,
788 )
789 .into(),
790 "binary_assignment" | "prefix_assignment" | "postfix_assignment" => {
791 let Expr::OperatorExpr(left) = self.expr(self.required_field(node, "left")?)?
792 else {
793 return Err(self.unsupported("operator assignment target", node));
794 };
795 OperatorAssignment::new(
796 left,
797 self.migrate(self.required_field(node, "operator")?)?,
798 right,
799 )
800 .into()
801 }
802 "binary_installation" | "prefix_installation" | "postfix_installation" => {
803 let Expr::OperatorExpr(left) = self.expr(self.required_field(node, "left")?)?
804 else {
805 return Err(self.unsupported("operator installation target", node));
806 };
807 let (typical_value, function) = installation_value(right);
808 match left {
809 OperatorExpr::AdjacentExpr(application) => MethodInstallation::new(
810 *application.left_operand,
811 *application.right_operand,
812 self.migrate(self.required_field(node, "operator")?)?,
813 typical_value,
814 function,
815 )
816 .into(),
817 domain => OperatorInstallation::new(
818 domain,
819 self.migrate(self.required_field(node, "operator")?)?,
820 typical_value,
821 function,
822 )
823 .into(),
824 }
825 }
826 "structured_binding" | "local_structured_binding" => {
827 let pack_expr = self.expr(self.required_field(node, "binding_pack")?)?;
828 let pack = assignment_pack(pack_expr)
829 .ok_or_else(|| self.unsupported("assignment pack", node))?;
830 if node.kind() == "local_structured_binding" {
831 LocalParallelAssignment::new(
832 pack,
833 self.migrate(self.required_field(node, "operator")?)?,
834 right,
835 )
836 .into()
837 } else {
838 GlobalParallelAssignment::new(
839 pack,
840 self.migrate(self.required_field(node, "operator")?)?,
841 right,
842 )
843 .into()
844 }
845 }
846 kind => return Err(self.unsupported(kind, node)),
847 })
848 }
849
850 fn then_clause(&self, node: tree_sitter::Node<'_>) -> Result<ThenClause, ParseError> {
851 Ok(ThenClause::new(
852 self.migrate(self.required_kind(node, "then")?)?,
853 self.expr(self.required_expression_child(node)?)?,
854 ))
855 }
856
857 fn else_clause(&self, node: tree_sitter::Node<'_>) -> Result<ElseClause, ParseError> {
858 Ok(ElseClause::new(
859 self.migrate(self.required_kind(node, "else")?)?,
860 self.expr(self.required_expression_child(node)?)?,
861 ))
862 }
863
864 fn if_statement(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
865 Ok(IfStatement::new(
866 self.migrate(self.required_kind(node, "if")?)?,
867 self.expr(self.required_field(node, "condition")?)?,
868 self.then_clause(self.required_kind(node, "then_clause")?)?,
869 self.optional_kind(node, "else_clause")
870 .map(|child| self.else_clause(child))
871 .transpose()?,
872 )
873 .into())
874 }
875
876 fn loop_body(&self, node: tree_sitter::Node<'_>) -> Result<LoopBody, ParseError> {
877 let list_step = self
878 .optional_kind(node, "list")
879 .map(|token| {
880 Ok::<_, ParseError>(ListStep::new(
881 self.migrate(token)?,
882 self.expr(self.required_field(node, "listed_value")?)?,
883 ))
884 })
885 .transpose()?;
886 let do_step = self
887 .optional_kind(node, "do")
888 .map(|token| {
889 Ok::<_, ParseError>(DoStep::new(
890 self.migrate(token)?,
891 self.expr(self.required_field(node, "ignored_value")?)?,
892 ))
893 })
894 .transpose()?;
895 Ok(LoopBody::new(list_step, do_step))
896 }
897
898 fn for_loop(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
899 let iteration_domain = self
900 .optional_kind(node, "iteration_range")
901 .map(|range| self.iteration_domain(range))
902 .transpose()?;
903 let when_condition = self
904 .optional_kind(node, "when")
905 .map(|token| {
906 Ok::<_, ParseError>(WhenCondition::new(
907 self.migrate(token)?,
908 self.expr(self.required_field(node, "filter")?)?,
909 ))
910 })
911 .transpose()?;
912 Ok(ForLoop::new(
913 self.migrate(self.required_kind(node, "for")?)?,
914 self.migrate(self.required_field(node, "variable")?)?,
915 iteration_domain,
916 when_condition,
917 self.loop_body(self.required_kind(node, "loop_body")?)?,
918 )
919 .into())
920 }
921
922 fn iteration_domain(&self, node: tree_sitter::Node<'_>) -> Result<IterationDomain, ParseError> {
923 if let Some(token) = self.optional_kind(node, "in") {
924 return Ok(IterIn::new(
925 self.migrate(token)?,
926 self.expr(self.required_field(node, "iterated_collection")?)?,
927 )
928 .into());
929 }
930 let lower_bound = self
931 .optional_kind(node, "from")
932 .map(|token| {
933 Ok::<_, ParseError>(RangeBoundFrom::new(
934 self.migrate(token)?,
935 self.expr(self.required_field(node, "range_start")?)?,
936 ))
937 })
938 .transpose()?;
939 let upper_bound = self
940 .optional_kind(node, "to")
941 .map(|token| {
942 Ok::<_, ParseError>(RangeBoundTo::new(
943 self.migrate(token)?,
944 self.expr(self.required_field(node, "range_end")?)?,
945 ))
946 })
947 .transpose()?;
948 Ok(IterRange::new(lower_bound, upper_bound).into())
949 }
950
951 fn while_loop(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
952 Ok(WhileLoop::new(
953 self.migrate(self.required_kind(node, "while")?)?,
954 self.expr(self.required_field(node, "condition")?)?,
955 self.loop_body(self.required_kind(node, "loop_body")?)?,
956 )
957 .into())
958 }
959
960 fn new_statement(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
961 let mut installation = None;
962 let class =
963 self.new_statement_element(self.required_field(node, "class")?, &mut installation)?;
964 let parent_class = self
965 .optional_kind(node, "of")
966 .map(|token| {
967 Ok::<_, ParseError>(OfClass::new(
968 self.migrate(token)?,
969 self.new_statement_element(
970 self.required_field(node, "parent")?,
971 &mut installation,
972 )?,
973 ))
974 })
975 .transpose()?;
976 let instance = self
977 .optional_kind(node, "from")
978 .map(|token| {
979 Ok::<_, ParseError>(FromInstance::new(
980 self.migrate(token)?,
981 self.new_statement_element(
982 self.required_field(node, "instance")?,
983 &mut installation,
984 )?,
985 ))
986 })
987 .transpose()?;
988 let statement = NewStatement::new(
989 self.migrate(self.required_kind(node, "new")?)?,
990 class,
991 parent_class,
992 instance,
993 );
994 Ok(match installation {
995 Some((operator, function)) => {
996 NewInstallation::new(statement, operator, function).into()
997 }
998 None => statement.into(),
999 })
1000 }
1001
1002 fn new_statement_element(
1003 &self,
1004 node: tree_sitter::Node<'_>,
1005 installation: &mut Option<(Token![:=], Expr)>,
1006 ) -> Result<Expr, ParseError> {
1007 match node.kind() {
1008 "assignment" => return Err(self.unsupported("`new` assignment with `=`", node)),
1009 "local_assignment" => {}
1010 _ => return self.expr(node),
1011 }
1012 *installation = Some((
1013 self.migrate(self.required_field(node, "operator")?)?,
1014 self.expr(self.required_field(node, "right")?)?,
1015 ));
1016 self.expr(self.required_field(node, "left")?)
1017 }
1018
1019 fn try_statement(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
1020 let value = self
1021 .semantic_children(node)
1022 .into_iter()
1023 .find(|child| {
1024 child.kind() != "then_clause"
1025 && child.kind() != "else_clause"
1026 && child.kind() != "except_clause"
1027 })
1028 .ok_or_else(|| self.unsupported("try value", node))?;
1029 let on_success = self
1030 .optional_kind(node, "then_clause")
1031 .map(|child| self.then_clause(child))
1032 .transpose()?;
1033 let fallback = self
1034 .child_by_field(node, "fallback")
1035 .map(|child| match child.kind() {
1036 "else_clause" => self.else_clause(child).map(TryFallback::ElseClause),
1037 "except_clause" => self.except_do(child).map(TryFallback::ExceptDo),
1038 kind => Err(self.unsupported(kind, child)),
1039 })
1040 .transpose()?;
1041 Ok(TryStatement::new(
1042 self.migrate(self.required_kind(node, "try")?)?,
1043 self.expr(value)?,
1044 on_success,
1045 fallback,
1046 )
1047 .into())
1048 }
1049
1050 fn except_do(&self, node: tree_sitter::Node<'_>) -> Result<ExceptDo, ParseError> {
1051 Ok(ExceptDo::new(
1052 self.migrate(self.required_kind(node, "except")?)?,
1053 self.migrate(self.required_field(node, "exception")?)?,
1054 self.migrate(self.required_kind(node, "do")?)?,
1055 self.expr(self.required_expression_child(node)?)?,
1056 ))
1057 }
1058
1059 fn quote_expression(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
1060 let token = self
1061 .children(node)
1062 .into_iter()
1063 .find(|child| {
1064 matches!(
1065 child.kind(),
1066 "symbol" | "local" | "global" | "threadVariable" | "threadLocal"
1067 ) && self.child_by_field(node, "token") != Some(*child)
1068 })
1069 .ok_or_else(|| self.unsupported("quote specifier", node))?;
1070 let specifier = match token.kind() {
1071 "symbol" => QuoteSpecifier::Symbol(self.migrate(token)?),
1072 "local" => QuoteSpecifier::Local(self.migrate(token)?),
1073 "global" => QuoteSpecifier::Global(self.migrate(token)?),
1074 "threadVariable" => QuoteSpecifier::ThreadVariable(self.migrate(token)?),
1075 "threadLocal" => QuoteSpecifier::ThreadLocal(self.migrate(token)?),
1076 kind => return Err(self.unsupported(kind, token)),
1077 };
1078 let quoted = self.required_field(node, "token")?;
1079 Ok(
1080 QuoteExpression::new(specifier, Symbol::new(self.text(quoted), self.span(quoted)))
1081 .into(),
1082 )
1083 }
1084
1085 fn debug_clause(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
1086 let keyword = self.required_field(node, "keyword")?;
1087 let value = self
1088 .first_expression_child(node)
1089 .map(|child| self.expr(child))
1090 .transpose()?;
1091 Ok(match keyword.kind() {
1092 "elapsedTime" => ProfilingExpr::new(
1093 ProfilingModifier::ElapsedTime(self.migrate(keyword)?),
1094 value.ok_or_else(|| self.unsupported("profiling operand", node))?,
1095 )
1096 .into(),
1097 "elapsedTiming" => ProfilingExpr::new(
1098 ProfilingModifier::ElapsedTiming(self.migrate(keyword)?),
1099 value.ok_or_else(|| self.unsupported("profiling operand", node))?,
1100 )
1101 .into(),
1102 "profile" => ProfilingExpr::new(
1103 ProfilingModifier::Profile(self.migrate(keyword)?),
1104 value.ok_or_else(|| self.unsupported("profiling operand", node))?,
1105 )
1106 .into(),
1107 "time" => ProfilingExpr::new(
1108 ProfilingModifier::Time(self.migrate(keyword)?),
1109 value.ok_or_else(|| self.unsupported("profiling operand", node))?,
1110 )
1111 .into(),
1112 "timing" => ProfilingExpr::new(
1113 ProfilingModifier::Timing(self.migrate(keyword)?),
1114 value.ok_or_else(|| self.unsupported("profiling operand", node))?,
1115 )
1116 .into(),
1117 "TEST" => DebugExpr::new(DebugKeyword::Test(self.migrate(keyword)?), value).into(),
1118 "step" => DebugExpr::new(DebugKeyword::Step(self.migrate(keyword)?), value).into(),
1119 "finish" => DebugExpr::new(DebugKeyword::Finish(self.migrate(keyword)?), value).into(),
1120 "shield" => DebugExpr::new(DebugKeyword::Shield(self.migrate(keyword)?), value).into(),
1121 "breakpoint" => {
1122 DebugExpr::new(DebugKeyword::Breakpoint(self.migrate(keyword)?), value).into()
1123 }
1124 kind => return Err(self.unsupported(kind, keyword)),
1125 })
1126 }
1127
1128 fn migrate<T>(&self, node: tree_sitter::Node<'_>) -> Result<T, ParseError>
1129 where
1130 for<'tree> T: Migrate<TreeSitterNode<'tree, 'source>>,
1131 {
1132 T::migrate(TreeSitterNode::with_span(
1133 node,
1134 self.source,
1135 self.span(node),
1136 ))
1137 .map_err(Into::into)
1138 }
1139
1140 fn delimiter_spans(&self, node: tree_sitter::Node<'_>) -> Result<DoubleSpan, ParseError> {
1141 let kind = match node.kind() {
1142 "parenthesized_expression" | "sequence" => DelimiterKind::Parenthesis,
1143 "array" => DelimiterKind::Bracket,
1144 "list" => DelimiterKind::Brace,
1145 "angle_bar_list" => DelimiterKind::AngleBar,
1146 other => return Err(self.unsupported(other, node)),
1147 };
1148 let opening = self.span(self.required_kind(node, kind.opening())?);
1149 let closing = self.required_kind(node, kind.closing())?;
1150 if closing.start_byte() >= self.source.len() {
1151 Ok(DoubleSpan::unclosed(opening))
1152 } else {
1153 Ok(DoubleSpan::new(opening, self.span(closing)))
1154 }
1155 }
1156
1157 fn children<'tree>(&self, node: tree_sitter::Node<'tree>) -> Vec<tree_sitter::Node<'tree>> {
1158 (0..node.child_count())
1159 .filter_map(|index| node.child(u32::try_from(index).expect("child count fits u32")))
1160 .collect()
1161 }
1162
1163 fn semantic_children<'tree>(
1164 &self,
1165 node: tree_sitter::Node<'tree>,
1166 ) -> Vec<tree_sitter::Node<'tree>> {
1167 self.children(node)
1168 .into_iter()
1169 .filter(|child| child.is_named() && !child.is_extra())
1170 .collect()
1171 }
1172
1173 fn only_semantic_child<'tree>(
1174 &self,
1175 node: tree_sitter::Node<'tree>,
1176 ) -> Result<tree_sitter::Node<'tree>, ParseError> {
1177 let children = self.semantic_children(node);
1178 match children.as_slice() {
1179 [child] => Ok(*child),
1180 _ => Err(self.unsupported("cell contents", node)),
1181 }
1182 }
1183
1184 fn first_expression_child<'tree>(
1185 &self,
1186 node: tree_sitter::Node<'tree>,
1187 ) -> Option<tree_sitter::Node<'tree>> {
1188 self.semantic_children(node).into_iter().find(|child| {
1189 !matches!(
1190 child.kind(),
1191 "then_clause" | "else_clause" | "except_clause" | "iteration_range" | "loop_body"
1192 )
1193 })
1194 }
1195
1196 fn required_expression_child<'tree>(
1197 &self,
1198 node: tree_sitter::Node<'tree>,
1199 ) -> Result<tree_sitter::Node<'tree>, ParseError> {
1200 self.first_expression_child(node)
1201 .ok_or_else(|| self.unsupported("expression child", node))
1202 }
1203
1204 fn child_by_field<'tree>(
1205 &self,
1206 node: tree_sitter::Node<'tree>,
1207 field: &str,
1208 ) -> Option<tree_sitter::Node<'tree>> {
1209 node.child_by_field_name(field)
1210 }
1211
1212 fn required_field<'tree>(
1213 &self,
1214 node: tree_sitter::Node<'tree>,
1215 field: &str,
1216 ) -> Result<tree_sitter::Node<'tree>, ParseError> {
1217 self.child_by_field(node, field)
1218 .ok_or_else(|| self.unsupported(field, node))
1219 }
1220
1221 fn optional_kind<'tree>(
1222 &self,
1223 node: tree_sitter::Node<'tree>,
1224 kind: &str,
1225 ) -> Option<tree_sitter::Node<'tree>> {
1226 self.children(node)
1227 .into_iter()
1228 .find(|child| !child.is_extra() && child.kind() == kind)
1229 }
1230
1231 fn required_kind<'tree>(
1232 &self,
1233 node: tree_sitter::Node<'tree>,
1234 kind: &str,
1235 ) -> Result<tree_sitter::Node<'tree>, ParseError> {
1236 self.optional_kind(node, kind)
1237 .ok_or_else(|| self.unsupported(kind, node))
1238 }
1239
1240 fn text(&self, node: tree_sitter::Node<'_>) -> Cow<'_, str> {
1241 let range = self
1242 .span(node)
1243 .bounds()
1244 .map_or_else(|| node.byte_range(), |(start, end)| start..end);
1245 String::from_utf8_lossy(&self.source[range])
1246 }
1247
1248 fn span(&self, node: tree_sitter::Node<'_>) -> Span {
1249 let range = node.byte_range();
1250 self.aliases
1251 .iter()
1252 .find(|alias| alias.bare == range)
1253 .map_or_else(
1254 || {
1255 self.source_span.subspan(
1256 node.start_byte().min(self.source.len()),
1257 node.end_byte().min(self.source.len()),
1258 )
1259 },
1260 |alias| self.source_span.subspan(alias.full.start, alias.full.end),
1261 )
1262 }
1263
1264 fn unsupported(&self, kind: impl Into<String>, node: tree_sitter::Node<'_>) -> ParseError {
1265 self.unsupported_span(kind, self.span(node))
1266 }
1267
1268 fn unsupported_span(&self, kind: impl Into<String>, span: Span) -> ParseError {
1269 ParseError::UnsupportedNode {
1270 kind: kind.into(),
1271 span,
1272 }
1273 }
1274}
1275
1276#[derive(Clone)]
1277struct CoreAlias {
1278 full: Range<usize>,
1279 bare: Range<usize>,
1280}
1281
1282fn renamed_source(source: &str) -> Result<(Cow<'_, str>, Vec<CoreAlias>), LexError> {
1283 let tokens = lex_str(source)?;
1284 let mut aliases = Vec::new();
1285 collect_core_aliases(&tokens, &mut aliases);
1286 if aliases.is_empty() {
1287 return Ok((Cow::Borrowed(source), aliases));
1288 }
1289
1290 let mut renamed = source.as_bytes().to_vec();
1291 for alias in &aliases {
1292 renamed[alias.full.start..alias.bare.start].fill(b' ');
1293 }
1294 Ok((
1295 Cow::Owned(String::from_utf8(renamed).expect("replacing ASCII bytes preserves UTF-8")),
1296 aliases,
1297 ))
1298}
1299
1300type RecoveredSource<'source> = (Cow<'source, str>, Vec<CoreAlias>, Vec<LexError>);
1301
1302fn renamed_source_recovering(source: &str) -> Result<RecoveredSource<'_>, LexError> {
1303 let recovered = lex_str_recovering(source)?;
1304 let (tokens, diagnostics) = recovered.into_parts();
1305 let mut aliases = Vec::new();
1306 collect_core_aliases(&tokens, &mut aliases);
1307 let mut missing = Vec::new();
1308 collect_missing_closers(&tokens, &mut missing);
1309
1310 if aliases.is_empty() && missing.is_empty() {
1311 return Ok((Cow::Borrowed(source), aliases, diagnostics));
1312 }
1313
1314 let mut renamed = source.as_bytes().to_vec();
1315 for alias in &aliases {
1316 renamed[alias.full.start..alias.bare.start].fill(b' ');
1317 }
1318 for kind in missing {
1319 renamed.extend_from_slice(kind.closing().as_bytes());
1320 }
1321 Ok((
1322 Cow::Owned(String::from_utf8(renamed).expect("ASCII recovery preserves UTF-8")),
1323 aliases,
1324 diagnostics,
1325 ))
1326}
1327
1328fn collect_missing_closers(tokens: &TokenStream, missing: &mut Vec<DelimiterKind>) {
1329 for token in tokens.iter() {
1330 let TokenTree::Group(group) = token else {
1331 continue;
1332 };
1333 collect_missing_closers(group.stream(), missing);
1334 if !group.delimiter().is_closed() {
1335 missing.push(group.delim_kind());
1336 }
1337 }
1338}
1339
1340fn collect_core_aliases(tokens: &TokenStream, aliases: &mut Vec<CoreAlias>) {
1341 for token in tokens.iter() {
1342 match token {
1343 TokenTree::Group(group) => collect_core_aliases(group.stream(), aliases),
1344 TokenTree::Ident(identifier) => {
1345 let spelling = identifier.text();
1346 let bare = crate::lexer::canonical_word_spelling(spelling);
1347 if bare == spelling {
1348 continue;
1349 }
1350 let Some((start, end)) = identifier.expect_span().bounds() else {
1351 continue;
1352 };
1353 aliases.push(CoreAlias {
1354 full: start..end,
1355 bare: end - bare.len()..end,
1356 });
1357 }
1358 TokenTree::Literal(_) | TokenTree::Punct(_) => {}
1359 }
1360 }
1361}
1362
1363#[derive(Clone)]
1364pub struct TreeSitterNode<'tree, 'source> {
1366 node: tree_sitter::Node<'tree>,
1367 source: &'source [u8],
1368 span: Option<Span>,
1369}
1370
1371impl<'tree, 'source> TreeSitterNode<'tree, 'source> {
1372 pub fn new(node: tree_sitter::Node<'tree>, source: &'source [u8]) -> Self {
1374 Self {
1375 node,
1376 source,
1377 span: None,
1378 }
1379 }
1380
1381 fn with_span(node: tree_sitter::Node<'tree>, source: &'source [u8], span: Span) -> Self {
1382 Self {
1383 node,
1384 source,
1385 span: Some(span),
1386 }
1387 }
1388}
1389
1390impl ExternalCstNode for TreeSitterNode<'_, '_> {
1391 type Children<'syntax>
1392 = IntoIter<ExternalCstChild<Self>>
1393 where
1394 Self: 'syntax;
1395
1396 fn identity(&self) -> CSTNodeClassLabel<'_> {
1397 CSTNodeClassLabel::new(self.node.kind(), self.node.is_named())
1398 }
1399
1400 fn children(&self) -> Self::Children<'_> {
1401 let parent = self.node;
1402 (0..parent.child_count())
1403 .filter_map(|index| {
1404 let index = u32::try_from(index).expect("Tree-sitter child count fits u32");
1405 parent.child(index).map(|node| ExternalCstChild {
1406 field: parent.field_name_for_child(index),
1407 node: Self::new(node, self.source),
1408 })
1409 })
1410 .collect::<Vec<_>>()
1411 .into_iter()
1412 }
1413
1414 fn text(&self) -> Cow<'_, str> {
1415 let range = self
1416 .span
1417 .as_ref()
1418 .and_then(Span::bounds)
1419 .map_or_else(|| self.node.byte_range(), |(start, end)| start..end);
1420 String::from_utf8_lossy(&self.source[range])
1421 }
1422
1423 fn is_extra(&self) -> bool {
1424 self.node.is_extra()
1425 }
1426}
1427
1428impl Spanned for TreeSitterNode<'_, '_> {
1429 fn try_span(&self) -> Option<Span> {
1430 self.span.clone()
1431 }
1432}