luaur_analysis/methods/arc_collector_arc_collector.rs
1//! Faithful port of `Luau::detail::ArcCollector::ArcCollector`
2//! (`Analysis/src/TopoSortStatements.cpp:207-217`).
3//!
4//! ```cpp
5//! ArcCollector(NodeQueue& queue)
6//! : queue(queue)
7//! , map(Identifier{std::string{}, 0})
8//! , currentArc(nullptr)
9//! {
10//! for (const auto& node : queue)
11//! {
12//! if (node->name && !map.contains(*node->name))
13//! map[*node->name] = node.get();
14//! }
15//! }
16//! ```
17use crate::records::arc_collector::ArcCollector;
18use crate::records::identifier::Identifier;
19use crate::records::identifier_hash::IdentifierHash;
20use crate::records::node::Node;
21use crate::type_aliases::node_queue::NodeQueue;
22use luaur_common::records::dense_hash_map::DenseHashMap;
23use luaur_common::records::dense_hash_table::DenseHasher;
24
25// Wires the C++ `IdentifierHash::operator()` functor (used as the `Hash`
26// template parameter of `DenseHashMap<Identifier, Node*, IdentifierHash>`) into
27// the container's `DenseHasher` trait so the map is constructible. The hash body
28// itself already lives in `IdentifierHash::identifier_hash_operator_call`.
29impl DenseHasher<Identifier> for IdentifierHash {
30 fn hash(&self, key: &Identifier) -> usize {
31 IdentifierHash::identifier_hash_operator_call(key)
32 }
33}
34
35impl ArcCollector {
36 pub fn arc_collector(&mut self, queue: &mut NodeQueue) {
37 // : queue(queue), map(Identifier{std::string{}, 0}), currentArc(nullptr)
38 self.queue = queue as *mut NodeQueue;
39 self.map = DenseHashMap::new(Identifier::new(
40 alloc::string::String::new(),
41 core::ptr::null(),
42 ));
43 self.current_arc = core::ptr::null_mut();
44
45 // for (const auto& node : queue)
46 // if (node->name && !map.contains(*node->name))
47 // map[*node->name] = node.get();
48 let size = queue.size();
49 for i in 0..size {
50 let node_ptr: *mut Node = *queue.at(i);
51 let node = unsafe { &*node_ptr };
52 if let Some(name) = &node.name {
53 if !self.map.contains(name) {
54 *self.map.get_or_insert(name.clone()) = node_ptr;
55 }
56 }
57 }
58 }
59}