luaur_analysis/methods/
replacer_replacer.rs1use crate::records::replacer::Replacer;
2use crate::records::substitution::Substitution;
3use crate::records::tarjan::SubstitutionVtable;
4use crate::records::txn_log::TxnLog;
5use crate::records::type_arena::TypeArena;
6use crate::type_aliases::type_id::TypeId;
7use crate::type_aliases::type_pack_id::TypePackId;
8use core::ffi::c_void;
9use luaur_common::macros::luau_assert::LUAU_ASSERT;
10use luaur_common::records::dense_hash_map::DenseHashMap;
11
12fn replacer_is_dirty_ty(owner: *mut c_void, ty: TypeId) -> bool {
13 unsafe { (*(owner as *mut Replacer)).is_dirty_type_id(ty) }
14}
15
16fn replacer_is_dirty_tp(owner: *mut c_void, tp: TypePackId) -> bool {
17 unsafe { (*(owner as *mut Replacer)).is_dirty_type_pack_id(tp) }
18}
19
20fn replacer_clean_ty(owner: *mut c_void, ty: TypeId) -> TypeId {
21 unsafe { (*(owner as *mut Replacer)).clean_type_id(ty) }
22}
23
24fn replacer_clean_tp(owner: *mut c_void, tp: TypePackId) -> TypePackId {
25 unsafe { (*(owner as *mut Replacer)).clean_type_pack_id(tp) }
26}
27
28fn replacer_found_dirty_ty(owner: *mut c_void, ty: TypeId) {
29 unsafe { (*(owner as *mut Replacer)).base.found_dirty_type_id(ty) }
30}
31
32fn replacer_found_dirty_tp(owner: *mut c_void, tp: TypePackId) {
33 unsafe {
34 (*(owner as *mut Replacer))
35 .base
36 .found_dirty_type_pack_id(tp)
37 }
38}
39
40fn replacer_ignore_children_ty(owner: *mut c_void, ty: TypeId) -> bool {
41 unsafe { (*(owner as *mut Replacer)).ignore_children(ty) }
42}
43
44fn replacer_ignore_children_tp(_owner: *mut c_void, _tp: TypePackId) -> bool {
45 false
46}
47
48impl Replacer {
49 pub fn replacer(
50 arena: *mut TypeArena,
51 replacements: *mut DenseHashMap<TypeId, TypeId>,
52 replacement_packs: *mut DenseHashMap<TypePackId, TypePackId>,
53 ) -> Self {
54 let this = Replacer {
55 base: Substitution::substitution_new(TxnLog::empty(), arena),
56 replacements,
57 replacement_packs,
58 };
59 LUAU_ASSERT!(this.check_replacement_keys());
60 this
61 }
62
63 fn install_substitution_vtable(&mut self) {
64 let owner = self as *mut Replacer as *mut c_void;
65 self.base.base.vtable = SubstitutionVtable {
66 owner,
67 is_dirty_ty: Some(replacer_is_dirty_ty),
68 is_dirty_tp: Some(replacer_is_dirty_tp),
69 clean_ty: Some(replacer_clean_ty),
70 clean_tp: Some(replacer_clean_tp),
71 found_dirty_ty: Some(replacer_found_dirty_ty),
72 found_dirty_tp: Some(replacer_found_dirty_tp),
73 ignore_children_ty: Some(replacer_ignore_children_ty),
74 ignore_children_tp: Some(replacer_ignore_children_tp),
75 ignore_children_visit_ty: Some(replacer_ignore_children_ty),
76 ignore_children_visit_tp: Some(replacer_ignore_children_tp),
77 };
78 }
79
80 pub fn substitute_type_id(&mut self, ty: TypeId) -> Option<TypeId> {
81 self.install_substitution_vtable();
82 self.base.substitute_type_id(ty)
83 }
84
85 pub fn substitute_type_pack_id(&mut self, tp: TypePackId) -> Option<TypePackId> {
86 self.install_substitution_vtable();
87 self.base.substitute_type_pack_id(tp)
88 }
89}