luaur_analysis/methods/
constraint_generator_create_generic_packs.rs1use 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}