Skip to main content

luaur_analysis/methods/
frontend_check_frontend.rs

1use crate::functions::make_type_check_limits::make_type_check_limits;
2use crate::records::build_queue_item::BuildQueueItem;
3use crate::records::check_result::CheckResult;
4use crate::records::frontend::Frontend;
5use crate::records::frontend_options::FrontendOptions;
6use crate::records::type_check_limits::TypeCheckLimits;
7use crate::type_aliases::module_name_file_resolver::ModuleName;
8use alloc::vec::Vec;
9use luaur_common::macros::luau_assert::LUAU_ASSERT;
10use luaur_common::macros::luau_timetrace_argument::LUAU_TIMETRACE_ARGUMENT;
11use luaur_common::macros::luau_timetrace_scope::LUAU_TIMETRACE_SCOPE;
12use luaur_common::records::dense_hash_set::DenseHashSet;
13use luaur_common::FFlag;
14
15impl Frontend {
16    pub fn check_module_name_optional_frontend_options(
17        &mut self,
18        name: &ModuleName,
19        option_override: Option<FrontendOptions>,
20    ) -> CheckResult {
21        LUAU_TIMETRACE_SCOPE!("Frontend::check", "Frontend");
22        LUAU_TIMETRACE_ARGUMENT!("name", name.as_str());
23
24        let mut frontend_options = option_override.unwrap_or_else(|| self.options.clone());
25        if self.get_luau_solver_mode() == crate::enums::solver_mode::SolverMode::New {
26            frontend_options.for_autocomplete = false;
27        }
28
29        if let Some(result) = self.get_check_result(name, true, frontend_options.for_autocomplete) {
30            return result;
31        }
32
33        let mut build_queue: Vec<ModuleName> = Vec::new();
34        let cycle_detected = self.parse_graph(
35            &mut build_queue,
36            name,
37            &make_type_check_limits(&frontend_options),
38            frontend_options.for_autocomplete,
39        );
40
41        let mut seen: DenseHashSet<ModuleName> = DenseHashSet::new(ModuleName::default());
42        let mut build_queue_items: Vec<BuildQueueItem> = Vec::new();
43        self.add_build_queue_items(
44            &mut build_queue_items,
45            &build_queue,
46            cycle_detected,
47            &mut seen,
48            &frontend_options,
49        );
50        LUAU_ASSERT!(!build_queue_items.is_empty());
51
52        if FFlag::DebugLuauLogSolverToJson.get() {
53            LUAU_ASSERT!(build_queue_items.last().unwrap().name == *name);
54            build_queue_items.last_mut().unwrap().record_json_log = true;
55        }
56
57        self.check_build_queue_items(&mut build_queue_items);
58
59        let mut check_result = CheckResult::default();
60
61        for item in &build_queue_items {
62            if item.module.timeout {
63                check_result.timeout_hits.push(item.name.clone());
64            }
65
66            if item.module.cancelled {
67                return CheckResult::default();
68            }
69
70            check_result
71                .errors
72                .extend(item.module.errors.iter().cloned());
73
74            if item.name == *name {
75                check_result.lint_result = item.module.lint_result.clone();
76            }
77        }
78
79        check_result
80    }
81}