nu_protocol/engine/
overlay.rs

1use crate::{DeclId, ModuleId, OverlayId, VarId};
2use std::collections::HashMap;
3
4pub static DEFAULT_OVERLAY_NAME: &str = "zero";
5
6/// Tells whether a decl is visible or not
7#[derive(Debug, Clone)]
8pub struct Visibility {
9    decl_ids: HashMap<DeclId, bool>,
10}
11
12impl Visibility {
13    pub fn new() -> Self {
14        Visibility {
15            decl_ids: HashMap::new(),
16        }
17    }
18
19    pub fn is_decl_id_visible(&self, decl_id: &DeclId) -> bool {
20        *self.decl_ids.get(decl_id).unwrap_or(&true) // by default it's visible
21    }
22
23    pub fn hide_decl_id(&mut self, decl_id: &DeclId) {
24        self.decl_ids.insert(*decl_id, false);
25    }
26
27    pub fn use_decl_id(&mut self, decl_id: &DeclId) {
28        self.decl_ids.insert(*decl_id, true);
29    }
30
31    /// Overwrite own values with the other
32    pub fn merge_with(&mut self, other: Visibility) {
33        self.decl_ids.extend(other.decl_ids);
34    }
35
36    /// Take new values from the other but keep own values
37    pub fn append(&mut self, other: &Visibility) {
38        for (decl_id, visible) in other.decl_ids.iter() {
39            if !self.decl_ids.contains_key(decl_id) {
40                self.decl_ids.insert(*decl_id, *visible);
41            }
42        }
43    }
44}
45
46#[derive(Debug, Clone)]
47pub struct ScopeFrame {
48    /// List of both active and inactive overlays in this ScopeFrame.
49    ///
50    /// The order does not have any meaning. Indexed locally (within this ScopeFrame) by
51    /// OverlayIds in active_overlays.
52    pub overlays: Vec<(Vec<u8>, OverlayFrame)>,
53
54    /// List of currently active overlays.
55    ///
56    /// Order is significant: The last item points at the last activated overlay.
57    pub active_overlays: Vec<OverlayId>,
58
59    /// Removed overlays from previous scope frames / permanent state
60    pub removed_overlays: Vec<Vec<u8>>,
61
62    /// temporary storage for predeclarations
63    pub predecls: HashMap<Vec<u8>, DeclId>,
64}
65
66impl ScopeFrame {
67    pub fn new() -> Self {
68        Self {
69            overlays: vec![],
70            active_overlays: vec![],
71            removed_overlays: vec![],
72            predecls: HashMap::new(),
73        }
74    }
75
76    pub fn with_empty_overlay(name: Vec<u8>, origin: ModuleId, prefixed: bool) -> Self {
77        Self {
78            overlays: vec![(name, OverlayFrame::from_origin(origin, prefixed))],
79            active_overlays: vec![OverlayId::new(0)],
80            removed_overlays: vec![],
81            predecls: HashMap::new(),
82        }
83    }
84
85    pub fn get_var(&self, var_name: &[u8]) -> Option<&VarId> {
86        for overlay_id in self.active_overlays.iter().rev() {
87            if let Some(var_id) = self
88                .overlays
89                .get(overlay_id.get())
90                .expect("internal error: missing overlay")
91                .1
92                .vars
93                .get(var_name)
94            {
95                return Some(var_id);
96            }
97        }
98
99        None
100    }
101
102    pub fn active_overlay_ids(&self, removed_overlays: &mut Vec<Vec<u8>>) -> Vec<OverlayId> {
103        for name in &self.removed_overlays {
104            if !removed_overlays.contains(name) {
105                removed_overlays.push(name.clone());
106            }
107        }
108
109        self.active_overlays
110            .iter()
111            .filter(|id| {
112                !removed_overlays
113                    .iter()
114                    .any(|name| name == self.get_overlay_name(**id))
115            })
116            .copied()
117            .collect()
118    }
119
120    pub fn active_overlays<'a, 'b>(
121        &'b self,
122        removed_overlays: &'a mut Vec<Vec<u8>>,
123    ) -> impl DoubleEndedIterator<Item = &'b OverlayFrame> + 'a
124    where
125        'b: 'a,
126    {
127        self.active_overlay_ids(removed_overlays)
128            .into_iter()
129            .map(|id| self.get_overlay(id))
130    }
131
132    pub fn active_overlay_names(&self, removed_overlays: &mut Vec<Vec<u8>>) -> Vec<&[u8]> {
133        self.active_overlay_ids(removed_overlays)
134            .iter()
135            .map(|id| self.get_overlay_name(*id))
136            .collect()
137    }
138
139    pub fn get_overlay_name(&self, overlay_id: OverlayId) -> &[u8] {
140        &self
141            .overlays
142            .get(overlay_id.get())
143            .expect("internal error: missing overlay")
144            .0
145    }
146
147    pub fn get_overlay(&self, overlay_id: OverlayId) -> &OverlayFrame {
148        &self
149            .overlays
150            .get(overlay_id.get())
151            .expect("internal error: missing overlay")
152            .1
153    }
154
155    pub fn get_overlay_mut(&mut self, overlay_id: OverlayId) -> &mut OverlayFrame {
156        &mut self
157            .overlays
158            .get_mut(overlay_id.get())
159            .expect("internal error: missing overlay")
160            .1
161    }
162
163    pub fn find_overlay(&self, name: &[u8]) -> Option<OverlayId> {
164        self.overlays
165            .iter()
166            .position(|(n, _)| n == name)
167            .map(OverlayId::new)
168    }
169
170    pub fn find_active_overlay(&self, name: &[u8]) -> Option<OverlayId> {
171        self.overlays
172            .iter()
173            .position(|(n, _)| n == name)
174            .map(OverlayId::new)
175            .filter(|id| self.active_overlays.contains(id))
176    }
177}
178
179#[derive(Debug, Clone)]
180pub struct OverlayFrame {
181    pub vars: HashMap<Vec<u8>, VarId>,
182    pub predecls: HashMap<Vec<u8>, DeclId>, // temporary storage for predeclarations
183    pub decls: HashMap<Vec<u8>, DeclId>,
184    pub modules: HashMap<Vec<u8>, ModuleId>,
185    pub visibility: Visibility,
186    pub origin: ModuleId, // The original module the overlay was created from
187    pub prefixed: bool,   // Whether the overlay has definitions prefixed with its name
188}
189
190impl OverlayFrame {
191    pub fn from_origin(origin: ModuleId, prefixed: bool) -> Self {
192        Self {
193            vars: HashMap::new(),
194            predecls: HashMap::new(),
195            decls: HashMap::new(),
196            modules: HashMap::new(),
197            visibility: Visibility::new(),
198            origin,
199            prefixed,
200        }
201    }
202
203    pub fn insert_decl(&mut self, name: Vec<u8>, decl_id: DeclId) -> Option<DeclId> {
204        self.decls.insert(name, decl_id)
205    }
206
207    pub fn insert_module(&mut self, name: Vec<u8>, module_id: ModuleId) -> Option<ModuleId> {
208        self.modules.insert(name, module_id)
209    }
210
211    pub fn insert_variable(&mut self, name: Vec<u8>, variable_id: VarId) -> Option<VarId> {
212        self.vars.insert(name, variable_id)
213    }
214
215    pub fn get_decl(&self, name: &[u8]) -> Option<DeclId> {
216        self.decls.get(name).cloned()
217    }
218}
219
220impl Default for Visibility {
221    fn default() -> Self {
222        Self::new()
223    }
224}
225
226impl Default for ScopeFrame {
227    fn default() -> Self {
228        Self::new()
229    }
230}