luaur_analysis/methods/
require_tracer_process.rs1use crate::records::file_resolver::FileResolver;
2use crate::records::module_info::ModuleInfo;
3use crate::records::require_tracer::RequireTracer;
4use crate::records::type_check_limits::TypeCheckLimits;
5use luaur_ast::records::ast_expr::AstExpr;
6use luaur_ast::records::ast_expr_call::AstExprCall;
7use luaur_ast::records::ast_expr_group::AstExprGroup;
8use luaur_ast::records::ast_expr_local::AstExprLocal;
9use luaur_ast::records::ast_expr_type_assertion::AstExprTypeAssertion;
10use luaur_ast::records::ast_node::AstNode;
11use luaur_ast::records::ast_type_group::AstTypeGroup;
12use luaur_ast::records::ast_type_typeof::AstTypeTypeof;
13
14impl RequireTracer {
15 pub fn process(&mut self, limits: &TypeCheckLimits) {
16 let module_context = ModuleInfo {
17 name: self.current_module_name.clone(),
18 optional: false,
19 };
20
21 self.work.reserve(self.require_calls.len());
22 for &require in &self.require_calls {
23 unsafe {
24 if (*require).args.size > 0 {
25 self.work.push(*(*require).args.data.add(0) as *mut AstNode);
26 }
27 }
28 }
29
30 let mut i = 0;
31 while i < self.work.len() {
32 let node = self.work[i];
33 if !node.is_null() {
34 let dep = unsafe { self.get_dependent(node) };
35 if !dep.is_null() {
36 self.work.push(dep);
37 }
38 }
39 i += 1;
40 }
41
42 unsafe {
43 let mut i = self.work.len();
44 while i > 0 {
45 let expr = self.work[i - 1];
46 i -= 1;
47
48 if (*self.result).exprs.find(&expr).is_some() {
49 continue;
50 }
51
52 let mut info: Option<ModuleInfo> = None;
53 let dep = self.get_dependent(expr);
54
55 if !dep.is_null() {
56 let context = (*self.result).exprs.find(&dep);
57 if let Some(context) = context {
58 if (*expr).is::<AstExprLocal>()
59 || (*expr).is::<AstExprGroup>()
60 || (*expr).is::<AstTypeGroup>()
61 || (*expr).is::<AstTypeTypeof>()
62 || (*expr).is::<AstExprTypeAssertion>()
63 {
64 info = Some(context.clone());
65 } else if let Some(as_expr) = (*expr).as_expr().as_mut() {
66 info = FileResolver::resolve_module(
67 self.file_resolver,
68 context,
69 as_expr,
70 limits,
71 );
72 }
73 }
74 } else if let Some(as_expr) = (*expr).as_expr().as_mut() {
75 info = FileResolver::resolve_module(
76 self.file_resolver,
77 &module_context,
78 as_expr,
79 limits,
80 );
81 }
82
83 if let Some(info) = info {
84 (*self.result).exprs.try_insert(expr, info);
85 }
86 }
87
88 (*self.result)
89 .require_list
90 .reserve(self.require_calls.len());
91 for &require in &self.require_calls {
92 let arg = *(*require).args.data.add(0) as *mut AstNode;
93 if let Some(info) = (*self.result).exprs.find(&arg) {
94 (*self.result)
95 .require_list
96 .push((info.name.clone(), (*require).base.base.location));
97 let info_copy = info.clone();
98 (*self.result)
99 .exprs
100 .try_insert(require as *mut AstNode, info_copy);
101 } else {
102 (*self.result)
103 .exprs
104 .try_insert(require as *mut AstNode, ModuleInfo::default());
105 }
106 }
107 }
108 }
109}