summaryrefslogtreecommitdiff
path: root/src/reports/source_hierarchy.rs
blob: f391785fae3e59b60a2c6f826a0a8af2663f3c4e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
use crate::*;


pub struct SourceHierarchy<'a> {
    pub resolver: &'a Resolver,
}

impl<'a> SourceHierarchy<'a> {
    pub fn report(&self) {
        ink!(".").eprintln();
        let len = self.resolver.root_unit_ids.len();
        for (i, id) in self.resolver.root_unit_ids.iter().enumerate() {
            let end = i + 1 == len;
            self.report_leaf(*id, Vec::new(), end);
        }
    }

    fn report_leaf(&self, id: usize, mut levels: Vec<bool>, end: bool) {
        // A level entry is true if all entries in that level have been printed.
        for level in &levels {
            match level {
                false => ink!("│   ").eprint(),
                true  => ink!("    ").eprint(),
            }
        }
        // The end value is true if all siblings of this entry have been printed.
        match end {
                false => ink!("├── ").eprint(),
                true  => ink!("└── ").eprint(),
        }
        let unit = &self.resolver.source_units[id];
        let path_str = &unit.source_unit.main.path.as_os_str().to_string_lossy();
        if let Some(name_str) = unit.source_unit.name() {
            ink!("{name_str}").eprint();
            if unit.source_unit.head.is_some() { ink!(" +head").blue().eprint() }
            if unit.source_unit.tail.is_some() { ink!(" +tail").blue().eprint() }
            let mut unresolved = 0;
            for symbol in &self.resolver.unresolved {
                if symbol.source_id == id { unresolved += 1; }
            }
            if unresolved > 0 { ink!(" ({unresolved})").red().eprint(); }
            ink!(" ({path_str})").dim().eprintln();
        } else {
            ink!("{path_str}").eprintln();
        }
        levels.push(end);
        let len = unit.child_ids.len();
        for (i, id) in unit.child_ids.iter().enumerate() {
            let end = i + 1 == len;
            self.report_leaf(*id, levels.clone(), end);
        }
    }
}