use crate::records::file_resolver::FileResolver;
use crate::records::module_info::ModuleInfo;
use crate::records::require_tracer::RequireTracer;
use crate::records::type_check_limits::TypeCheckLimits;
use luaur_ast::records::ast_expr::AstExpr;
use luaur_ast::records::ast_expr_call::AstExprCall;
use luaur_ast::records::ast_expr_group::AstExprGroup;
use luaur_ast::records::ast_expr_local::AstExprLocal;
use luaur_ast::records::ast_expr_type_assertion::AstExprTypeAssertion;
use luaur_ast::records::ast_node::AstNode;
use luaur_ast::records::ast_type_group::AstTypeGroup;
use luaur_ast::records::ast_type_typeof::AstTypeTypeof;
impl RequireTracer {
pub fn process(&mut self, limits: &TypeCheckLimits) {
let module_context = ModuleInfo {
name: self.current_module_name.clone(),
optional: false,
};
self.work.reserve(self.require_calls.len());
for &require in &self.require_calls {
unsafe {
if (*require).args.size > 0 {
self.work.push(*(*require).args.data.add(0) as *mut AstNode);
}
}
}
let mut i = 0;
while i < self.work.len() {
let node = self.work[i];
if !node.is_null() {
let dep = unsafe { self.get_dependent(node) };
if !dep.is_null() {
self.work.push(dep);
}
}
i += 1;
}
unsafe {
let mut i = self.work.len();
while i > 0 {
let expr = self.work[i - 1];
i -= 1;
if (*self.result).exprs.find(&expr).is_some() {
continue;
}
let mut info: Option<ModuleInfo> = None;
let dep = self.get_dependent(expr);
if !dep.is_null() {
let context = (*self.result).exprs.find(&dep);
if let Some(context) = context {
if (*expr).is::<AstExprLocal>()
|| (*expr).is::<AstExprGroup>()
|| (*expr).is::<AstTypeGroup>()
|| (*expr).is::<AstTypeTypeof>()
|| (*expr).is::<AstExprTypeAssertion>()
{
info = Some(context.clone());
} else if let Some(as_expr) = (*expr).as_expr().as_mut() {
info = FileResolver::resolve_module(
self.file_resolver,
context,
as_expr,
limits,
);
}
}
} else if let Some(as_expr) = (*expr).as_expr().as_mut() {
info = FileResolver::resolve_module(
self.file_resolver,
&module_context,
as_expr,
limits,
);
}
if let Some(info) = info {
(*self.result).exprs.try_insert(expr, info);
}
}
(*self.result)
.require_list
.reserve(self.require_calls.len());
for &require in &self.require_calls {
let arg = *(*require).args.data.add(0) as *mut AstNode;
if let Some(info) = (*self.result).exprs.find(&arg) {
(*self.result)
.require_list
.push((info.name.clone(), (*require).base.base.location));
let info_copy = info.clone();
(*self.result)
.exprs
.try_insert(require as *mut AstNode, info_copy);
} else {
(*self.result)
.exprs
.try_insert(require as *mut AstNode, ModuleInfo::default());
}
}
}
}
}