use super::collect_ops::ExportedOpsCache; use crate::interner::{Interner, Tok}; use crate::pipeline::import_abs_path::import_abs_path; use crate::representations::sourcefile::{ FileEntry, Import, Member, ModuleBlock, }; use crate::representations::tree::{ModMember, Module}; use crate::utils::iter::box_once; use crate::utils::{unwrap_or, BoxedIter, Substack}; fn member_rec( // level mod_stack: Substack>, preparsed: &Module, // object member: Member, // context path: &[Tok], ops_cache: &ExportedOpsCache, i: &Interner, ) -> Member { match member { Member::Module(ModuleBlock { name, body }) => { let subprep = unwrap_or!( &preparsed.items[&name].member => ModMember::Sub; unreachable!("This name must point to a namespace") ); let new_stack = mod_stack.push(name.clone()); let new_body = entv_rec(new_stack, subprep, body, path, ops_cache, i); Member::Module(ModuleBlock { name, body: new_body }) }, any => any, } } /// Normalize imports in the FileEntry list recursively /// /// # Panics /// /// - if a path contains too many "super" prefixes /// - if the exported operators in a module cannot be determined fn entv_rec( // level mod_stack: Substack>, preparsed: &Module, // object data: Vec, // context mod_path: &[Tok], ops_cache: &ExportedOpsCache, i: &Interner, ) -> Vec { data .into_iter() .map(|ent| match ent { FileEntry::Import(imps) => FileEntry::Import( imps .into_iter() .flat_map(|import| { if let Import { name: None, path } = import { let p = import_abs_path(mod_path, mod_stack.clone(), &path, i) .expect("Should have emerged in preparsing"); let names = (ops_cache.find(&i.i(&p))) .expect("Should have emerged in second parsing"); let imports = (names.iter()) .map(|n| Import { name: Some(n.clone()), path: path.clone() }) .collect::>(); Box::new(imports.into_iter()) as BoxedIter } else { box_once(import) } }) .collect(), ), FileEntry::Exported(mem) => FileEntry::Exported(member_rec( mod_stack.clone(), preparsed, mem, mod_path, ops_cache, i, )), FileEntry::Internal(mem) => FileEntry::Internal(member_rec( mod_stack.clone(), preparsed, mem, mod_path, ops_cache, i, )), any => any, }) .collect() } pub fn normalize_imports( preparsed: &Module, data: Vec, path: &[Tok], ops_cache: &ExportedOpsCache, i: &Interner, ) -> Vec { entv_rec(Substack::Bottom, preparsed, data, path, ops_cache, i) }