use crate::node::{Node, Tree};
use crate::traits::{LanguageInfo, ParserTrait};
pub fn for_each_node_with_chain<L: LanguageInfo>(
code: &[u8],
mut check: impl FnMut(&Node<'_>, &[Node<'_>]),
) -> usize {
let tree = Tree::new::<L>(code);
let root = tree.get_root();
assert!(
!root.has_error(),
"fixture must parse cleanly, else the walk covers error recovery"
);
let mut chain: Vec<Node<'_>> = Vec::new();
let mut stack = vec![(root, 0_usize)];
let mut visited = 0;
while let Some((node, depth)) = stack.pop() {
chain.truncate(depth);
check(&node, &chain);
visited += 1;
chain.push(node);
let first = stack.len();
stack.extend(node.children().map(|child| (child, depth + 1)));
stack[first..].reverse();
}
visited
}
pub fn ast_has_kind_id<P: ParserTrait>(parser: &P, target: u16) -> bool {
parser.root().preorder().any(|n| n.kind_id() == target)
}
#[track_caller]
pub fn assert_classifies(predicate: fn(&[u8]) -> bool, yes: &[&[u8]], no: &[&[u8]]) {
for input in yes {
assert!(predicate(input), "{}", String::from_utf8_lossy(input));
}
for input in no {
assert!(!predicate(input), "{}", String::from_utf8_lossy(input));
}
}