in src/ast.rs [80:124]
fn build<T: ParserTrait>(parser: &T, span: bool, comment: bool) -> Option<AstNode> {
let code = parser.get_code();
let root = parser.get_root();
let mut cursor = root.cursor();
let mut node_stack = Vec::new();
let mut child_stack = Vec::new();
node_stack.push(root);
child_stack.push(Vec::new());
/* To avoid Rc, RefCell and stuff like that (or use of unsafe)
the idea here is to build AstNode from bottom-to-top and from left-to-right.
So once we have built the array of children we can build the node itself until the root. */
loop {
let ts_node = node_stack.last().unwrap();
cursor.reset(ts_node);
if cursor.goto_first_child() {
let node = cursor.node();
child_stack.push(Vec::with_capacity(node.child_count()));
node_stack.push(node);
} else {
loop {
let ts_node = node_stack.pop().unwrap();
if let Some(node) = T::Checker::get_ast_node(
&ts_node,
code,
child_stack.pop().unwrap(),
span,
comment,
) {
if !child_stack.is_empty() {
child_stack.last_mut().unwrap().push(node);
} else {
return Some(node);
}
}
if let Some(next_node) = ts_node.next_sibling() {
child_stack.push(Vec::with_capacity(next_node.child_count()));
node_stack.push(next_node);
break;
}
}
}
}
}