use super::function::{
AsyncFunctionDeclaration, AsyncGeneratorDeclaration, FunctionDeclaration, GeneratorDeclaration,
};
use crate::{
function::ClassDeclaration,
visitor::{VisitWith, Visitor, VisitorMut},
};
use boa_interner::{Interner, Sym, ToIndentedString, ToInternedString};
use core::ops::ControlFlow;
mod export;
mod import;
mod variable;
pub use export::*;
pub use import::*;
pub use variable::*;
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[derive(Clone, Debug, PartialEq)]
pub enum Declaration {
FunctionDeclaration(FunctionDeclaration),
GeneratorDeclaration(GeneratorDeclaration),
AsyncFunctionDeclaration(AsyncFunctionDeclaration),
AsyncGeneratorDeclaration(AsyncGeneratorDeclaration),
ClassDeclaration(Box<ClassDeclaration>),
Lexical(LexicalDeclaration),
}
impl ToIndentedString for Declaration {
fn to_indented_string(&self, interner: &Interner, indentation: usize) -> String {
match self {
Self::FunctionDeclaration(f) => f.to_indented_string(interner, indentation),
Self::GeneratorDeclaration(g) => g.to_indented_string(interner, indentation),
Self::AsyncFunctionDeclaration(af) => af.to_indented_string(interner, indentation),
Self::AsyncGeneratorDeclaration(ag) => ag.to_indented_string(interner, indentation),
Self::ClassDeclaration(c) => c.to_indented_string(interner, indentation),
Self::Lexical(l) => {
let mut s = l.to_interned_string(interner);
s.push(';');
s
}
}
}
}
impl VisitWith for Declaration {
fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow<V::BreakTy>
where
V: Visitor<'a>,
{
match self {
Self::FunctionDeclaration(f) => visitor.visit_function_declaration(f),
Self::GeneratorDeclaration(g) => visitor.visit_generator_declaration(g),
Self::AsyncFunctionDeclaration(af) => visitor.visit_async_function_declaration(af),
Self::AsyncGeneratorDeclaration(ag) => visitor.visit_async_generator_declaration(ag),
Self::ClassDeclaration(c) => visitor.visit_class_declaration(c),
Self::Lexical(ld) => visitor.visit_lexical_declaration(ld),
}
}
fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow<V::BreakTy>
where
V: VisitorMut<'a>,
{
match self {
Self::FunctionDeclaration(f) => visitor.visit_function_declaration_mut(f),
Self::GeneratorDeclaration(g) => visitor.visit_generator_declaration_mut(g),
Self::AsyncFunctionDeclaration(af) => visitor.visit_async_function_declaration_mut(af),
Self::AsyncGeneratorDeclaration(ag) => {
visitor.visit_async_generator_declaration_mut(ag)
}
Self::ClassDeclaration(c) => visitor.visit_class_declaration_mut(c),
Self::Lexical(ld) => visitor.visit_lexical_declaration_mut(ld),
}
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[derive(Clone, Debug, Copy, PartialEq, Eq)]
pub struct ModuleSpecifier {
module: Sym,
}
impl ModuleSpecifier {
#[must_use]
pub const fn new(module: Sym) -> Self {
Self { module }
}
#[inline]
#[must_use]
pub const fn sym(self) -> Sym {
self.module
}
}
impl From<Sym> for ModuleSpecifier {
#[inline]
fn from(module: Sym) -> Self {
Self::new(module)
}
}
impl VisitWith for ModuleSpecifier {
fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow<V::BreakTy>
where
V: Visitor<'a>,
{
visitor.visit_sym(&self.module)
}
fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow<V::BreakTy>
where
V: VisitorMut<'a>,
{
visitor.visit_sym_mut(&mut self.module)
}
}