1use crate::{
2 BlockId, DeclId, FileId, ModuleId, ParseError, Span, Value, VarId, ast::ImportPatternMember,
3 engine::StateWorkingSet,
4};
5
6use crate::parser_path::ParserPath;
7use indexmap::IndexMap;
8
9pub struct ResolvedImportPattern {
10 pub decls: Vec<(Vec<u8>, DeclId)>,
11 pub modules: Vec<(Vec<u8>, ModuleId)>,
12 pub constants: Vec<(Vec<u8>, VarId)>,
13 pub constant_values: Vec<(Vec<u8>, Value)>,
16}
17
18impl ResolvedImportPattern {
19 pub fn new(
20 decls: Vec<(Vec<u8>, DeclId)>,
21 modules: Vec<(Vec<u8>, ModuleId)>,
22 constants: Vec<(Vec<u8>, VarId)>,
23 constant_values: Vec<(Vec<u8>, Value)>,
24 ) -> Self {
25 ResolvedImportPattern {
26 decls,
27 modules,
28 constants,
29 constant_values,
30 }
31 }
32}
33
34#[derive(Debug, Clone)]
36pub struct Module {
37 pub name: Vec<u8>,
38 pub decls: IndexMap<Vec<u8>, DeclId>,
39 pub submodules: IndexMap<Vec<u8>, ModuleId>,
40 pub constants: IndexMap<Vec<u8>, VarId>,
41 pub env_block: Option<BlockId>, pub main: Option<DeclId>, pub span: Option<Span>,
44 pub imported_modules: Vec<ModuleId>, pub file: Option<(ParserPath, FileId)>,
46}
47
48impl Module {
49 pub fn new(name: Vec<u8>) -> Self {
50 Module {
51 name,
52 decls: IndexMap::new(),
53 submodules: IndexMap::new(),
54 constants: IndexMap::new(),
55 env_block: None,
56 main: None,
57 span: None,
58 imported_modules: vec![],
59 file: None,
60 }
61 }
62
63 pub fn from_span(name: Vec<u8>, span: Span) -> Self {
64 Module {
65 name,
66 decls: IndexMap::new(),
67 submodules: IndexMap::new(),
68 constants: IndexMap::new(),
69 env_block: None,
70 main: None,
71 span: Some(span),
72 imported_modules: vec![],
73 file: None,
74 }
75 }
76
77 pub fn name(&self) -> Vec<u8> {
78 self.name.clone()
79 }
80
81 pub fn add_decl(&mut self, name: Vec<u8>, decl_id: DeclId) -> Option<DeclId> {
82 self.decls.insert(name, decl_id)
83 }
84
85 pub fn add_submodule(&mut self, name: Vec<u8>, module_id: ModuleId) -> Option<ModuleId> {
86 self.submodules.insert(name, module_id)
87 }
88
89 pub fn add_variable(&mut self, name: Vec<u8>, var_id: VarId) -> Option<VarId> {
90 self.constants.insert(name, var_id)
91 }
92
93 pub fn add_env_block(&mut self, block_id: BlockId) {
94 self.env_block = Some(block_id);
95 }
96
97 pub fn track_imported_modules(&mut self, module_id: &[ModuleId]) {
98 for m in module_id {
99 self.imported_modules.push(*m)
100 }
101 }
102
103 pub fn has_decl(&self, name: &[u8]) -> bool {
104 if name == self.name && self.main.is_some() {
105 return true;
106 }
107
108 self.decls.contains_key(name)
109 }
110
111 pub fn resolve_import_pattern(
115 &self,
116 working_set: &StateWorkingSet,
117 self_id: ModuleId,
118 members: &[ImportPatternMember],
119 name_override: Option<&[u8]>, backup_span: Span,
121 imported_modules: &mut Vec<ModuleId>,
122 ) -> (ResolvedImportPattern, Vec<ParseError>) {
123 imported_modules.push(self_id);
124 let final_name = name_override.unwrap_or(&self.name).to_vec();
125
126 let (head, rest) = if let Some((head, rest)) = members.split_first() {
127 (head, rest)
128 } else {
129 let mut decls = vec![];
131 let mut const_rows = vec![];
132 let mut errors = vec![];
133
134 for (_, id) in &self.submodules {
135 let submodule = working_set.get_module(*id);
136 let span = submodule.span.or(self.span).unwrap_or(backup_span);
137
138 let (sub_results, sub_errors) = submodule.resolve_import_pattern(
139 working_set,
140 *id,
141 &[],
142 None,
143 span,
144 imported_modules,
145 );
146 errors.extend(sub_errors);
147
148 for (sub_name, sub_decl_id) in sub_results.decls {
149 let mut new_name = final_name.clone();
150 new_name.push(b' ');
151 new_name.extend(sub_name);
152
153 decls.push((new_name, sub_decl_id));
154 }
155
156 const_rows.extend(sub_results.constant_values);
157 }
158
159 decls.extend(self.decls_with_head(&final_name));
160
161 for (name, var_id) in self.consts() {
162 match working_set.get_constant(var_id) {
163 Ok(const_val) => const_rows.push((name, const_val.clone())),
164 Err(err) => errors.push(err),
165 }
166 }
167
168 let span = self.span.unwrap_or(backup_span);
169
170 let constant_values = if const_rows.is_empty() {
172 vec![]
173 } else {
174 vec![(
175 normalize_module_name(&final_name),
176 Value::record(
177 const_rows
178 .into_iter()
179 .map(|(name, val)| (String::from_utf8_lossy(&name).to_string(), val))
180 .collect(),
181 span,
182 ),
183 )]
184 };
185
186 return (
187 ResolvedImportPattern::new(
188 decls,
189 vec![(final_name.clone(), self_id)],
190 vec![],
191 constant_values,
192 ),
193 errors,
194 );
195 };
196
197 match head {
198 ImportPatternMember::Name { name, span } => {
199 let errors = if !rest.is_empty() && self.submodules.get(name).is_none() {
202 vec![ParseError::WrongImportPattern(
203 format!(
204 "Trying to import something but the parent `{}` is not a module, maybe you want to try `use <module> [<name1>, <name2>]`",
205 String::from_utf8_lossy(name)
206 ),
207 rest[0].span(),
208 )]
209 } else {
210 vec![]
211 };
212
213 if name == b"main" {
214 if let Some(main_decl_id) = self.main {
215 (
216 ResolvedImportPattern::new(
217 vec![(final_name, main_decl_id)],
218 vec![],
219 vec![],
220 vec![],
221 ),
222 errors,
223 )
224 } else {
225 (
226 ResolvedImportPattern::new(vec![], vec![], vec![], vec![]),
227 vec![ParseError::ExportNotFound(*span)],
228 )
229 }
230 } else if let Some(decl_id) = self.decls.get(name) {
231 (
232 ResolvedImportPattern::new(
233 vec![(name.clone(), *decl_id)],
234 vec![],
235 vec![],
236 vec![],
237 ),
238 errors,
239 )
240 } else if let Some(var_id) = self.constants.get(name) {
241 match working_set.get_constant(*var_id) {
242 Ok(_) => (
243 ResolvedImportPattern::new(
244 vec![],
245 vec![],
246 vec![(name.clone(), *var_id)],
247 vec![],
248 ),
249 errors,
250 ),
251 Err(err) => (
252 ResolvedImportPattern::new(vec![], vec![], vec![], vec![]),
253 vec![err],
254 ),
255 }
256 } else if let Some(submodule_id) = self.submodules.get(name) {
257 let submodule = working_set.get_module(*submodule_id);
258 submodule.resolve_import_pattern(
259 working_set,
260 *submodule_id,
261 rest,
262 None,
263 self.span.unwrap_or(backup_span),
264 imported_modules,
265 )
266 } else {
267 (
268 ResolvedImportPattern::new(vec![], vec![], vec![], vec![]),
269 vec![ParseError::ExportNotFound(*span)],
270 )
271 }
272 }
273 ImportPatternMember::Glob { .. } => {
274 let mut decls = vec![];
275 let mut submodules = vec![];
276 let mut constants = vec![];
277 let mut constant_values = vec![];
278 let mut errors = vec![];
279
280 for (_, id) in &self.submodules {
281 let submodule = working_set.get_module(*id);
282 let (sub_results, sub_errors) = submodule.resolve_import_pattern(
283 working_set,
284 *id,
285 &[],
286 None,
287 self.span.unwrap_or(backup_span),
288 imported_modules,
289 );
290 decls.extend(sub_results.decls);
291
292 submodules.extend(sub_results.modules);
293 constants.extend(sub_results.constants);
294 constant_values.extend(sub_results.constant_values);
295 errors.extend(sub_errors);
296 }
297
298 decls.extend(self.decls());
299 for (name, var_id) in self.constants.iter() {
300 match working_set.get_constant(*var_id) {
301 Ok(_) => {
302 constants.push((name.clone(), *var_id));
303 }
304 Err(err) => {
305 errors.push(err);
306 }
307 }
308 }
309 submodules.extend(self.submodules());
310
311 (
312 ResolvedImportPattern::new(decls, submodules, constants, constant_values),
313 errors,
314 )
315 }
316 ImportPatternMember::List { names } => {
317 let mut decls = vec![];
318 let mut modules = vec![];
319 let mut constants = vec![];
320 let mut constant_values = vec![];
321 let mut errors = vec![];
322
323 for (name, span) in names {
324 if name == b"main" {
325 if let Some(main_decl_id) = self.main {
326 decls.push((final_name.clone(), main_decl_id));
327 } else {
328 errors.push(ParseError::ExportNotFound(*span));
329 }
330 } else if let Some(decl_id) = self.decls.get(name) {
331 decls.push((name.clone(), *decl_id));
332 } else if let Some(var_id) = self.constants.get(name) {
333 match working_set.get_constant(*var_id) {
334 Ok(_) => constants.push((name.clone(), *var_id)),
335 Err(err) => errors.push(err),
336 }
337 } else if let Some(submodule_id) = self.submodules.get(name) {
338 let submodule = working_set.get_module(*submodule_id);
339 let (sub_results, sub_errors) = submodule.resolve_import_pattern(
340 working_set,
341 *submodule_id,
342 rest,
343 None,
344 self.span.unwrap_or(backup_span),
345 imported_modules,
346 );
347
348 decls.extend(sub_results.decls);
349 modules.extend(sub_results.modules);
350 constants.extend(sub_results.constants);
351 constant_values.extend(sub_results.constant_values);
352 errors.extend(sub_errors);
353 } else {
354 errors.push(ParseError::ExportNotFound(*span));
355 }
356 }
357
358 (
359 ResolvedImportPattern::new(decls, modules, constants, constant_values),
360 errors,
361 )
362 }
363 }
364 }
365
366 pub fn decl_name_with_head(&self, name: &[u8], head: &[u8]) -> Option<Vec<u8>> {
367 if self.has_decl(name) {
368 let mut new_name = head.to_vec();
369 new_name.push(b' ');
370 new_name.extend(name);
371 Some(new_name)
372 } else {
373 None
374 }
375 }
376
377 pub fn decls_with_head(&self, head: &[u8]) -> Vec<(Vec<u8>, DeclId)> {
378 let mut result: Vec<(Vec<u8>, DeclId)> = self
379 .decls
380 .iter()
381 .map(|(name, id)| {
382 let mut new_name = head.to_vec();
383 new_name.push(b' ');
384 new_name.extend(name);
385 (new_name, *id)
386 })
387 .collect();
388
389 if let Some(decl_id) = self.main {
390 result.push((self.name.clone(), decl_id));
391 }
392
393 result
394 }
395
396 pub fn consts(&self) -> Vec<(Vec<u8>, VarId)> {
397 self.constants
398 .iter()
399 .map(|(name, id)| (name.to_vec(), *id))
400 .collect()
401 }
402
403 pub fn decl_names_with_head(&self, head: &[u8]) -> Vec<Vec<u8>> {
404 let mut result: Vec<Vec<u8>> = self
405 .decls
406 .keys()
407 .map(|name| {
408 let mut new_name = head.to_vec();
409 new_name.push(b' ');
410 new_name.extend(name);
411 new_name
412 })
413 .collect();
414
415 if self.main.is_some() {
416 result.push(self.name.clone());
417 }
418
419 result
420 }
421
422 pub fn decls(&self) -> Vec<(Vec<u8>, DeclId)> {
423 let mut result: Vec<(Vec<u8>, DeclId)> = self
424 .decls
425 .iter()
426 .map(|(name, id)| (name.clone(), *id))
427 .collect();
428
429 if let Some(decl_id) = self.main {
430 result.push((self.name.clone(), decl_id));
431 }
432
433 result
434 }
435
436 pub fn submodules(&self) -> Vec<(Vec<u8>, ModuleId)> {
437 self.submodules
438 .iter()
439 .map(|(name, id)| (name.clone(), *id))
440 .collect()
441 }
442
443 pub fn decl_names(&self) -> Vec<Vec<u8>> {
444 let mut result: Vec<Vec<u8>> = self.decls.keys().cloned().collect();
445
446 if self.main.is_some() {
447 result.push(self.name.clone());
448 }
449
450 result
451 }
452}
453
454fn normalize_module_name(bytes: &[u8]) -> Vec<u8> {
456 bytes
457 .iter()
458 .map(|x| match is_identifier_byte(*x) {
459 true => *x,
460 false => b'_',
461 })
462 .collect()
463}
464
465fn is_identifier_byte(b: u8) -> bool {
466 b != b'.'
467 && b != b'['
468 && b != b'('
469 && b != b'{'
470 && b != b'+'
471 && b != b'-'
472 && b != b'*'
473 && b != b'^'
474 && b != b'/'
475 && b != b'='
476 && b != b'!'
477 && b != b'<'
478 && b != b'>'
479 && b != b'&'
480 && b != b'|'
481}