use crate::ast::*;
use crate::Error;
mod aliases;
mod deinline_import_export;
mod gensym;
mod names;
mod types;
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
pub enum Ns {
Func,
Table,
Global,
Memory,
Module,
Instance,
Tag,
Type,
}
impl Ns {
fn from_export(kind: &ExportKind) -> Ns {
match kind {
ExportKind::Func => Ns::Func,
ExportKind::Table => Ns::Table,
ExportKind::Global => Ns::Global,
ExportKind::Memory => Ns::Memory,
ExportKind::Instance => Ns::Instance,
ExportKind::Module => Ns::Module,
ExportKind::Tag => Ns::Tag,
ExportKind::Type => Ns::Type,
}
}
}
pub fn resolve<'a>(module: &mut Module<'a>) -> Result<Names<'a>, Error> {
let fields = match &mut module.kind {
ModuleKind::Text(fields) => fields,
_ => return Ok(Default::default()),
};
gensym::reset();
deinline_import_export::run(fields);
aliases::run(fields);
let mut last = None;
for field in fields.iter() {
match field {
ModuleField::Import(i) => {
if let Some(name) = last {
return Err(Error::new(i.span, format!("import after {}", name)));
}
}
ModuleField::Memory(_) => last = Some("memory"),
ModuleField::Func(_) => last = Some("function"),
ModuleField::Table(_) => last = Some("table"),
ModuleField::Global(_) => last = Some("global"),
_ => continue,
}
}
types::expand(fields);
let resolver = names::resolve(module.id, fields)?;
Ok(Names { resolver })
}
#[derive(Default)]
pub struct Names<'a> {
resolver: names::Resolver<'a>,
}
impl<'a> Names<'a> {
pub fn resolve_func(&self, idx: &mut Index<'a>) -> Result<(), Error> {
self.resolver.resolve(idx, Ns::Func)?;
Ok(())
}
pub fn resolve_memory(&self, idx: &mut Index<'a>) -> Result<(), Error> {
self.resolver.resolve(idx, Ns::Memory)?;
Ok(())
}
pub fn resolve_table(&self, idx: &mut Index<'a>) -> Result<(), Error> {
self.resolver.resolve(idx, Ns::Table)?;
Ok(())
}
pub fn resolve_global(&self, idx: &mut Index<'a>) -> Result<(), Error> {
self.resolver.resolve(idx, Ns::Global)?;
Ok(())
}
}