luaur_analyze_cli/methods/
cli_file_resolver_resolve_module.rs1use crate::records::cli_file_resolver::CliFileResolver;
2use crate::records::file_navigation_context::FileNavigationContext;
3use crate::records::luau_config_interrupt_info::LuauConfigInterruptInfo;
4use alloc::boxed::Box;
5use alloc::string::String;
6use luaur_analysis::records::module_info::ModuleInfo;
7use luaur_analysis::records::type_check_limits::TypeCheckLimits;
8use luaur_ast::records::ast_expr::AstExpr;
9use luaur_ast::records::ast_expr_constant_string::AstExprConstantString;
10use luaur_ast::records::ast_node::AstNode;
11use luaur_ast::rtti::ast_node_as;
12use luaur_require::enums::status_require_navigator::Status;
13use luaur_require::records::error_handler::ErrorHandler;
14use luaur_require::records::navigator::Navigator;
15
16struct NullErrorHandler;
19
20impl ErrorHandler for NullErrorHandler {
21 fn report_error(&mut self, _message: String) {}
22}
23
24impl CliFileResolver {
25 pub unsafe fn resolve_module(
28 &mut self,
29 context: *const ModuleInfo,
30 expr: *mut AstExpr,
31 limits: &TypeCheckLimits,
32 ) -> Option<ModuleInfo> {
33 let const_str = ast_node_as::<AstExprConstantString>(expr as *mut AstNode);
35 if const_str.is_null() {
36 return None;
37 }
38
39 let bytes: &[u8] = {
41 let slice = (*const_str).value.as_slice();
42 core::slice::from_raw_parts(slice.as_ptr() as *const u8, slice.len())
43 };
44 let path = String::from_utf8_lossy(bytes).into_owned();
45
46 let mut navigation_context = FileNavigationContext::new((*context).name.clone());
48
49 navigation_context.interrupt_info = Some(Box::new(LuauConfigInterruptInfo {
52 limits: limits.clone(),
53 module: path.clone(),
54 }));
55
56 let mut null_error_handler = NullErrorHandler;
57
58 let mut navigator = Navigator::new(&mut navigation_context, &mut null_error_handler);
60
61 if navigator.navigate(path) != Status::Success {
63 return None;
64 }
65
66 drop(navigator);
69
70 if !crate::methods::file_navigation_context_is_module_present::file_navigation_context_is_module_present(
72 &navigation_context,
73 ) {
74 return None;
75 }
76
77 if let Some(identifier) =
80 crate::methods::file_navigation_context_get_identifier::file_navigation_context_get_identifier(
81 &navigation_context,
82 )
83 {
84 return Some(ModuleInfo {
85 name: identifier,
86 optional: false,
87 });
88 }
89
90 None
91 }
92}