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(self.required_field(node, "left")?)?;
800 let operator = self.required_field(node, "operator")?;
801 let right = self.expr(self.required_field(node, "right")?)?;
802 if operator.kind() == "SPACE" {
803 Ok(Expr!(Op::Bin::Adj {
804 left_operand: Box::new(left),
805 operator: Adj::new("", self.span(operator)),
806 right_operand: Box::new(right),
807 }))
808 } else {
809 match self.text(operator).as_ref() {
810 spelling if GENERATED_AUGMENTED_OPERATOR_SPELLINGS.contains(&spelling) => {
811 Ok(Expr!(Assign::Augmented {
812 target: Box::new(left),
813 operator: self.migrate(operator)?,
814 value: Box::new(right),
815 }))
816 }
817 "." => Ok(Expr!(Op::Bin::Member::Dot {
818 receiver: Box::new(left),
819 operator: self.migrate(operator)?,
820 member: Box::new(right),
821 })),
822 ".?" => Ok(Expr!(Op::Bin::Member::Optional {
823 receiver: Box::new(left),
824 operator: self.migrate(operator)?,
825 member: Box::new(right),
826 })),
827 "#" => Ok(Expr!(Op::Bin::Index {
828 receiver: Box::new(left),
829 operator: self.migrate(operator)?,
830 index: Box::new(right),
831 })),
832 _ => Ok(Expr!(Op::Bin::Regular {
833 left_operand: Box::new(left),
834 operator: self.migrate(operator)?,
835 right_operand: Box::new(right),
836 })),
837 }
838 }
839 }
840
841 fn prefix_expr(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
843 Ok(Expr!(Op::Prefix {
844 operator: self.migrate(self.required_field(node, "operator")?)?,
845 operand: Box::new(self.expr(self.required_field(node, "operand")?)?),
846 }))
847 }
848
849 fn postfix_expr(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
851 Ok(Expr!(Op::Postfix {
852 operand: Box::new(self.expr(self.required_field(node, "operand")?)?),
853 operator: self.migrate(self.required_field(node, "operator")?)?,
854 }))
855 }
856
857 fn lambda_expression(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
859 let argument_expr = self.expr(self.required_field(node, "parameters")?)?;
860 let arguments = lambda_arguments(argument_expr)
861 .ok_or_else(|| self.unsupported("lambda arguments", node))?;
862 let operator = self.migrate(self.required_field(node, "operator")?)?;
863 let body = Box::new(self.expr(self.required_field(node, "body")?)?);
864 Ok(match arguments {
865 LambdaArguments::Variadic(argument) => Expr!(Lambda::Variadic {
866 argument,
867 operator,
868 body,
869 }),
870 LambdaArguments::List(arguments) => Expr!(Lambda::List {
871 arguments: *arguments,
872 operator,
873 body,
874 }),
875 })
876 }
877
878 fn assignment(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
880 let right = self.expr(self.required_field(node, "right")?)?;
881 Ok(match node.kind() {
882 "assignment" => Expr!(Assign::Simple::Global {
883 variable: self.migrate(self.required_field(node, "left")?)?,
884 operator: self.migrate(self.required_field(node, "operator")?)?,
885 value: Box::new(right),
886 }),
887 "local_assignment" => Expr!(Assign::Simple::Local {
888 variable: self.migrate(self.required_field(node, "left")?)?,
889 operator: self.migrate(self.required_field(node, "operator")?)?,
890 value: Box::new(right),
891 }),
892 "binary_assignment" | "prefix_assignment" | "postfix_assignment" => {
893 let Expr::Op(left) = self.expr(self.required_field(node, "left")?)? else {
894 return Err(self.unsupported("operator assignment target", node));
895 };
896 Expr!(Assign::Op {
897 argument_expr: left,
898 operator: self.migrate(self.required_field(node, "operator")?)?,
899 value_expr: Box::new(right),
900 })
901 }
902 "binary_installation" | "prefix_installation" | "postfix_installation" => {
903 let Expr::Op(left) = self.expr(self.required_field(node, "left")?)? else {
904 return Err(self.unsupported("operator installation target", node));
905 };
906 let (typical_value, function) = installation_value(right);
907 match left {
908 ExprOp::Bin(ExprOpBin::Adj(application)) => Expr!(Assign::Install::Method {
909 method: application.left_operand,
910 operator: application.operator,
911 signature: application.right_operand,
912 assign_op: self.migrate(self.required_field(node, "operator")?)?,
913 typical_value,
914 function: Box::new(function),
915 }),
916 domain_expr => Expr!(Assign::Install::Op {
917 domain_expr,
918 assign_op: self.migrate(self.required_field(node, "operator")?)?,
919 typical_value,
920 function: Box::new(function),
921 }),
922 }
923 }
924 "structured_binding" | "local_structured_binding" => {
925 let list_expr = self.expr(self.required_field(node, "binding_pack")?)?;
926 let argument_list = assignment_list(list_expr)
927 .ok_or_else(|| self.unsupported("assignment argument list", node))?;
928 if node.kind() == "local_structured_binding" {
929 Expr!(Assign::Parallel::Local {
930 argument_list: Box::new(argument_list),
931 operator: self.migrate(self.required_field(node, "operator")?)?,
932 value: Box::new(right),
933 })
934 } else {
935 Expr!(Assign::Parallel::Global {
936 argument_list: Box::new(argument_list),
937 operator: self.migrate(self.required_field(node, "operator")?)?,
938 value: Box::new(right),
939 })
940 }
941 }
942 kind => return Err(self.unsupported(kind, node)),
943 })
944 }
945
946 fn then_clause(&self, node: tree_sitter::Node<'_>) -> Result<ThenClause, ParseError> {
948 Ok(ThenClause::new(
949 self.migrate(self.required_kind(node, "then")?)?,
950 Box::new(self.expr(self.required_expression_child(node)?)?),
951 ))
952 }
953
954 fn else_clause(&self, node: tree_sitter::Node<'_>) -> Result<ElseClause, ParseError> {
956 Ok(ElseClause::new(
957 self.migrate(self.required_kind(node, "else")?)?,
958 Box::new(self.expr(self.required_expression_child(node)?)?),
959 ))
960 }
961
962 fn if_statement(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
964 Ok(Expr!(If {
965 if_token: self.migrate(self.required_kind(node, "if")?)?,
966 condition: Box::new(self.expr(self.required_field(node, "condition")?)?),
967 then_clause: self.then_clause(self.required_kind(node, "then_clause")?)?,
968 else_clause: self
969 .optional_kind(node, "else_clause")
970 .map(|child| self.else_clause(child))
971 .transpose()?,
972 }))
973 }
974
975 fn loop_body(&self, node: tree_sitter::Node<'_>) -> Result<LoopBody, ParseError> {
977 let list_step = self
978 .optional_kind(node, "list")
979 .map(|token| {
980 Ok::<_, ParseError>(ListStep::new(
981 self.migrate(token)?,
982 Box::new(self.expr(self.required_field(node, "listed_value")?)?),
983 ))
984 })
985 .transpose()?;
986 let do_step = self
987 .optional_kind(node, "do")
988 .map(|token| {
989 Ok::<_, ParseError>(DoStep::new(
990 self.migrate(token)?,
991 Box::new(self.expr(self.required_field(node, "ignored_value")?)?),
992 ))
993 })
994 .transpose()?;
995 Ok(LoopBody::new(list_step, do_step))
996 }
997
998 fn for_loop(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
1000 let iteration_domain = self
1001 .optional_kind(node, "iteration_range")
1002 .map(|range| self.iteration_domain(range))
1003 .transpose()?;
1004 let when_condition = self
1005 .optional_kind(node, "when")
1006 .map(|token| {
1007 Ok::<_, ParseError>(WhenCondition::new(
1008 self.migrate(token)?,
1009 Box::new(self.expr(self.required_field(node, "filter")?)?),
1010 ))
1011 })
1012 .transpose()?;
1013 let for_token = self.migrate(self.required_kind(node, "for")?)?;
1014 let variable = self.migrate(self.required_field(node, "variable")?)?;
1015 let body = self.loop_body(self.required_kind(node, "loop_body")?)?;
1016 Ok(match iteration_domain {
1017 None => Expr!(For::Bare {
1018 for_token,
1019 variable,
1020 condition: when_condition,
1021 body,
1022 }),
1023 Some(IterationDomain::Range(lower_bound, upper_bound)) => Expr!(For::Range {
1024 for_token,
1025 variable,
1026 lower_bound,
1027 upper_bound,
1028 condition: when_condition,
1029 body,
1030 }),
1031 Some(IterationDomain::In(in_token, collection)) => Expr!(For::In {
1032 for_token,
1033 variable,
1034 in_token,
1035 collection,
1036 condition: when_condition,
1037 body,
1038 }),
1039 })
1040 }
1041
1042 fn iteration_domain(&self, node: tree_sitter::Node<'_>) -> Result<IterationDomain, ParseError> {
1044 if let Some(token) = self.optional_kind(node, "in") {
1045 return Ok(IterationDomain::In(
1046 self.migrate(token)?,
1047 Box::new(self.expr(self.required_field(node, "iterated_collection")?)?),
1048 ));
1049 }
1050 let lower_bound = self
1051 .optional_kind(node, "from")
1052 .map(|token| {
1053 Ok::<_, ParseError>(RangeBoundFrom::new(
1054 self.migrate(token)?,
1055 Box::new(self.expr(self.required_field(node, "range_start")?)?),
1056 ))
1057 })
1058 .transpose()?;
1059 let upper_bound = self
1060 .optional_kind(node, "to")
1061 .map(|token| {
1062 Ok::<_, ParseError>(RangeBoundTo::new(
1063 self.migrate(token)?,
1064 Box::new(self.expr(self.required_field(node, "range_end")?)?),
1065 ))
1066 })
1067 .transpose()?;
1068 Ok(IterationDomain::Range(lower_bound, upper_bound))
1069 }
1070
1071 fn while_loop(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
1073 Ok(Expr!(While {
1074 while_token: self.migrate(self.required_kind(node, "while")?)?,
1075 condition: Box::new(self.expr(self.required_field(node, "condition")?)?),
1076 body: self.loop_body(self.required_kind(node, "loop_body")?)?,
1077 }))
1078 }
1079
1080 fn new_statement(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
1082 let mut installation = None;
1083 let class =
1084 self.new_statement_element(self.required_field(node, "class")?, &mut installation)?;
1085 let parent_class = self
1086 .optional_kind(node, "of")
1087 .map(|token| {
1088 Ok::<_, ParseError>(OfClass::new(
1089 self.migrate(token)?,
1090 Box::new(self.new_statement_element(
1091 self.required_field(node, "parent")?,
1092 &mut installation,
1093 )?),
1094 ))
1095 })
1096 .transpose()?;
1097 let instance = self
1098 .optional_kind(node, "from")
1099 .map(|token| {
1100 Ok::<_, ParseError>(FromInstance::new(
1101 self.migrate(token)?,
1102 Box::new(self.new_statement_element(
1103 self.required_field(node, "instance")?,
1104 &mut installation,
1105 )?),
1106 ))
1107 })
1108 .transpose()?;
1109 let statement = Expr!(New {
1110 new_token: self.migrate(self.required_kind(node, "new")?)?,
1111 class: Box::new(class),
1112 parent_class,
1113 instance,
1114 });
1115 Ok(match installation {
1116 Some((operator, function)) => {
1117 let Expr::New(new_statement) = statement else {
1118 unreachable!("the constructor selected the new-statement specialization")
1119 };
1120 Expr!(Assign::Install::New {
1121 new_statement,
1122 operator,
1123 function: Box::new(function),
1124 })
1125 }
1126 None => statement,
1127 })
1128 }
1129
1130 fn new_statement_element(
1132 &self,
1133 node: tree_sitter::Node<'_>,
1134 installation: &mut Option<(Token![:=], Expr)>,
1135 ) -> Result<Expr, ParseError> {
1136 match node.kind() {
1137 "assignment" => return Err(self.unsupported("`new` assignment with `=`", node)),
1138 "local_assignment" => {}
1139 _ => return self.expr(node),
1140 }
1141 *installation = Some((
1142 self.migrate(self.required_field(node, "operator")?)?,
1143 self.expr(self.required_field(node, "right")?)?,
1144 ));
1145 self.expr(self.required_field(node, "left")?)
1146 }
1147
1148 fn try_statement(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
1150 let value = self
1151 .semantic_children(node)
1152 .into_iter()
1153 .find(|child| {
1154 child.kind() != "then_clause"
1155 && child.kind() != "else_clause"
1156 && child.kind() != "except_clause"
1157 })
1158 .ok_or_else(|| self.unsupported("try value", node))?;
1159 let on_success = self
1160 .optional_kind(node, "then_clause")
1161 .map(|child| self.then_clause(child))
1162 .transpose()?;
1163 let fallback = self
1164 .child_by_field(node, "fallback")
1165 .map(|child| match child.kind() {
1166 "else_clause" => self.else_clause(child).map(TryFallback::Else),
1167 "except_clause" => self.except_do(child),
1168 kind => Err(self.unsupported(kind, child)),
1169 })
1170 .transpose()?;
1171 Ok(Expr!(Try {
1172 try_token: self.migrate(self.required_kind(node, "try")?)?,
1173 value: Box::new(self.expr(value)?),
1174 on_success,
1175 fallback,
1176 }))
1177 }
1178
1179 fn except_do(&self, node: tree_sitter::Node<'_>) -> Result<TryFallback, ParseError> {
1181 Ok(TryFallback!(Except {
1182 except_token: self.migrate(self.required_kind(node, "except")?)?,
1183 exception: self.migrate(self.required_field(node, "exception")?)?,
1184 do_token: self.migrate(self.required_kind(node, "do")?)?,
1185 value: Box::new(self.expr(self.required_expression_child(node)?)?),
1186 }))
1187 }
1188
1189 fn quote_expression(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
1191 let token = self
1192 .children(node)
1193 .into_iter()
1194 .find(|child| {
1195 matches!(
1196 child.kind(),
1197 "symbol" | "local" | "global" | "threadVariable" | "threadLocal"
1198 ) && self.child_by_field(node, "token") != Some(*child)
1199 })
1200 .ok_or_else(|| self.unsupported("quote specifier", node))?;
1201 let quoted = self.required_field(node, "token")?;
1202 let symbol = Symbol::new(self.text(quoted), self.span(quoted));
1203 Ok(match token.kind() {
1204 "symbol" => Expr!(Quote::Symbol {
1205 specifier: self.migrate(token)?,
1206 symbol,
1207 }),
1208 "local" => Expr!(Quote::Local {
1209 specifier: self.migrate(token)?,
1210 symbol,
1211 }),
1212 "global" => Expr!(Quote::Global {
1213 specifier: self.migrate(token)?,
1214 symbol,
1215 }),
1216 "threadVariable" => Expr!(Quote::ThreadVariable {
1217 specifier: self.migrate(token)?,
1218 symbol,
1219 }),
1220 "threadLocal" => Expr!(Quote::ThreadLocal {
1221 specifier: self.migrate(token)?,
1222 symbol,
1223 }),
1224 kind => return Err(self.unsupported(kind, token)),
1225 })
1226 }
1227
1228 fn debug_clause(&self, node: tree_sitter::Node<'_>) -> Result<Expr, ParseError> {
1230 let keyword = self.required_field(node, "keyword")?;
1231 let value = self
1232 .first_expression_child(node)
1233 .map(|child| self.expr(child))
1234 .transpose()?;
1235 Ok(match keyword.kind() {
1236 "elapsedTime" => Expr!(Profile::ElapsedTime {
1237 modifier: self.migrate(keyword)?,
1238 value: Box::new(value.ok_or_else(|| self.unsupported("profiling operand", node))?,),
1239 }),
1240 "elapsedTiming" => Expr!(Profile::ElapsedTiming {
1241 modifier: self.migrate(keyword)?,
1242 value: Box::new(value.ok_or_else(|| self.unsupported("profiling operand", node))?,),
1243 }),
1244 "profile" => Expr!(Profile::Profile {
1245 modifier: self.migrate(keyword)?,
1246 value: Box::new(value.ok_or_else(|| self.unsupported("profiling operand", node))?,),
1247 }),
1248 "time" => Expr!(Profile::Time {
1249 modifier: self.migrate(keyword)?,
1250 value: Box::new(value.ok_or_else(|| self.unsupported("profiling operand", node))?,),
1251 }),
1252 "timing" => Expr!(Profile::Timing {
1253 modifier: self.migrate(keyword)?,
1254 value: Box::new(value.ok_or_else(|| self.unsupported("profiling operand", node))?,),
1255 }),
1256 "TEST" => Expr!(Debug::Test {
1257 keyword: self.migrate(keyword)?,
1258 value: value.map(Box::new),
1259 }),
1260 "step" => Expr!(Debug::Step {
1261 keyword: self.migrate(keyword)?,
1262 value: value.map(Box::new),
1263 }),
1264 "finish" => Expr!(Debug::Finish {
1265 keyword: self.migrate(keyword)?,
1266 value: value.map(Box::new),
1267 }),
1268 "shield" => Expr!(Debug::Shield {
1269 keyword: self.migrate(keyword)?,
1270 value: value.map(Box::new),
1271 }),
1272 "breakpoint" => Expr!(Debug::Breakpoint {
1273 keyword: self.migrate(keyword)?,
1274 value: value.map(Box::new),
1275 }),
1276 kind => return Err(self.unsupported(kind, keyword)),
1277 })
1278 }
1279
1280 fn migrate<T>(&self, node: tree_sitter::Node<'_>) -> Result<T, ParseError>
1282 where
1283 for<'tree> T: Migrate<TreeSitterNode<'tree, 'source>>,
1284 {
1285 T::migrate(TreeSitterNode::with_span(
1286 node,
1287 self.source,
1288 self.span(node),
1289 ))
1290 .map_err(Into::into)
1291 }
1292
1293 fn delimiter_spans(&self, node: tree_sitter::Node<'_>) -> Result<DoubleSpan, ParseError> {
1295 let kind = match node.kind() {
1296 "parenthesized_expression" | "sequence" => DelimiterKind::Parenthesis,
1297 "array" => DelimiterKind::Bracket,
1298 "list" => DelimiterKind::Brace,
1299 "angle_bar_list" => DelimiterKind::AngleBar,
1300 other => return Err(self.unsupported(other, node)),
1301 };
1302 let opening = self.span(self.required_kind(node, kind.opening())?);
1303 let closing = self.required_kind(node, kind.closing())?;
1304 if closing.start_byte() >= self.source.len() {
1305 Ok(DoubleSpan::unclosed(opening))
1306 } else {
1307 Ok(DoubleSpan::new(opening, self.span(closing)))
1308 }
1309 }
1310
1311 fn children<'tree>(&self, node: tree_sitter::Node<'tree>) -> Vec<tree_sitter::Node<'tree>> {
1313 (0..node.child_count())
1314 .filter_map(|index| node.child(u32::try_from(index).expect("child count fits u32")))
1315 .collect()
1316 }
1317
1318 fn semantic_children<'tree>(
1320 &self,
1321 node: tree_sitter::Node<'tree>,
1322 ) -> Vec<tree_sitter::Node<'tree>> {
1323 self.children(node)
1324 .into_iter()
1325 .filter(|child| child.is_named() && !child.is_extra())
1326 .collect()
1327 }
1328
1329 fn only_semantic_child<'tree>(
1331 &self,
1332 node: tree_sitter::Node<'tree>,
1333 ) -> Result<tree_sitter::Node<'tree>, ParseError> {
1334 let children = self.semantic_children(node);
1335 match children.as_slice() {
1336 [child] => Ok(*child),
1337 _ => Err(self.unsupported("cell contents", node)),
1338 }
1339 }
1340
1341 fn first_expression_child<'tree>(
1343 &self,
1344 node: tree_sitter::Node<'tree>,
1345 ) -> Option<tree_sitter::Node<'tree>> {
1346 self.semantic_children(node).into_iter().find(|child| {
1347 !matches!(
1348 child.kind(),
1349 "then_clause" | "else_clause" | "except_clause" | "iteration_range" | "loop_body"
1350 )
1351 })
1352 }
1353
1354 fn required_expression_child<'tree>(
1356 &self,
1357 node: tree_sitter::Node<'tree>,
1358 ) -> Result<tree_sitter::Node<'tree>, ParseError> {
1359 self.first_expression_child(node)
1360 .ok_or_else(|| self.unsupported("expression child", node))
1361 }
1362
1363 fn child_by_field<'tree>(
1365 &self,
1366 node: tree_sitter::Node<'tree>,
1367 field: &str,
1368 ) -> Option<tree_sitter::Node<'tree>> {
1369 node.child_by_field_name(field)
1370 }
1371
1372 fn required_field<'tree>(
1374 &self,
1375 node: tree_sitter::Node<'tree>,
1376 field: &str,
1377 ) -> Result<tree_sitter::Node<'tree>, ParseError> {
1378 self.child_by_field(node, field)
1379 .ok_or_else(|| self.unsupported(field, node))
1380 }
1381
1382 fn optional_kind<'tree>(
1384 &self,
1385 node: tree_sitter::Node<'tree>,
1386 kind: &str,
1387 ) -> Option<tree_sitter::Node<'tree>> {
1388 self.children(node)
1389 .into_iter()
1390 .find(|child| !child.is_extra() && child.kind() == kind)
1391 }
1392
1393 fn required_kind<'tree>(
1395 &self,
1396 node: tree_sitter::Node<'tree>,
1397 kind: &str,
1398 ) -> Result<tree_sitter::Node<'tree>, ParseError> {
1399 self.optional_kind(node, kind)
1400 .ok_or_else(|| self.unsupported(kind, node))
1401 }
1402
1403 fn text(&self, node: tree_sitter::Node<'_>) -> Cow<'_, str> {
1405 let range = self
1406 .span(node)
1407 .bounds()
1408 .map_or_else(|| node.byte_range(), |(start, end)| start..end);
1409 String::from_utf8_lossy(&self.source[range])
1410 }
1411
1412 fn span(&self, node: tree_sitter::Node<'_>) -> Span {
1414 let range = node.byte_range();
1415 self.aliases
1416 .iter()
1417 .find(|alias| alias.bare == range)
1418 .map_or_else(
1419 || {
1420 self.source_span.subspan(
1421 node.start_byte().min(self.source.len()),
1422 node.end_byte().min(self.source.len()),
1423 )
1424 },
1425 |alias| self.source_span.subspan(alias.full.start, alias.full.end),
1426 )
1427 }
1428
1429 fn unsupported(&self, kind: impl Into<String>, node: tree_sitter::Node<'_>) -> ParseError {
1431 self.unsupported_span(kind, self.span(node))
1432 }
1433
1434 fn unsupported_span(&self, kind: impl Into<String>, span: Span) -> ParseError {
1436 ParseError::UnsupportedNode {
1437 kind: kind.into(),
1438 span,
1439 }
1440 }
1441}
1442
1443#[derive(Clone)]
1444struct CoreAlias {
1446 full: Range<usize>,
1448 bare: Range<usize>,
1450}
1451
1452fn renamed_source(source: &str) -> Result<(Cow<'_, str>, Vec<CoreAlias>), LexError> {
1454 let tokens = lex_str(source)?;
1455 let mut aliases = Vec::new();
1456 collect_core_aliases(&tokens, &mut aliases);
1457 if aliases.is_empty() {
1458 return Ok((Cow::Borrowed(source), aliases));
1459 }
1460
1461 let mut renamed = source.as_bytes().to_vec();
1462 for alias in &aliases {
1463 renamed[alias.full.start..alias.bare.start].fill(b' ');
1464 }
1465 Ok((
1466 Cow::Owned(String::from_utf8(renamed).expect("replacing ASCII bytes preserves UTF-8")),
1467 aliases,
1468 ))
1469}
1470
1471type RecoveredSource<'source> = (Cow<'source, str>, Vec<CoreAlias>, Vec<LexError>);
1473
1474fn renamed_source_recovering(source: &str) -> Result<RecoveredSource<'_>, LexError> {
1476 let recovered = lex_str_recovering(source)?;
1477 let (tokens, diagnostics) = recovered.into_parts();
1478 let mut aliases = Vec::new();
1479 collect_core_aliases(&tokens, &mut aliases);
1480 let mut missing = Vec::new();
1481 collect_missing_closers(&tokens, &mut missing);
1482
1483 if aliases.is_empty() && missing.is_empty() {
1484 return Ok((Cow::Borrowed(source), aliases, diagnostics));
1485 }
1486
1487 let mut renamed = source.as_bytes().to_vec();
1488 for alias in &aliases {
1489 renamed[alias.full.start..alias.bare.start].fill(b' ');
1490 }
1491 for kind in missing {
1492 renamed.extend_from_slice(kind.closing().as_bytes());
1493 }
1494 Ok((
1495 Cow::Owned(String::from_utf8(renamed).expect("ASCII recovery preserves UTF-8")),
1496 aliases,
1497 diagnostics,
1498 ))
1499}
1500
1501fn collect_missing_closers(tokens: &TokenStream, missing: &mut Vec<DelimiterKind>) {
1503 for token in tokens.iter() {
1504 let TokenTree::Group(group) = token else {
1505 continue;
1506 };
1507 collect_missing_closers(group.stream(), missing);
1508 if !group.delimiter().is_closed() {
1509 missing.push(group.delim_kind());
1510 }
1511 }
1512}
1513
1514fn collect_core_aliases(tokens: &TokenStream, aliases: &mut Vec<CoreAlias>) {
1516 for token in tokens.iter() {
1517 match token {
1518 TokenTree::Group(group) => collect_core_aliases(group.stream(), aliases),
1519 TokenTree::Ident(identifier) => {
1520 let spelling = identifier.text();
1521 let bare = crate::lexer::canonical_word_spelling(spelling);
1522 if bare == spelling {
1523 continue;
1524 }
1525 let Some((start, end)) = identifier.expect_span().bounds() else {
1526 continue;
1527 };
1528 aliases.push(CoreAlias {
1529 full: start..end,
1530 bare: end - bare.len()..end,
1531 });
1532 }
1533 TokenTree::Literal(_) | TokenTree::Punct(_) => {}
1534 }
1535 }
1536}
1537
1538#[derive(Clone)]
1539pub struct TreeSitterNode<'tree, 'source> {
1541 node: tree_sitter::Node<'tree>,
1543 source: &'source [u8],
1545 span: Option<Span>,
1547}
1548
1549impl<'tree, 'source> TreeSitterNode<'tree, 'source> {
1550 pub fn new(node: tree_sitter::Node<'tree>, source: &'source [u8]) -> Self {
1552 Self {
1553 node,
1554 source,
1555 span: None,
1556 }
1557 }
1558
1559 fn with_span(node: tree_sitter::Node<'tree>, source: &'source [u8], span: Span) -> Self {
1561 Self {
1562 node,
1563 source,
1564 span: Some(span),
1565 }
1566 }
1567}
1568
1569impl ExternalCstNode for TreeSitterNode<'_, '_> {
1570 type Children<'syntax>
1571 = IntoIter<ExternalCstChild<Self>>
1572 where
1573 Self: 'syntax;
1574
1575 fn identity(&self) -> CSTNodeClassLabel<'_> {
1576 CSTNodeClassLabel::new(self.node.kind(), self.node.is_named())
1577 }
1578
1579 fn children(&self) -> Self::Children<'_> {
1580 let parent = self.node;
1581 (0..parent.child_count())
1582 .filter_map(|index| {
1583 let index = u32::try_from(index).expect("Tree-sitter child count fits u32");
1584 parent.child(index).map(|node| ExternalCstChild {
1585 field: parent.field_name_for_child(index),
1586 node: Self::new(node, self.source),
1587 })
1588 })
1589 .collect::<Vec<_>>()
1590 .into_iter()
1591 }
1592
1593 fn text(&self) -> Cow<'_, str> {
1594 let range = self
1595 .span
1596 .as_ref()
1597 .and_then(Span::bounds)
1598 .map_or_else(|| self.node.byte_range(), |(start, end)| start..end);
1599 String::from_utf8_lossy(&self.source[range])
1600 }
1601
1602 fn is_extra(&self) -> bool {
1603 self.node.is_extra()
1604 }
1605}
1606
1607impl Spanned for TreeSitterNode<'_, '_> {
1608 fn try_span(&self) -> Option<Span> {
1609 self.span.clone()
1610 }
1611}