1use crate::{
29 entry::{Entry, EntryMut},
30 handle::Handle,
31 source::Source,
32 type_kind::TypeKind,
33};
34use cl_ast::{Expr, Meta, PathPart, Sym};
35use cl_structures::{index_map::IndexMap, span::Span};
36use std::collections::HashMap;
37
38#[derive(Debug)]
45pub struct Table<'a> {
46 root: Handle,
47 kinds: IndexMap<Handle, NodeKind>,
49 parents: IndexMap<Handle, Handle>,
50 pub(crate) children: HashMap<Handle, HashMap<Sym, Handle>>,
51 pub(crate) imports: HashMap<Handle, HashMap<Sym, Handle>>,
52 pub(crate) use_items: HashMap<Handle, Vec<Handle>>,
53 bodies: HashMap<Handle, &'a Expr>,
54 types: HashMap<Handle, TypeKind>,
55 spans: HashMap<Handle, Span>,
56 metas: HashMap<Handle, &'a [Meta]>,
57 sources: HashMap<Handle, Source<'a>>,
58 impl_targets: HashMap<Handle, Handle>,
59 anon_types: HashMap<TypeKind, Handle>,
60 lang_items: HashMap<&'static str, Handle>,
61
62 pub(crate) unchecked: Vec<Handle>,
64 pub(crate) impls: Vec<Handle>,
65 pub(crate) uses: Vec<Handle>,
66}
67
68impl<'a> Table<'a> {
69 pub fn new() -> Self {
70 let mut kinds = IndexMap::new();
71 let mut parents = IndexMap::new();
72 let root = kinds.insert(NodeKind::Root);
73 assert_eq!(root, parents.insert(root));
74
75 Self {
76 root,
77 kinds,
78 parents,
79 children: HashMap::new(),
80 imports: HashMap::new(),
81 use_items: HashMap::new(),
82 bodies: HashMap::new(),
83 types: HashMap::new(),
84 spans: HashMap::new(),
85 metas: HashMap::new(),
86 sources: HashMap::new(),
87 impl_targets: HashMap::new(),
88 anon_types: HashMap::new(),
89 lang_items: HashMap::new(),
90 unchecked: Vec::new(),
91 impls: Vec::new(),
92 uses: Vec::new(),
93 }
94 }
95
96 pub fn entry(&self, handle: Handle) -> Entry<'_, 'a> {
97 handle.to_entry(self)
98 }
99
100 pub fn entry_mut(&mut self, handle: Handle) -> EntryMut<'_, 'a> {
101 handle.to_entry_mut(self)
102 }
103
104 pub fn new_entry(&mut self, parent: Handle, kind: NodeKind) -> Handle {
105 let entry = self.kinds.insert(kind);
106 assert_eq!(entry, self.parents.insert(parent));
107 entry
108 }
109
110 pub fn add_child(&mut self, parent: Handle, name: Sym, child: Handle) -> Option<Handle> {
111 self.children.entry(parent).or_default().insert(name, child)
112 }
113
114 pub fn add_import(&mut self, parent: Handle, name: Sym, import: Handle) -> Option<Handle> {
115 self.imports.entry(parent).or_default().insert(name, import)
116 }
117
118 pub fn mark_unchecked(&mut self, item: Handle) {
119 self.unchecked.push(item);
120 }
121
122 pub fn mark_use_item(&mut self, item: Handle) {
123 let parent = self.parents[item];
124 self.use_items.entry(parent).or_default().push(item);
125 self.uses.push(item);
126 }
127
128 pub fn mark_impl_item(&mut self, item: Handle) {
129 self.impls.push(item);
130 }
131
132 pub fn mark_lang_item(&mut self, name: &'static str, item: Handle) {
133 self.lang_items.insert(name, item);
134 }
135
136 pub fn get_lang_item(&self, name: &str) -> Handle {
137 match self.lang_items.get(name).copied() {
138 Some(handle) => handle,
139 None => todo!(),
140 }
141 }
142
143 pub fn handle_iter(&self) -> impl Iterator<Item = Handle> + use<> {
144 self.kinds.keys()
145 }
146
147 pub fn debug_entry_iter(&self) -> impl Iterator<Item = Entry<'_, 'a>> {
149 self.kinds.keys().map(|key| key.to_entry(self))
150 }
151
152 pub(crate) fn anon_type(&mut self, kind: TypeKind) -> Handle {
155 if let Some(id) = self.anon_types.get(&kind) {
156 return *id;
157 }
158 let entry = self.new_entry(self.root, NodeKind::Type);
159 self.types.insert(entry, kind.clone());
161 self.anon_types.insert(kind, entry);
162 entry
163 }
164
165 pub(crate) fn inferred_type(&mut self) -> Handle {
166 let handle = self.new_entry(self.root, NodeKind::Type);
167 self.types.insert(handle, TypeKind::Inferred);
168 handle
169 }
170
171 pub(crate) fn type_variable(&mut self) -> Handle {
172 let handle = self.new_entry(self.root, NodeKind::Type);
173 self.types.insert(handle, TypeKind::Variable);
174 handle
175 }
176
177 pub const fn root_entry(&self) -> Entry<'_, 'a> {
178 self.root.to_entry(self)
179 }
180
181 pub fn root_entry_mut(&mut self) -> crate::entry::EntryMut<'_, 'a> {
182 self.root.to_entry_mut(self)
183 }
184
185 pub const fn root(&self) -> Handle {
188 self.root
189 }
190
191 pub fn kind(&self, node: Handle) -> Option<&NodeKind> {
192 self.kinds.get(node)
193 }
194
195 pub fn parent(&self, node: Handle) -> Option<&Handle> {
196 self.parents.get(node)
197 }
198
199 pub fn children(&self, node: Handle) -> Option<&HashMap<Sym, Handle>> {
200 self.children.get(&node)
201 }
202
203 pub fn imports(&self, node: Handle) -> Option<&HashMap<Sym, Handle>> {
204 self.imports.get(&node)
205 }
206
207 pub fn body(&self, node: Handle) -> Option<&'a Expr> {
208 self.bodies.get(&node).copied()
209 }
210
211 pub fn ty(&self, node: Handle) -> Option<&TypeKind> {
212 self.types.get(&node)
213 }
214
215 pub fn span(&self, node: Handle) -> Option<&Span> {
216 self.spans.get(&node)
217 }
218
219 pub fn meta(&self, node: Handle) -> Option<&'a [Meta]> {
220 self.metas.get(&node).copied()
221 }
222
223 pub fn source(&self, node: Handle) -> Option<&Source<'a>> {
224 self.sources.get(&node)
225 }
226
227 pub fn impl_target(&self, node: Handle) -> Option<Handle> {
228 self.impl_targets.get(&node).copied()
229 }
230
231 pub fn reparent(&mut self, node: Handle, parent: Handle) -> Handle {
232 self.parents.replace(node, parent)
233 }
234
235 pub fn set_body(&mut self, node: Handle, body: &'a Expr) -> Option<&'a Expr> {
236 self.mark_unchecked(node);
237 self.bodies.insert(node, body)
238 }
239
240 pub fn set_ty(&mut self, node: Handle, kind: TypeKind) -> Option<TypeKind> {
241 self.types.insert(node, kind)
242 }
243
244 pub fn set_span(&mut self, node: Handle, span: Span) -> Option<Span> {
245 self.spans.insert(node, span)
246 }
247
248 pub fn set_meta(&mut self, node: Handle, meta: &'a [Meta]) -> Option<&'a [Meta]> {
249 self.metas.insert(node, meta)
250 }
251
252 pub fn set_source(&mut self, node: Handle, source: Source<'a>) -> Option<Source<'a>> {
253 self.sources.insert(node, source)
254 }
255
256 pub fn set_impl_target(&mut self, node: Handle, target: Handle) -> Option<Handle> {
257 self.impl_targets.insert(node, target)
258 }
259
260 pub fn selfty(&self, node: Handle) -> Option<Handle> {
264 match self.kinds.get(node)? {
265 NodeKind::Root | NodeKind::Use => None,
266 NodeKind::Type => Some(node),
267 NodeKind::Impl => self.impl_target(node),
268 _ => self.selfty(*self.parent(node)?),
269 }
270 }
271
272 pub fn super_of(&self, node: Handle) -> Option<Handle> {
273 match self.kinds.get(node)? {
274 NodeKind::Root => None,
275 NodeKind::Module => self.parent(node).copied(),
276 _ => self.super_of(*self.parent(node)?),
277 }
278 }
279
280 pub fn name(&self, node: Handle) -> Option<Sym> {
281 self.source(node).and_then(|s| s.name())
282 }
283
284 pub fn is_transparent(&self, node: Handle) -> bool {
285 !matches!(
286 self.kind(node),
287 None | Some(NodeKind::Root | NodeKind::Module)
288 )
289 }
290
291 pub fn get_child(&self, node: Handle, name: &Sym) -> Option<Handle> {
292 self.children.get(&node).and_then(|c| c.get(name)).copied()
293 }
294
295 pub fn get_import(&self, node: Handle, name: &Sym) -> Option<Handle> {
296 self.imports.get(&node).and_then(|i| i.get(name)).copied()
297 }
298
299 pub fn get_by_sym(&self, node: Handle, name: &Sym) -> Option<Handle> {
300 self.get_child(node, name)
301 .or_else(|| self.get_import(node, name))
302 .or_else(|| {
303 self.is_transparent(node)
304 .then(|| {
305 self.parent(node)
306 .and_then(|node| self.get_by_sym(*node, name))
307 })
308 .flatten()
309 })
310 }
311
312 pub fn nav(&self, node: Handle, path: &[PathPart]) -> Option<Handle> {
314 match path {
315 [PathPart::SuperKw, rest @ ..] => self.nav(self.super_of(node)?, rest),
316 [PathPart::SelfTy, rest @ ..] => self.nav(self.selfty(node)?, rest),
317 [PathPart::Ident(name), rest @ ..] => self.nav(self.get_by_sym(node, name)?, rest),
318 [] => Some(node),
319 }
320 }
321}
322
323impl Default for Table<'_> {
324 fn default() -> Self {
325 Self::new()
326 }
327}
328
329#[derive(Clone, Copy, Debug)]
330pub enum NodeKind {
331 Root,
332 Module,
333 Type,
334 Const,
335 Static,
336 Function,
337 Temporary,
338 Let,
339 Scope,
340 Impl,
341 Use,
342}
343
344mod display {
345 use super::*;
346 use std::fmt;
347 impl fmt::Display for NodeKind {
348 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
349 match self {
350 NodeKind::Root => write!(f, "root"),
351 NodeKind::Module => write!(f, "mod"),
352 NodeKind::Type => write!(f, "type"),
353 NodeKind::Const => write!(f, "const"),
354 NodeKind::Static => write!(f, "static"),
355 NodeKind::Function => write!(f, "fn"),
356 NodeKind::Temporary => write!(f, "temp"),
357 NodeKind::Let => write!(f, "let"),
358 NodeKind::Scope => write!(f, "scope"),
359 NodeKind::Use => write!(f, "use"),
360 NodeKind::Impl => write!(f, "impl"),
361 }
362 }
363 }
364}