//! Source: `Analysis/src/TypePath.cpp:999-1006` (hand-ported)
use crate::functions::follow_type::follow_type_id;
use crate::functions::traverse_type_path::traverse as traverse_path;
use crate::records::builtin_types::BuiltinTypes;
use crate::records::path::Path;
use crate::records::traversal_state::TraversalState;
use crate::records::type_arena::TypeArena;
use crate::type_aliases::type_id::TypeId;
use crate::type_aliases::type_or_pack::TypeOrPack;

pub fn traverse(
    root: TypeId,
    path: &Path,
    builtin_types: &BuiltinTypes,
    arena: &mut TypeArena,
) -> Option<TypeOrPack> {
    let mut state = TraversalState::traversal_state_type_id_not_null_builtin_types_type_arena(
        unsafe { follow_type_id(root) },
        builtin_types,
        arena,
    );
    if traverse_path(&mut state, path) {
        Some(state.current)
    } else {
        None
    }
}
