Skip to main content

luaur_analysis/methods/
frontend_add_build_queue_items.rs

1use crate::functions::get_require_cycles::get_require_cycles;
2use crate::functions::make_type_check_limits::make_type_check_limits;
3use crate::records::build_queue_item::BuildQueueItem;
4use crate::records::file_resolver::FileResolver;
5use crate::records::frontend::{Frontend, FrontendStats};
6use crate::records::frontend_options::FrontendOptions;
7use crate::records::module::Module;
8use crate::records::source_module::SourceModule;
9use crate::type_aliases::module_name_file_resolver::ModuleName;
10use alloc::sync::Arc;
11use alloc::vec::Vec;
12use luaur_common::macros::luau_assert::LUAU_ASSERT;
13use luaur_common::records::dense_hash_set::DenseHashSet;
14use luaur_common::FFlag;
15
16impl Frontend {
17    pub fn add_build_queue_items(
18        &mut self,
19        items: &mut Vec<BuildQueueItem>,
20        build_queue: &Vec<ModuleName>,
21        cycle_detected: bool,
22        seen: &mut DenseHashSet<ModuleName>,
23        frontend_options: &FrontendOptions,
24    ) {
25        for module_name in build_queue {
26            if seen.contains(module_name) {
27                continue;
28            }
29            seen.insert(module_name.clone());
30
31            LUAU_ASSERT!(self.source_nodes.contains_key(module_name));
32            let source_node = self.source_nodes.get(module_name).unwrap().clone();
33
34            if !source_node.has_dirty_module(frontend_options.for_autocomplete) {
35                continue;
36            }
37
38            LUAU_ASSERT!(self.source_modules.contains_key(module_name));
39            let source_module = self.source_modules.get(module_name).unwrap().clone();
40
41            let human_readable_name = unsafe {
42                FileResolver::get_human_readable_module_name(self.file_resolver, module_name)
43            };
44
45            let limits = make_type_check_limits(frontend_options);
46            let config = unsafe {
47                let get_config = (*self.config_resolver)
48                    .get_config
49                    .expect("ConfigResolver::getConfig is not set");
50                (*get_config(self.config_resolver, module_name, &limits)).clone()
51            };
52
53            let environment_scope = self.get_module_environment(
54                source_module.as_ref(),
55                &config,
56                frontend_options.for_autocomplete,
57            );
58
59            let mut require_cycles = Vec::new();
60            if cycle_detected {
61                require_cycles = unsafe {
62                    get_require_cycles(
63                        &*self.file_resolver,
64                        &self.source_nodes,
65                        source_node.as_ref(),
66                    )
67                };
68            }
69
70            unsafe {
71                let source_module_mut = Arc::as_ptr(&source_module) as *mut SourceModule;
72                (*source_module_mut).cyclic = !require_cycles.is_empty();
73            }
74
75            items.push(BuildQueueItem {
76                name: module_name.clone(),
77                human_readable_name,
78                source_node,
79                source_module,
80                config,
81                environment_scope,
82                require_cycles,
83                options: frontend_options.clone(),
84                record_json_log: FFlag::DebugLuauLogSolverToJson.get(),
85                reverse_deps: Vec::new(),
86                dirty_dependencies: 0,
87                processing: false,
88                exception: None,
89                module: Arc::new(Module::default()),
90                stats: FrontendStats::default(),
91            });
92        }
93    }
94}