Skip to main content

luaur_analysis/methods/
frontend_get_required_scripts.rs

1use crate::functions::trace_requires::trace_requires;
2use crate::records::file_resolver::FileResolver;
3use crate::records::frontend::Frontend;
4use crate::records::require_trace_result::RequireTraceResult;
5use crate::records::type_check_limits::TypeCheckLimits;
6use crate::type_aliases::module_name_file_resolver::ModuleName;
7use alloc::vec::Vec;
8use luaur_config::records::config::Config;
9
10impl Frontend {
11    pub fn get_required_scripts(
12        &mut self,
13        name: &ModuleName,
14        limits: &TypeCheckLimits,
15    ) -> Vec<ModuleName> {
16        // C++: RequireTraceResult require = requireTrace[name];
17        // operator[] default-inserts an empty value when the key is absent.
18        let mut require = self
19            .require_trace
20            .entry(name.clone())
21            .or_insert_with(|| RequireTraceResult {
22                exprs: luaur_common::records::dense_hash_map::DenseHashMap::new(
23                    core::ptr::null_mut(),
24                ),
25                require_list: Vec::new(),
26            })
27            .clone();
28
29        if self.is_dirty(name, false) {
30            let source = unsafe { FileResolver::read_source(self.file_resolver, name) };
31            if source.is_none() {
32                return Vec::new();
33            }
34
35            let source_code = source.unwrap();
36            let config: &Config = unsafe {
37                let get_config = (*self.config_resolver)
38                    .get_config
39                    .expect("ConfigResolver::getConfig is not set");
40                &*get_config(self.config_resolver, name, limits)
41            };
42            let mut opts = config.parse_options.clone();
43            opts.capture_comments = true;
44            let mut result =
45                self.parse_module_name_string_view_parse_options(name, &source_code.source, &opts);
46            result.r#type = source_code.r#type;
47            require = trace_requires(self.file_resolver, result.root, name.clone(), limits);
48        }
49
50        let mut required_module_names: Vec<ModuleName> = Vec::new();
51        required_module_names.reserve(require.require_list.len());
52        for (module_name, _) in require.require_list.iter() {
53            required_module_names.push(module_name.clone());
54        }
55        required_module_names
56    }
57}