Skip to content

Commit

Permalink
error nodes: removed traversal into AnyNodes, added `visit_error_ch…
Browse files Browse the repository at this point in the history
…ild` visitor function in exchange
  • Loading branch information
SpontanCombust committed Aug 27, 2024
1 parent a8dc24c commit 3f35786
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 11 deletions.
5 changes: 5 additions & 0 deletions crates/core/src/ast/traversal/visitor.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::tokens::*;
use crate::ast::*;
use crate::AnyNode;
use crate::ErrorNode;
use super::policies::*;
use super::contexts::*;
Expand Down Expand Up @@ -280,8 +281,12 @@ pub trait SyntaxNodeVisitor {
/// Called when visiting an unnamed node (i.e. keyword or punctuation).
fn visit_unnamed(&mut self, n: &UnnamedNode, ctx: &TraversalContextStack) {}


/// Called when visiting a node representing a syntax error.
fn visit_error(&mut self, n: &ErrorNode, ctx: &TraversalContextStack) -> ErrorTraversalPolicy { TraversalPolicy::default_to(self.traversal_policy_default()) }
/// Called after visiting a node representing a syntax error and possibly also children nodes specified in traversal policy.
fn exit_error(&mut self, n: &ErrorNode, ctx: &TraversalContextStack) {}

/// Called when visiting a child node of an error node. The actual kind of node is not resolved automatically and thus not traversed into.
fn visit_error_child(&mut self, n: &AnyNode, ctx: &TraversalContextStack) {}
}
7 changes: 6 additions & 1 deletion crates/core/src/ast/traversal/visitor_chain.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::{cell::{RefCell, RefMut}, rc::Rc};
use crate::{ast::*, ErrorNode};
use crate::{ast::*, AnyNode, ErrorNode};
use crate::tokens::*;


Expand Down Expand Up @@ -595,4 +595,9 @@ impl<'a> SyntaxNodeVisitor for SyntaxNodeVisitorChain<'a> {
fn exit_error(&mut self, n: &ErrorNode, ctx: &TraversalContextStack) {
self.chain_exit(move |link| link.exit_error(n, ctx))
}

#[inline]
fn visit_error_child(&mut self, n: &AnyNode, ctx: &TraversalContextStack) {
self.chain_visit(move |link| link.visit_error_child(n, ctx))
}
}
13 changes: 6 additions & 7 deletions crates/core/src/syntax_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,15 @@ impl std::fmt::Debug for ErrorNode<'_> {
impl<'script> SyntaxNodeTraversal for ErrorNode<'script> {
fn accept<V: SyntaxNodeVisitor>(&self, visitor: &mut V, ctx: &mut TraversalContextStack) {
let tp = visitor.visit_error(self, ctx);
ctx.push(TraversalContext::Error);
if tp.traverse {
for res in self.children_detailed() {
match res {
Ok((n, _)) => n.accept(visitor, ctx),
Err(e) => e.accept(visitor, ctx)
}
ctx.push(TraversalContext::Error);

for n in self.children().can_be_error(true) {
visitor.visit_error_child(&n, ctx);
}

ctx.pop();
}
ctx.pop();
visitor.exit_error(self, ctx);
}
}
13 changes: 10 additions & 3 deletions crates/core/src/syntax_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,8 @@ pub struct SyntaxNodeChildren<'script> {
cursor: ts::TreeCursor<'script>,
any_children_left: bool,

must_be_named: bool
must_be_named: bool,
can_be_error: bool
}

impl<'script> SyntaxNodeChildren<'script> {
Expand All @@ -296,14 +297,20 @@ impl<'script> SyntaxNodeChildren<'script> {
cursor,
any_children_left,

must_be_named: false
must_be_named: false,
can_be_error: false
}
}

pub fn must_be_named(mut self, b: bool) -> Self {
self.must_be_named = b;
self
}

pub fn can_be_error(mut self, b: bool) -> Self {
self.can_be_error = b;
self
}
}

impl<'script> Iterator for SyntaxNodeChildren<'script> {
Expand All @@ -313,7 +320,7 @@ impl<'script> Iterator for SyntaxNodeChildren<'script> {
if self.any_children_left {
let mut n = self.cursor.node();
while n.is_extra()
|| n.is_error()
|| (!self.can_be_error && n.is_error())
|| (self.must_be_named && !n.is_named()) {
if self.cursor.goto_next_sibling() {
n = self.cursor.node();
Expand Down

0 comments on commit 3f35786

Please sign in to comment.