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::{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)]
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,
111}
112
113pub struct RealtimeParser {
121 parser: tree_sitter::Parser,
123 source: Arc<Source>,
125 parse_view: String,
127 tree: tree_sitter::Tree,
129 syntax: SourceFile,
131 diagnostics: Vec<LexError>,
133 changed_ranges: Vec<Span>,
135}
136
137impl RealtimeParser {
138 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 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 pub fn source(&self) -> &str {
219 self.source.text()
220 }
221
222 pub fn syntax(&self) -> &SourceFile {
224 &self.syntax
225 }
226
227 pub fn diagnostics(&self) -> &[LexError] {
229 &self.diagnostics
230 }
231
232 pub fn changed_ranges(&self) -> &[Span] {
234 &self.changed_ranges
235 }
236
237 pub fn into_syntax(self) -> SourceFile {
239 self.syntax
240 }
241}
242
243struct ParsedTree {
245 parse_view: String,
247 tree: tree_sitter::Tree,
249 syntax: SourceFile,
251 diagnostics: Vec<LexError>,
253}
254
255fn 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
283fn 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
320fn 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 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 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 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
420pub 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
431pub fn parse_file_recovering(source: &str) -> Result<Recovered<SourceFile, LexError>, ParseError> {
438 TreeSitterParser::new()?.parse_recovering(source)
439}
440
441pub fn parse_tokens(tokens: &TokenStream) -> Result<SourceFile, ParseError> {
448 let cells = tokens.to_cell_stream()?;
449 TreeSitterParser::new()?.parse_cells(cells)
450}
451
452fn 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
466struct Lowerer<'source> {
468 source: &'source [u8],
470 source_span: Span,
472 aliases: Vec<CoreAlias>,
474}
475
476enum IterationDomain {
478 Range(Option<RangeBoundFrom>, Option<RangeBoundTo>),
480 In(Token![in], Box<Expr>),
482}
483
484impl<'source> Lowerer<'source> {
485 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 fn unsupported(&self, kind: impl Into<String>, node: tree_sitter::Node<'_>) -> ParseError {
1435 self.unsupported_span(kind, self.span(node))
1436 }
1437
1438 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)]
1448struct CoreAlias {
1450 full: Range<usize>,
1452 bare: Range<usize>,
1454}
1455
1456fn 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
1475type RecoveredSource<'source> = (Cow<'source, str>, Vec<CoreAlias>, Vec<LexError>);
1477
1478fn 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
1505fn 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
1518fn 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)]
1543pub struct TreeSitterNode<'tree, 'source> {
1545 node: tree_sitter::Node<'tree>,
1547 source: &'source [u8],
1549 span: Option<Span>,
1551}
1552
1553impl<'tree, 'source> TreeSitterNode<'tree, 'source> {
1554 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 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}