Skip to main content

luaur_analysis/functions/
accumulate_errors.rs

1use 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}