microcad_lang/resolve/symbol/
symbol_definition.rs1use crate::{builtin::*, rc::*, resolve::*, src_ref::*, syntax::*, value::*};
5
6#[derive(Clone)]
8pub enum SymbolDef {
9 SourceFile(Rc<SourceFile>),
11 Module(Rc<ModuleDefinition>),
13 Workbench(Rc<WorkbenchDefinition>),
15 Function(Rc<FunctionDefinition>),
17 Assignment(Rc<Assignment>),
19 Builtin(Rc<Builtin>),
21 Constant(Visibility, Identifier, Value),
23 Argument(Identifier, Value),
25 Alias(Visibility, Identifier, QualifiedName),
27 UseAll(Visibility, QualifiedName),
29 #[cfg(test)]
31 Tester(Identifier),
32}
33
34impl SymbolDef {
35 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::Assignment(a) => a.id.clone(),
44 Self::Constant(_, id, _) | Self::Argument(id, _) | Self::Alias(_, id, _) => id.clone(),
45 Self::UseAll(..) => Identifier::none(),
46 #[cfg(test)]
47 Self::Tester(id) => id.clone(),
48 }
49 }
50
51 pub fn visibility(&self) -> Visibility {
53 match &self {
54 Self::SourceFile(..) | Self::Builtin(..) => Visibility::Public,
55
56 Self::Argument(..) => Visibility::Private,
57
58 Self::Constant(visibility, ..) => visibility.clone(),
59 Self::Module(md) => md.visibility.clone(),
60 Self::Workbench(wd) => wd.visibility.clone(),
61 Self::Function(fd) => fd.visibility.clone(),
62 Self::Assignment(a) => a.visibility.clone(),
63
64 Self::Alias(visibility, ..) | Self::UseAll(visibility, ..) => visibility.clone(),
65
66 #[cfg(test)]
67 Self::Tester(..) => Visibility::Public,
68 }
69 }
70
71 pub(crate) fn kind_str(&self) -> String {
72 match self {
73 Self::Workbench(w) => format!("{}", w.kind),
74 Self::Module(..) => "Module".to_string(),
75 Self::Function(..) => "Function".to_string(),
76 Self::SourceFile(..) => "SourceFile".to_string(),
77 Self::Builtin(b) => format!("{}", b.kind),
78 Self::Constant(..) => "Constant".to_string(),
79 Self::Assignment(..) => "Assignment".to_string(),
80 Self::Argument(..) => "Argument".to_string(),
81 Self::Alias(..) => "Alias".to_string(),
82 Self::UseAll(..) => "UseAll".to_string(),
83 #[cfg(test)]
84 Self::Tester(..) => "Tester".to_string(),
85 }
86 }
87
88 pub(crate) fn source_hash(&self) -> u64 {
89 match self {
90 Self::SourceFile(sf) => sf.hash,
91 Self::Module(md) => md.src_ref().source_hash(),
92 Self::Workbench(wd) => wd.src_ref().source_hash(),
93 Self::Function(fd) => fd.src_ref().source_hash(),
94 Self::Builtin(_) => 0,
95 Self::Assignment(a) => a.src_ref.source_hash(),
96 Self::Constant(_, id, _) | Self::Argument(id, _) | Self::Alias(_, id, _) => {
97 id.src_ref().source_hash()
98 }
99 Self::UseAll(_, name) => name.src_ref().source_hash(),
100 #[cfg(test)]
101 Self::Tester(..) => 0,
102 }
103 }
104}
105
106impl std::fmt::Display for SymbolDef {
107 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
108 let kind = self.kind_str();
109 match self {
110 Self::Workbench(..)
111 | Self::Module(..)
112 | Self::Function(..)
113 | Self::SourceFile(..)
114 | Self::Builtin(..) => write!(f, "({kind})"),
115 Self::Constant(.., value) => write!(f, "({kind}) = {value}"),
116 Self::Assignment(.., value) => write!(f, "({kind}) = {value}"),
117 Self::Argument(.., value) => write!(f, "({kind}) = {value}"),
118 Self::Alias(.., name) => write!(f, "({kind}) => {name}"),
119 Self::UseAll(.., name) => write!(f, "({kind}) => {name}"),
120 #[cfg(test)]
121 Self::Tester(id) => write!(f, "(Tester) => {id}"),
122 }
123 }
124}
125
126impl std::fmt::Debug for SymbolDef {
127 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
128 let kind = self.kind_str();
129 match self {
130 Self::Workbench(..)
131 | Self::Module(..)
132 | Self::Function(..)
133 | Self::SourceFile(..)
134 | Self::Builtin(..) => write!(f, "({kind})"),
135 Self::Constant(.., value) => write!(f, "({kind}) = {value}"),
136 Self::Assignment(.., expr) => write!(f, "({kind}) = {expr:?}"),
137 Self::Argument(.., value) => write!(f, "({kind}) = {value}"),
138 Self::Alias(.., name) => write!(f, "({kind}) => {name:?}"),
139 Self::UseAll(.., name) => write!(f, "({kind}) => {name:?}"),
140 #[cfg(test)]
141 Self::Tester(id) => write!(f, "({kind}) => {id:?}"),
142 }
143 }
144}
145
146impl Doc for SymbolDef {
147 fn doc(&self) -> Option<DocBlock> {
148 match self {
149 SymbolDef::SourceFile(sf) => sf.doc(),
150 SymbolDef::Module(md) => md.doc(),
151 SymbolDef::Workbench(wd) => wd.doc(),
152 SymbolDef::Function(fd) => fd.doc(),
153 _ => None,
154 }
155 }
156}
157
158impl Info for SymbolDef {
159 fn info(&self) -> SymbolInfo {
160 match self {
161 SymbolDef::SourceFile(sf) => sf.into(),
162 SymbolDef::Module(md) => md.into(),
163 SymbolDef::Workbench(wd) => wd.into(),
164 SymbolDef::Function(fd) => fd.into(),
165 SymbolDef::Builtin(bi) => bi.into(),
166 SymbolDef::Assignment(a) => a.into(),
167
168 SymbolDef::Constant(visibility, id, value) => {
169 SymbolInfo::new_constant(visibility, id, value)
170 }
171 SymbolDef::Argument(id, value) => SymbolInfo::new_arg(id, value),
172
173 SymbolDef::Alias(..) => unimplemented!(),
174 SymbolDef::UseAll(..) => unimplemented!(),
175
176 #[cfg(test)]
177 SymbolDef::Tester(_) => unreachable!(),
178 }
179 }
180}