microcad_lang/resolve/symbol/
symbol_definition.rs

1// Copyright © 2025 The µcad authors <info@ucad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4use crate::{builtin::*, rc::*, syntax::*, value::*};
5
6/// Symbol definition
7#[derive(Clone)]
8pub enum SymbolDefinition {
9    /// Source file symbol.
10    SourceFile(Rc<SourceFile>),
11    /// Module symbol.
12    Module(Rc<ModuleDefinition>),
13    /// Part symbol.
14    Workbench(Rc<WorkbenchDefinition>),
15    /// Function symbol.
16    Function(Rc<FunctionDefinition>),
17    /// Builtin symbol.
18    Builtin(Rc<Builtin>),
19    /// Constant.
20    Constant(Visibility, Identifier, Value),
21    /// Constant.
22    ConstExpression(Visibility, Identifier, Rc<Expression>),
23    /// Argument value.
24    Argument(Identifier, Value),
25    /// Alias of a pub use statement.
26    Alias(Visibility, Identifier, QualifiedName),
27    /// Use all available symbols in the module with the given name.
28    UseAll(Visibility, QualifiedName),
29    /// Just a dummy for testing
30    #[cfg(test)]
31    Tester(Identifier),
32}
33
34impl SymbolDefinition {
35    /// Returns ID of this definition.
36    pub fn id(&self) -> Identifier {
37        match &self {
38            Self::Workbench(w) => w.id.clone(),
39            Self::Module(m) => m.id.clone(),
40            Self::Function(f) => f.id.clone(),
41            Self::SourceFile(s) => s.id(),
42            Self::Builtin(m) => m.id(),
43            Self::Constant(_, id, _)
44            | Self::ConstExpression(_, id, _)
45            | Self::Argument(id, _)
46            | Self::Alias(_, id, _) => id.clone(),
47            Self::UseAll(..) => Identifier::none(),
48            #[cfg(test)]
49            Self::Tester(id) => id.clone(),
50        }
51    }
52
53    /// Return visibility of this symbol.
54    pub fn visibility(&self) -> Visibility {
55        match &self {
56            SymbolDefinition::SourceFile(..) | SymbolDefinition::Builtin(..) => Visibility::Public,
57
58            SymbolDefinition::Argument(..) => Visibility::Private,
59
60            SymbolDefinition::Constant(visibility, ..) => *visibility,
61            SymbolDefinition::Module(md) => md.visibility,
62            SymbolDefinition::Workbench(wd) => wd.visibility,
63            SymbolDefinition::Function(fd) => fd.visibility,
64
65            SymbolDefinition::ConstExpression(visibility, ..)
66            | SymbolDefinition::Alias(visibility, ..)
67            | SymbolDefinition::UseAll(visibility, ..) => *visibility,
68
69            #[cfg(test)]
70            SymbolDefinition::Tester(..) => Visibility::Public,
71        }
72    }
73
74    pub(crate) fn kind(&self) -> String {
75        match self {
76            Self::Workbench(w) => format!("{}", w.kind),
77            Self::Module(..) => "module".to_string(),
78            Self::Function(..) => "function".to_string(),
79            Self::SourceFile(..) => "file".to_string(),
80            Self::Builtin(..) => "builtin".to_string(),
81            Self::Constant(..) => "constant".to_string(),
82            Self::ConstExpression(..) => "const expression".to_string(),
83            Self::Argument(..) => "call argument".to_string(),
84            Self::Alias(..) => "alias".to_string(),
85            Self::UseAll(..) => "use all".to_string(),
86            #[cfg(test)]
87            Self::Tester(..) => "tester".to_string(),
88        }
89    }
90}
91
92impl std::fmt::Display for SymbolDefinition {
93    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94        match self {
95            Self::Workbench(w) => write!(f, "({})", w.kind),
96            Self::Module(..) => write!(f, "(module)"),
97            Self::Function(..) => write!(f, "(function)"),
98            Self::SourceFile(..) => write!(f, "(file)"),
99            Self::Builtin(..) => write!(f, "(builtin)"),
100            Self::Constant(.., value) => write!(f, "(constant) = {value}"),
101            Self::ConstExpression(.., value) => write!(f, "(const expression) = {value}"),
102            Self::Argument(.., value) => write!(f, "(call argument) = {value}"),
103            Self::Alias(.., name) => write!(f, "(alias) => {name}"),
104            Self::UseAll(.., name) => write!(f, "(use all) => {name}"),
105            #[cfg(test)]
106            Self::Tester(id) => write!(f, "(tester) => {id}"),
107        }
108    }
109}
110
111impl std::fmt::Debug for SymbolDefinition {
112    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
113        match self {
114            Self::Workbench(w) => write!(f, "({})", w.kind),
115            Self::Module(..) => write!(f, "(module)"),
116            Self::Function(..) => write!(f, "(function)"),
117            Self::SourceFile(..) => write!(f, "(file)"),
118            Self::Builtin(..) => write!(f, "(builtin)"),
119            Self::Constant(.., value) => write!(f, "(constant) = {value}"),
120            Self::ConstExpression(.., expr) => write!(f, "(const expression) = {expr:?}"),
121            Self::Argument(.., value) => write!(f, "(call argument) = {value}"),
122            Self::Alias(.., name) => write!(f, "(alias) => {name:?}"),
123            Self::UseAll(.., name) => write!(f, "(use all) => {name:?}"),
124            #[cfg(test)]
125            Self::Tester(id) => write!(f, "(tester) => {id:?}"),
126        }
127    }
128}