packs/packs/
reference_extractor.rs1use std::{
2 collections::{HashMap, HashSet},
3 path::PathBuf,
4};
5
6use rayon::prelude::{IntoParallelRefIterator, ParallelIterator};
7use tracing::debug;
8
9use crate::packs::{
10 get_experimental_constant_resolver, get_zeitwerk_constant_resolver,
11 process_files_with_cache, ProcessedFile,
12};
13
14use super::{checker::reference::Reference, Configuration, Sigil};
15
16#[allow(clippy::type_complexity)]
20pub(crate) fn get_all_references_and_sigils(
21 configuration: &Configuration,
22 absolute_paths: &HashSet<PathBuf>,
23) -> anyhow::Result<(Vec<Reference>, HashMap<PathBuf, Vec<Sigil>>)> {
24 let cache = configuration.get_cache();
25
26 debug!("Getting unresolved references (using cache if possible)");
27
28 let (constant_resolver, processed_files_to_check) = if configuration
29 .experimental_parser
30 {
31 let all_processed_files: Vec<ProcessedFile> = process_files_with_cache(
33 &configuration.included_files,
34 cache,
35 configuration,
36 )?;
37
38 let constant_resolver = get_experimental_constant_resolver(
39 &configuration.absolute_root,
40 &all_processed_files,
41 &configuration.ignored_definitions,
42 );
43
44 let processed_files_to_check = all_processed_files
45 .into_iter()
46 .filter(|processed_file| {
47 absolute_paths.contains(&processed_file.absolute_path)
48 })
49 .collect();
50
51 (constant_resolver, processed_files_to_check)
52 } else {
53 let processed_files: Vec<ProcessedFile> =
54 process_files_with_cache(absolute_paths, cache, configuration)?;
55
56 let constant_resolver = get_zeitwerk_constant_resolver(
58 &configuration.pack_set,
59 &configuration.constant_resolver_configuration(),
60 );
61
62 (constant_resolver, processed_files)
63 };
64
65 debug!("Getting sigils");
68 let mut path_to_sigils: HashMap<PathBuf, Vec<Sigil>> = HashMap::new();
69 for processed_file in &processed_files_to_check {
70 if !processed_file.sigils.is_empty() {
71 path_to_sigils.insert(
72 processed_file.absolute_path.to_owned(),
73 processed_file.sigils.to_owned(),
74 );
75 }
76 }
77
78 debug!("Turning unresolved references into fully qualified references");
79 let references: anyhow::Result<Vec<Reference>> = processed_files_to_check
80 .par_iter()
81 .try_fold(
82 Vec::new,
83 |mut acc, processed_file| {
85 for unresolved_ref in &processed_file.unresolved_references {
87 let mut refs = Reference::from_unresolved_reference(
88 configuration,
89 constant_resolver.as_ref(),
90 unresolved_ref,
91 &processed_file.absolute_path,
92 )?;
93 acc.append(&mut refs); }
95 Ok(acc)
96 },
97 )
98 .try_reduce(
99 Vec::new, |mut acc, mut vec| {
101 acc.append(&mut vec); Ok(acc)
104 },
105 );
106 debug!("Finished turning unresolved references into fully qualified references");
107
108 Ok((references?, path_to_sigils))
109}