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
54
use crate::{ast::*, ast_visitor::Fold};

/// Converts relative paths into absolute paths
pub struct NormalizePaths {
    path: Path,
}

impl NormalizePaths {
    pub fn new() -> Self {
        Self { path: Path { absolute: true, parts: vec![] } }
    }
    /// Normalizes paths as if they came from within the provided paths
    pub fn in_path(path: Path) -> Self {
        Self { path }
    }
}

impl Default for NormalizePaths {
    fn default() -> Self {
        Self::new()
    }
}

impl Fold for NormalizePaths {
    fn fold_module(&mut self, m: Module) -> Module {
        let Module { name, kind } = m;
        self.path.push(PathPart::Ident(name));

        let (name, kind) = (self.fold_sym(name), self.fold_module_kind(kind));

        self.path.pop();
        Module { name, kind }
    }

    fn fold_path(&mut self, p: Path) -> Path {
        if p.absolute {
            p
        } else {
            self.path.clone().concat(&p)
        }
    }

    fn fold_use(&mut self, u: Use) -> Use {
        let Use { absolute, mut tree } = u;

        if !absolute {
            for segment in self.path.parts.iter().rev() {
                tree = UseTree::Path(segment.clone(), Box::new(tree))
            }
        }

        Use { absolute: true, tree: self.fold_use_tree(tree) }
    }
}