luaur_analysis/methods/
constraint_solver_resolve_module.rs1use crate::enums::type_file_resolver::Type;
2use crate::functions::first::first;
3use crate::functions::get_type_pack::get_type_pack_id;
4use crate::records::constraint_solver::ConstraintSolver;
5use crate::records::illegal_require::IllegalRequire;
6use crate::records::module_info::ModuleInfo;
7use crate::records::unknown_require::UnknownRequire;
8use crate::type_aliases::error_type_pack::ErrorTypePack;
9use crate::type_aliases::type_error_data::TypeErrorData;
10use crate::type_aliases::type_id::TypeId;
11use alloc::string::{String, ToString};
12use luaur_ast::records::location::Location;
13
14impl ConstraintSolver {
15 pub fn resolve_module(&mut self, info: &ModuleInfo, location: &Location) -> TypeId {
16 if info.name.is_empty() {
17 self.report_error_type_error_data_location(
18 UnknownRequire::new(String::new()).into(),
19 location,
20 );
21 return unsafe { (*self.builtin_types).errorType };
22 }
23
24 for require_cycle in &self.require_cycles {
25 if !require_cycle.path.is_empty() && require_cycle.path[0] == info.name {
26 return unsafe { (*self.builtin_types).anyType };
27 }
28 }
29
30 let module = unsafe {
31 ((*self.module_resolver).vtable.get_module)(self.module_resolver, &info.name)
32 };
33 if module.is_none() {
34 if unsafe {
35 !((*self.module_resolver).vtable.module_exists)(self.module_resolver, &info.name)
36 } && !info.optional
37 {
38 let human_readable_name = unsafe {
39 ((*self.module_resolver)
40 .vtable
41 .get_human_readable_module_name)(
42 self.module_resolver, &info.name
43 )
44 };
45 self.report_error_type_error_data_location(
46 UnknownRequire::new(human_readable_name).into(),
47 location,
48 );
49 }
50 return unsafe { (*self.builtin_types).errorType };
51 }
52
53 let module = module.unwrap();
54 if module.r#type != Type::Module {
55 self.report_error_type_error_data_location(
56 IllegalRequire::new(
57 module.human_readable_name.clone(),
58 "Module is not a ModuleScript. It cannot be required.".to_string(),
59 )
60 .into(),
61 location,
62 );
63 return unsafe { (*self.builtin_types).errorType };
64 }
65
66 if module
67 .errors
68 .iter()
69 .any(|error| matches!(error.data, TypeErrorData::SyntaxError(_)))
70 {
71 return unsafe { (*self.builtin_types).errorType };
72 }
73
74 let module_pack = module.return_type;
75 if !unsafe { get_type_pack_id::<ErrorTypePack>(module_pack) }.is_null() {
76 return unsafe { (*self.builtin_types).errorType };
77 }
78
79 let module_type = first(module_pack, true);
80 if module_type.is_none() {
81 self.report_error_type_error_data_location(
82 IllegalRequire::new(
83 module.human_readable_name.clone(),
84 "Module does not return exactly 1 value. It cannot be required.".to_string(),
85 )
86 .into(),
87 location,
88 );
89 return unsafe { (*self.builtin_types).errorType };
90 }
91
92 module_type.unwrap()
93 }
94}