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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use core::fmt;

use crate::{ast::Ident, LibraryNamespace, LibraryPath, SourceSpan, Spanned};

// IMPORT
// ================================================================================================

/// Represents an import statement in Miden Assembly syntax.
#[derive(Clone)]
pub struct Import {
    /// The source span of the statement.
    pub span: SourceSpan,
    /// The local module name/alias.
    ///
    /// When the imported item is aliased to a new name, this field contains the alias, while
    /// `path.last()` can be used to obtain the actual name.
    pub name: Ident,
    /// The fully-qualified path.
    pub path: LibraryPath,
    /// The number of times this import has been used locally.
    pub uses: usize,
}

impl Import {
    /// Returns true if this import is aliased to a different name in its containing module.
    pub fn is_aliased(&self) -> bool {
        self.name.as_ref() != self.path.last()
    }

    /// Returns the namespace of the imported module.
    pub fn namespace(&self) -> &LibraryNamespace {
        self.path.namespace()
    }

    /// Returns the fully-qualified path of the imported module.
    pub fn path(&self) -> &LibraryPath {
        &self.path
    }

    /// Returns true if this import has at least one use in its containing module.
    pub fn is_used(&self) -> bool {
        self.uses > 0
    }
}

impl fmt::Debug for Import {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Import")
            .field("name", &self.name)
            .field("path", &self.path)
            .field("uses", &self.uses)
            .finish()
    }
}

impl crate::prettier::PrettyPrint for Import {
    fn render(&self) -> crate::prettier::Document {
        use crate::prettier::*;

        let mut doc = const_text("use") + const_text(".") + display(&self.path);
        if self.is_aliased() {
            doc += const_text("->") + display(&self.name);
        }
        doc
    }
}

impl Eq for Import {}

impl PartialEq for Import {
    fn eq(&self, other: &Self) -> bool {
        self.name == other.name && self.path == other.path
    }
}

impl Spanned for Import {
    fn span(&self) -> SourceSpan {
        self.span
    }
}