luaur_analysis/methods/
constraint_generator_create_generics.rs1use crate::enums::polarity::Polarity;
2use crate::records::blocked_type::BlockedType;
3use crate::records::constraint_generator::ConstraintGenerator;
4use crate::records::generic_type::GenericType;
5use crate::records::generic_type_definition::GenericTypeDefinition;
6use crate::records::scope::Scope;
7use crate::records::type_fun::TypeFun;
8use crate::type_aliases::name_type::Name;
9use crate::type_aliases::scope_ptr_type::ScopePtr;
10use crate::type_aliases::type_id::TypeId;
11use alloc::vec::Vec;
12use luaur_ast::records::ast_array::AstArray;
13use luaur_ast::records::ast_generic_type::AstGenericType;
14
15impl ConstraintGenerator {
16 pub fn create_generics(
17 &mut self,
18 scope: &ScopePtr,
19 generics: AstArray<*mut AstGenericType>,
20 use_cache: bool,
21 add_types: bool,
22 ) -> Vec<(Name, GenericTypeDefinition)> {
23 let mut result: Vec<(Name, GenericTypeDefinition)> = Vec::new();
24
25 let parent_scope = scope.parent.as_ref().unwrap();
26 let parent_scope_ptr = parent_scope.as_ref() as *const Scope as *mut Scope;
27 let scope_ptr = scope.as_ref() as *const Scope as *mut Scope;
28
29 for i in 0..generics.size {
30 let generic = unsafe { *generics.data.add(i) };
31
32 let generic_name_ptr = unsafe { (*generic).name.value };
33 let generic_name = unsafe { core::ffi::CStr::from_ptr(generic_name_ptr) }
34 .to_string_lossy()
35 .into_owned();
36
37 let generic_ty: TypeId;
38
39 if use_cache {
40 if let Some(ty) = parent_scope
41 .type_alias_type_parameters
42 .get(generic_name.as_str())
43 {
44 generic_ty = *ty;
45 } else {
46 generic_ty = unsafe {
47 (*self.arena).add_type(GenericType::generic_type_scope_name_polarity(
48 scope_ptr,
49 generic_name.clone(),
50 Polarity::None,
51 ))
52 };
53 unsafe {
54 (*parent_scope_ptr)
55 .type_alias_type_parameters
56 .insert(generic_name.clone(), generic_ty);
57 }
58 }
59 } else {
60 generic_ty = unsafe {
61 (*self.arena).add_type(GenericType::generic_type_scope_name_polarity(
62 scope_ptr,
63 generic_name.clone(),
64 Polarity::None,
65 ))
66 };
67 unsafe {
68 (*parent_scope_ptr)
69 .type_alias_type_parameters
70 .insert(generic_name.clone(), generic_ty);
71 }
72 }
73
74 let default_ty: Option<TypeId> = if unsafe { (*generic).default_value }.is_null() {
75 None
76 } else {
77 unsafe { (*self.arena).add_type(BlockedType::default()) }.into()
78 };
79
80 if add_types {
81 unsafe {
82 (*scope_ptr)
83 .private_type_bindings
84 .insert(generic_name.clone(), TypeFun::type_fun_type_id(generic_ty));
85 }
86 }
87
88 result.push((
89 generic_name,
90 GenericTypeDefinition {
91 ty: generic_ty,
92 defaultValue: default_ty,
93 },
94 ));
95 }
96
97 result
98 }
99}