Skip to main content

luaur_analysis/records/
contains_generics.rs

1use crate::records::generic_type::GenericType;
2use crate::records::generic_type_pack::GenericTypePack;
3use crate::records::iterative_type_visitor::IterativeTypeVisitor;
4use crate::records::type_function_instance_type::TypeFunctionInstanceType;
5use crate::type_aliases::type_id::TypeId;
6use crate::type_aliases::type_pack_id::TypePackId;
7use core::ffi::c_void;
8use luaur_common::records::dense_hash_set::DenseHashSet;
9
10#[derive(Debug, Clone)]
11pub struct ContainsGenerics {
12    pub base: IterativeTypeVisitor,
13    pub generics: *mut DenseHashSet<*const c_void>,
14    pub found: bool,
15}
16
17impl ContainsGenerics {
18    pub fn contains_generics(&mut self, generics: *mut DenseHashSet<*const c_void>) {
19        // Keep state wiring consistent with the C++ constructor intent, but
20        // avoid calling missing constructors on IterativeTypeVisitor.
21        self.generics = generics;
22        self.found = false;
23    }
24
25    pub fn visit_type_id(&mut self, _ty: TypeId) -> bool {
26        !self.found
27    }
28
29    pub fn visit_type_id_generic_type(&mut self, ty: TypeId, _gt: &GenericType) -> bool {
30        unsafe {
31            let set = &*self.generics;
32            let key = ty as *const c_void;
33            self.found |= set.contains(&key);
34        }
35        true
36    }
37
38    pub fn visit_type_id_type_function_instance_type(
39        &mut self,
40        _ty: TypeId,
41        _tfit: &TypeFunctionInstanceType,
42    ) -> bool {
43        !self.found
44    }
45
46    pub fn visit_type_pack_id_generic_type_pack(
47        &mut self,
48        tp: TypePackId,
49        _gtp: &GenericTypePack,
50    ) -> bool {
51        unsafe {
52            let set = &*self.generics;
53            let key = tp as *const c_void;
54            self.found |= set.contains(&key);
55        }
56        !self.found
57    }
58}