rune/worker/
wildcard_import.rs

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
use crate::alloc::prelude::*;
use crate::compile::{self, ErrorKind, Location, ModId, Visibility};
use crate::item::IntoComponent;
use crate::query::Query;
use crate::ItemBuf;

pub(crate) struct WildcardImport {
    pub(crate) visibility: Visibility,
    pub(crate) from: ItemBuf,
    pub(crate) name: ItemBuf,
    pub(crate) location: Location,
    pub(crate) module: ModId,
    pub(crate) found: bool,
}

impl WildcardImport {
    pub(crate) fn process_global(&mut self, query: &mut Query<'_, '_>) -> compile::Result<()> {
        if query.context.contains_prefix(&self.name)? {
            for c in query.context.iter_components(&self.name)? {
                let name = self.name.extended(c)?;

                query.insert_import(
                    &self.location,
                    self.module,
                    self.visibility,
                    &self.from,
                    &name,
                    None,
                    true,
                )?;
            }

            self.found = true;
        }

        Ok(())
    }

    /// Process a local wildcard import.
    pub(crate) fn process_local(&mut self, query: &mut Query) -> compile::Result<()> {
        if query.contains_prefix(&self.name)? {
            let components = query
                .iter_components(&self.name)?
                .map(|c| c.into_component())
                .try_collect::<Result<Vec<_>, _>>()??;

            for c in components {
                let name = self.name.extended(c)?;

                query.insert_import(
                    &self.location,
                    self.module,
                    self.visibility,
                    &self.from,
                    &name,
                    None,
                    true,
                )?;
            }

            self.found = true;
        }

        if !self.found {
            return Err(compile::Error::new(
                self.location,
                ErrorKind::MissingItem {
                    item: self.name.try_clone()?,
                },
            ));
        }

        Ok(())
    }
}