luaur_analysis/functions/
accumulate_errors.rs1use crate::records::frontend_module_resolver::FrontendModuleResolver;
2use crate::records::source_node::SourceNode;
3use crate::type_aliases::error_vec::ErrorVec;
4use crate::type_aliases::module_name_file_resolver::ModuleName;
5use alloc::collections::{BTreeMap, BTreeSet};
6use alloc::sync::Arc;
7use alloc::vec::Vec;
8
9pub fn accumulate_errors(
10 source_nodes: &BTreeMap<ModuleName, Arc<SourceNode>>,
11 module_resolver: &FrontendModuleResolver,
12 name: &ModuleName,
13) -> ErrorVec {
14 let mut seen: BTreeSet<ModuleName> = BTreeSet::new();
15 let mut queue: Vec<ModuleName> = vec![name.clone()];
16 let mut result = ErrorVec::new();
17
18 while let Some(next) = queue.pop() {
19 if seen.contains(&next) {
20 continue;
21 }
22 seen.insert(next.clone());
23
24 let Some(source_node) = source_nodes.get(&next) else {
25 continue;
26 };
27
28 for dependency in source_node.require_set.iter() {
29 queue.push(dependency.clone());
30 }
31
32 let module = {
33 let _lock = module_resolver.module_mutex.lock().unwrap();
34 module_resolver.modules.get(&next).cloned()
35 };
36 let Some(module) = module else {
37 continue;
38 };
39
40 let prev_size = result.len();
41 result.extend(module.errors.iter().rev().cloned());
42 result[prev_size..].sort_by(|left, right| right.location.begin.cmp(&left.location.begin));
43 }
44
45 result.reverse();
46 result
47}