luaur_analysis/methods/
clone_public_interface_clean_module.rs1use crate::enums::table_state::TableState;
2use crate::functions::get_mutable_type::get_mutable_type_id;
3use crate::functions::get_type_alt_j::get_type_id;
4use crate::records::blocked_type::BlockedType;
5use crate::records::clone_public_interface::ClonePublicInterface;
6use crate::records::free_type::FreeType;
7use crate::records::function_type::FunctionType;
8use crate::records::generic_type::GenericType;
9use crate::records::generic_type_finder::GenericTypeFinder;
10use crate::records::generic_type_visitor::{GenericTypeVisitor, GenericTypeVisitorTrait};
11use crate::records::pending_expansion_type::PendingExpansionType;
12use crate::records::table_type::TableType;
13use crate::records::type_level::TypeLevel;
14use crate::type_aliases::type_id::TypeId;
15use core::ffi::c_void;
16use luaur_common::records::dense_hash_set::DenseHashSet;
17
18impl GenericTypeVisitorTrait for GenericTypeFinder {
23 type Seen = DenseHashSet<*mut c_void>;
24
25 fn visitor_base(&mut self) -> &mut GenericTypeVisitor<Self::Seen> {
26 &mut self.base.base
27 }
28
29 fn visit_type_id(&mut self, ty: TypeId) -> bool {
30 GenericTypeFinder::visit_type_id(self, ty)
31 }
32
33 fn visit_type_pack_id(&mut self, tp: crate::type_aliases::type_pack_id::TypePackId) -> bool {
34 GenericTypeFinder::visit_type_pack_id(self, tp)
35 }
36
37 fn visit_type_id_function_type(&mut self, ty: TypeId, ftv: &FunctionType) -> bool {
38 GenericTypeFinder::visit_type_id_function_type(self, ty, ftv)
39 }
40
41 fn visit_type_id_table_type(&mut self, ty: TypeId, ttv: &TableType) -> bool {
42 GenericTypeFinder::visit_type_id_table_type(self, ty, ttv)
43 }
44
45 fn visit_type_id_generic_type(&mut self, ty: TypeId, gtv: &GenericType) -> bool {
46 GenericTypeFinder::visit_type_id_generic_type(self, ty, gtv)
47 }
48
49 fn visit_type_pack_id_generic_type_pack(
50 &mut self,
51 tp: crate::type_aliases::type_pack_id::TypePackId,
52 gtp: &crate::records::generic_type_pack::GenericTypePack,
53 ) -> bool {
54 GenericTypeFinder::visit_type_pack_id_generic_type_pack(self, tp, gtp)
55 }
56
57 fn visit_type_id_extern_type(
58 &mut self,
59 ty: TypeId,
60 etv: &crate::records::extern_type::ExternType,
61 ) -> bool {
62 GenericTypeFinder::visit_type_id_extern_type(self, ty, etv)
63 }
64}
65
66impl ClonePublicInterface {
67 pub fn clean_type_id(&mut self, ty: TypeId) -> TypeId {
70 let mut result = self.base.clone_type_id(ty);
71
72 let ftv = unsafe { get_mutable_type_id::<FunctionType>(result) };
73 if !ftv.is_null() {
74 let ftv = unsafe { &mut *ftv };
75 if ftv.generics.is_empty() && ftv.generic_packs.is_empty() {
76 let mut marker = GenericTypeFinder::generic_type_finder();
77 marker.traverse_type_id(result);
78
79 if !marker.found {
80 ftv.has_no_free_or_generic_types = true;
81 }
82 }
83
84 ftv.level = TypeLevel::new(0, 0);
85 } else {
86 let ttv = unsafe { get_mutable_type_id::<TableType>(result) };
87 if !ttv.is_null() {
88 let ttv = unsafe { &mut *ttv };
89 ttv.level = TypeLevel::new(0, 0);
90 if self.is_new_solver() {
91 ttv.scope = core::ptr::null_mut();
92 ttv.state = TableState::Sealed;
93 }
94 }
95 }
96
97 if self.is_new_solver() {
98 if unsafe {
99 !get_type_id::<FreeType>(ty).is_null()
100 || !get_type_id::<BlockedType>(ty).is_null()
101 || !get_type_id::<PendingExpansionType>(ty).is_null()
102 } {
103 self.internal_type_escaped = true;
104 result = unsafe { (*self.builtin_types).errorType };
105 } else {
106 let genericty = unsafe { get_mutable_type_id::<GenericType>(result) };
107 if !genericty.is_null() {
108 unsafe { (*genericty).scope = core::ptr::null_mut() };
109 }
110 }
111 }
112
113 result
114 }
115}