mod analysis;
mod source_tree;
pub use analysis::{SymbolInfo, TargetMap, TargetSpan};
pub(crate) use source_tree::SourceProvider;
pub use source_tree::{SourceOverlay, SourceTree};
use std::sync::Arc;
use crate::pr;
#[derive(Debug)]
pub struct Project {
pub source: SourceTree,
pub root_module: pr::ModuleDef,
pub ordering: Vec<Vec<pr::Path>>,
pub dependencies: Vec<Dependency>,
pub target_map: analysis::TargetMap,
}
#[derive(Debug, Clone)]
pub struct Dependency {
pub name: String,
pub inner: Arc<Project>,
}
impl Project {
pub fn get_name(&self) -> Option<&str> {
self.root_module
.get_anno_at(&pr::Path::empty(), pr::Anno::as_std_metadata)
}
pub fn get_runner(&self) -> Option<&str> {
self.root_module
.get_anno_at(&pr::Path::empty(), pr::Anno::as_std_runner)
}
pub fn find_by_anno<'a, R: 'a>(
&'a self,
matcher: impl Fn(&'a pr::Anno) -> Option<R> + Copy,
) -> Vec<(pr::Path, R)> {
let mut result = Vec::new();
let empty = pr::Path::empty();
if let Some(r) = self.root_module.get_anno_at(&empty, matcher) {
result.push((empty.clone(), r));
}
find_by_anno_re(&self.root_module, matcher, empty, &mut result);
result
}
}
fn find_by_anno_re<'a, R: 'a>(
module: &'a pr::ModuleDef,
matcher: impl Fn(&'a pr::Anno) -> Option<R> + Copy,
mut path: pr::Path,
result: &mut Vec<(pr::Path, R)>,
) {
for (name, def) in &module.defs {
path.push(name.clone());
if let Some(r) = def.get_anno(matcher) {
result.push((path.clone(), r));
}
if let pr::DefKind::Module(inner) = &def.kind {
find_by_anno_re(inner, matcher, path.clone(), result);
}
path.pop();
}
}