fn build()

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;
                }
            }
        }
    }
}