Skip to main content

luaur_analysis/methods/
replacer_replacer.rs

1use 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}