kind_pass/expand/
uses.rs

1use fxhash::FxHashMap;
2use kind_report::data::Diagnostic;
3use kind_tree::concrete::{visitor::Visitor, Module};
4/// Expands sum type and record definitions to a lot of
5/// helper definitions like eliminators and replace qualified identifiers
6/// by their module names.
7use std::sync::mpsc::Sender;
8
9use crate::diagnostic::PassDiagnostic;
10
11pub struct Expand {
12    pub names: FxHashMap<String, String>,
13    pub errors: Sender<Box<dyn Diagnostic>>,
14    pub failed: bool,
15}
16
17impl Visitor for Expand {
18    fn visit_qualified_ident(&mut self, ident: &mut kind_tree::symbol::QualifiedIdent) {
19        if ident.get_aux().is_none() {
20            return;
21        }
22        let alias = match self.names.get(&ident.get_root()) {
23            Some(path) => path,
24            None => {
25                self.errors
26                    .send(Box::new(PassDiagnostic::CannotFindAlias(
27                        ident.get_root(),
28                        ident.range,
29                    )))
30                    .unwrap();
31                self.failed = true;
32                return;
33            }
34        };
35        match &ident.get_aux() {
36            Some(post) if post.is_empty() => {
37                ident.change_root(alias.to_string());
38                ident.reset_aux()
39            }
40            Some(post) => {
41                ident.change_root(format!("{}.{}", alias, post));
42                ident.reset_aux()
43            }
44            None => ident.change_root(alias.clone()),
45        }
46    }
47}
48
49pub fn expand_uses(module: &mut Module, errors: Sender<Box<dyn Diagnostic>>) -> bool {
50    let mut session = Expand {
51        names: module.uses.clone(),
52        errors,
53        failed: false,
54    };
55    for entry in module.entries.iter_mut() {
56        session.visit_top_level(entry)
57    }
58    session.failed
59}