Skip to main content

luaur_analysis/methods/
constraint_generator_create_generic_packs.rs

1use crate::enums::polarity::Polarity;
2use crate::records::blocked_type_pack::BlockedTypePack;
3use crate::records::constraint_generator::ConstraintGenerator;
4use crate::records::generic_type_pack::GenericTypePack;
5use crate::records::generic_type_pack_definition::GenericTypePackDefinition;
6use crate::records::scope::Scope;
7use crate::type_aliases::name_type::Name;
8use crate::type_aliases::scope_ptr_constraint_generator::ScopePtr;
9use crate::type_aliases::type_pack_id::TypePackId;
10use alloc::vec::Vec;
11use luaur_ast::records::ast_array::AstArray;
12use luaur_ast::records::ast_generic_type_pack::AstGenericTypePack;
13
14impl ConstraintGenerator {
15    pub fn create_generic_packs(
16        &mut self,
17        scope: &ScopePtr,
18        generics: AstArray<*mut AstGenericTypePack>,
19        use_cache: bool,
20        add_types: bool,
21    ) -> Vec<(Name, GenericTypePackDefinition)> {
22        let mut result: Vec<(Name, GenericTypePackDefinition)> = Vec::new();
23        let scope_ptr = scope.as_ref() as *const Scope as *mut Scope;
24
25        for i in 0..generics.size {
26            let generic = unsafe { *generics.data.add(i) };
27
28            let generic_name_ptr = unsafe { (*generic).name.value };
29            let generic_name_str = unsafe {
30                core::ffi::CStr::from_ptr(generic_name_ptr)
31                    .to_string_lossy()
32                    .into_owned()
33            };
34
35            let mut generic_ty: Option<TypePackId> = None;
36
37            if use_cache {
38                if let Some(parent_scope) = scope.parent.as_ref() {
39                    if let Some(type_pack_id) = parent_scope
40                        .type_alias_type_pack_parameters
41                        .get(&generic_name_str)
42                    {
43                        generic_ty = Some(*type_pack_id);
44                    }
45                }
46            }
47
48            if generic_ty.is_none() {
49                let mut gtp = GenericTypePack {
50                    index: 0,
51                    level: Default::default(),
52                    scope: core::ptr::null_mut(),
53                    name: Default::default(),
54                    explicitName: false,
55                    polarity: Polarity::None,
56                };
57                gtp.generic_type_pack_scope_name_polarity(
58                    scope_ptr,
59                    generic_name_str.clone(),
60                    Polarity::None,
61                );
62                generic_ty = Some(unsafe { (*self.arena).add_type_pack_t(gtp) });
63
64                if let Some(parent_scope) = scope.parent.as_ref() {
65                    let parent_scope_ptr = parent_scope.as_ref() as *const Scope as *mut Scope;
66                    unsafe {
67                        (*parent_scope_ptr)
68                            .type_alias_type_pack_parameters
69                            .insert(generic_name_str.clone(), generic_ty.unwrap());
70                    }
71                }
72            }
73
74            let default_ty: Option<TypePackId> = if unsafe { (*generic).default_value }.is_null() {
75                None
76            } else {
77                let mut btp = BlockedTypePack {
78                    index: 0,
79                    owner: core::ptr::null_mut(),
80                };
81                btp.blocked_type_pack_blocked_type_pack();
82                Some(unsafe { (*self.arena).add_type_pack_t(btp) })
83            };
84
85            if add_types {
86                unsafe {
87                    (*scope_ptr)
88                        .private_type_pack_bindings
89                        .insert(generic_name_str.clone(), generic_ty.unwrap());
90                }
91            }
92
93            result.push((
94                generic_name_str,
95                GenericTypePackDefinition {
96                    tp: generic_ty.unwrap(),
97                    defaultValue: default_ty,
98                },
99            ));
100        }
101
102        result
103    }
104}