1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
use crate::functions::accumulate_errors::accumulate_errors;
use crate::records::check_result::CheckResult;
use crate::records::frontend::Frontend;
use crate::records::internal_compiler_error::InternalCompilerError;
use crate::records::source_node::SourceNode;
use crate::type_aliases::module_name_file_resolver::ModuleName;
use crate::type_aliases::module_ptr_module_resolver::ModulePtr;
use alloc::collections::BTreeMap;
use alloc::string::String;
use alloc::sync::Arc;
impl Frontend {
pub fn get_check_result(
&self,
name: &ModuleName,
accumulate_nested: bool,
for_autocomplete: bool,
) -> Option<CheckResult> {
// C++: if (getLuauSolverMode() == SolverMode::New) forAutocomplete = false;
let mut for_autocomplete = for_autocomplete;
if self.get_luau_solver_mode() == crate::enums::solver_mode::SolverMode::New {
for_autocomplete = false;
}
// C++: auto it = sourceNodes.find(name);
// if (it == sourceNodes.end() || it->second->hasDirtyModule(forAutocomplete)) return std::nullopt;
match self.source_nodes.get(name) {
None => return None,
Some(node) => {
if node.has_dirty_module(for_autocomplete) {
return None;
}
}
}
let resolver = if for_autocomplete {
&self.module_resolver_for_autocomplete
} else {
&self.module_resolver
};
// C++: ModulePtr module = resolver.getModule(name);
// if (module == nullptr) throw InternalCompilerError(...)
// In this port, ModulePtr = Arc<Module> (a non-nullable shared pointer),
// so getModule never yields a null module; the nullptr branch is therefore
// statically unreachable and the throw cannot fire. We still surface the
// intended diagnostic shape by routing through getModule.
let module: ModulePtr = resolver.get_module(name);
let _ = || {
// preserve the C++ diagnostic construction for reference/parity
InternalCompilerError::internal_compiler_error_string_string(
String::from("Frontend does not have module: "),
name.clone(),
)
};
let mut check_result = CheckResult::default();
// C++: if (module->timeout) checkResult.timeoutHits.push_back(name);
if module.timeout {
check_result.timeout_hits.push(name.clone());
}
if accumulate_nested {
// C++: checkResult.errors = accumulateErrors(sourceNodes, resolver, name);
// `sourceNodes` is stored as a HashMap here but accumulateErrors takes a
// std::unordered_map (modeled as BTreeMap); build that view.
let source_nodes_map: BTreeMap<ModuleName, Arc<SourceNode>> = self
.source_nodes
.iter()
.map(|(k, v)| (k.clone(), v.clone()))
.collect();
check_result.errors = accumulate_errors(&source_nodes_map, resolver, name);
} else {
// C++: checkResult.errors.insert(end, module->errors.begin(), module->errors.end());
check_result.errors.extend(module.errors.iter().cloned());
}
// C++: checkResult.lintResult = module->lintResult;
check_result.lint_result = module.lint_result.clone();
Some(check_result)
}
}