use crate::engine::code::function::UnlinkedFunction;
use crate::engine::value::JsString;
pub const MODULE_DEFAULT_BINDING_NAME: &str = "<module-default>";
pub const MODULE_IMPORT_META_BINDING_NAME: &str = "<import.meta>";
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct ModuleRequestIndex(pub u32);
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ModuleImportAttribute {
pub key: JsString,
pub value: JsString,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ModuleImportAttributes {
Absent,
Present(Box<[ModuleImportAttribute]>),
}
impl ModuleImportAttributes {
#[must_use]
pub fn effective(&self) -> Option<&[ModuleImportAttribute]> {
match self {
Self::Present(attributes) if !attributes.is_empty() => Some(attributes),
Self::Absent | Self::Present(_) => None,
}
}
#[must_use]
pub fn syntactic(&self) -> Option<&[ModuleImportAttribute]> {
match self {
Self::Absent => None,
Self::Present(attributes) => Some(attributes),
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ModuleRequest {
pub specifier: JsString,
pub attributes: ModuleImportAttributes,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ModuleImport {
pub request: ModuleRequestIndex,
pub import_name: ModuleImportName,
pub closure_index: u16,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ModuleImportName {
Name(JsString),
Namespace,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ModuleLinkInitializerValue {
Undefined,
Function {
constant: u32,
inferred_name: Option<u32>,
},
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ModuleLinkInitializer {
pub closure_index: u16,
pub value: ModuleLinkInitializerValue,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ModuleImportCollision {
pub closure_index: u16,
pub declaration: ModuleImportCollisionDeclaration,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ModuleImportCollisionDeclaration {
Var,
Lexical,
Function,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ModuleExportTarget {
Local { closure_index: u16 },
Indirect {
request: ModuleRequestIndex,
import_name: ModuleImportName,
},
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ModuleExport {
pub export_name: JsString,
pub target: ModuleExportTarget,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ModuleStarExport {
pub request: ModuleRequestIndex,
}
#[derive(Debug)]
pub struct UnlinkedModule {
function: UnlinkedFunction,
has_top_level_await: bool,
declaration_order: Box<[u16]>,
link_initializers: Box<[ModuleLinkInitializer]>,
import_collisions: Box<[ModuleImportCollision]>,
requested_modules: Box<[ModuleRequest]>,
imports: Box<[ModuleImport]>,
exports: Box<[ModuleExport]>,
star_exports: Box<[ModuleStarExport]>,
}
pub struct UnlinkedModuleTables {
pub declaration_order: Vec<u16>,
pub link_initializers: Vec<ModuleLinkInitializer>,
pub import_collisions: Vec<ModuleImportCollision>,
pub requested_modules: Vec<ModuleRequest>,
pub imports: Vec<ModuleImport>,
pub exports: Vec<ModuleExport>,
pub star_exports: Vec<ModuleStarExport>,
}
impl UnlinkedModule {
#[must_use]
pub fn new(
function: UnlinkedFunction,
has_top_level_await: bool,
tables: UnlinkedModuleTables,
) -> Self {
let UnlinkedModuleTables {
declaration_order,
link_initializers,
import_collisions,
requested_modules,
imports,
exports,
star_exports,
} = tables;
Self {
function,
has_top_level_await,
declaration_order: declaration_order.into_boxed_slice(),
link_initializers: link_initializers.into_boxed_slice(),
import_collisions: import_collisions.into_boxed_slice(),
requested_modules: requested_modules.into_boxed_slice(),
imports: imports.into_boxed_slice(),
exports: exports.into_boxed_slice(),
star_exports: star_exports.into_boxed_slice(),
}
}
#[must_use]
#[cfg_attr(not(test), allow(dead_code))]
pub const fn function(&self) -> &UnlinkedFunction {
&self.function
}
#[must_use]
#[cfg_attr(not(test), allow(dead_code))]
pub const fn has_top_level_await(&self) -> bool {
self.has_top_level_await
}
#[must_use]
#[cfg_attr(not(test), allow(dead_code))]
pub const fn declaration_order(&self) -> &[u16] {
&self.declaration_order
}
#[must_use]
#[cfg_attr(not(test), allow(dead_code))]
pub const fn link_initializers(&self) -> &[ModuleLinkInitializer] {
&self.link_initializers
}
#[must_use]
#[cfg_attr(not(test), allow(dead_code))]
pub const fn import_collisions(&self) -> &[ModuleImportCollision] {
&self.import_collisions
}
#[must_use]
#[cfg_attr(not(test), allow(dead_code))]
pub const fn requested_modules(&self) -> &[ModuleRequest] {
&self.requested_modules
}
#[must_use]
#[cfg_attr(not(test), allow(dead_code))]
pub const fn imports(&self) -> &[ModuleImport] {
&self.imports
}
#[must_use]
#[cfg_attr(not(test), allow(dead_code))]
pub const fn exports(&self) -> &[ModuleExport] {
&self.exports
}
#[must_use]
#[cfg_attr(not(test), allow(dead_code))]
pub const fn star_exports(&self) -> &[ModuleStarExport] {
&self.star_exports
}
}