lutra_compiler/project/
mod.rs1mod analysis;
2mod source_tree;
3
4pub use analysis::{SymbolInfo, TargetMap, TargetSpan};
5pub(crate) use source_tree::SourceProvider;
6pub use source_tree::{SourceOverlay, SourceTree};
7
8use std::sync::Arc;
9
10use crate::pr;
11
12#[derive(Debug)]
14pub struct Project {
15 pub source: SourceTree,
17
18 pub root_module: pr::ModuleDef,
20
21 pub ordering: Vec<Vec<pr::Path>>,
24
25 pub dependencies: Vec<Dependency>,
26
27 pub target_map: analysis::TargetMap,
30}
31
32#[derive(Debug, Clone)]
33pub struct Dependency {
34 pub name: String,
35
36 pub inner: Arc<Project>,
37}
38
39impl Project {
40 pub fn get_name(&self) -> Option<&str> {
44 self.root_module
45 .get_anno_at(&pr::Path::empty(), pr::Anno::as_std_metadata)
46 }
47
48 pub fn get_runner(&self) -> Option<&str> {
50 self.root_module
51 .get_anno_at(&pr::Path::empty(), pr::Anno::as_std_runner)
52 }
53
54 pub fn find_by_anno<'a, R: 'a>(
59 &'a self,
60 matcher: impl Fn(&'a pr::Anno) -> Option<R> + Copy,
61 ) -> Vec<(pr::Path, R)> {
62 let mut result = Vec::new();
63 let empty = pr::Path::empty();
64 if let Some(r) = self.root_module.get_anno_at(&empty, matcher) {
65 result.push((empty.clone(), r));
66 }
67 find_by_anno_re(&self.root_module, matcher, empty, &mut result);
68 result
69 }
70}
71
72fn find_by_anno_re<'a, R: 'a>(
73 module: &'a pr::ModuleDef,
74 matcher: impl Fn(&'a pr::Anno) -> Option<R> + Copy,
75 mut path: pr::Path,
76 result: &mut Vec<(pr::Path, R)>,
77) {
78 for (name, def) in &module.defs {
79 path.push(name.clone());
80
81 if let Some(r) = def.get_anno(matcher) {
82 result.push((path.clone(), r));
83 }
84
85 if let pr::DefKind::Module(inner) = &def.kind {
86 find_by_anno_re(inner, matcher, path.clone(), result);
87 }
88
89 path.pop();
90 }
91}