1use super::{ImportAttribute, ModuleSpecifier, VarDeclaration};
13use crate::{
14 Declaration, Expression,
15 function::{
16 AsyncFunctionDeclaration, AsyncGeneratorDeclaration, ClassDeclaration, FunctionDeclaration,
17 GeneratorDeclaration,
18 },
19 visitor::{VisitWith, Visitor, VisitorMut},
20};
21use boa_interner::Sym;
22use std::ops::ControlFlow;
23
24#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
26#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
27#[derive(Clone, Debug, PartialEq, Eq)]
28pub enum ReExportKind {
29 Namespaced {
31 name: Option<Sym>,
33 },
34 Named {
36 names: Box<[ExportSpecifier]>,
38 },
39}
40
41impl VisitWith for ReExportKind {
42 fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow<V::BreakTy>
43 where
44 V: Visitor<'a>,
45 {
46 match self {
47 Self::Namespaced { name: Some(name) } => visitor.visit_sym(name),
48 Self::Namespaced { name: None } => ControlFlow::Continue(()),
49 Self::Named { names } => {
50 for name in &**names {
51 visitor.visit_export_specifier(name)?;
52 }
53 ControlFlow::Continue(())
54 }
55 }
56 }
57
58 fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow<V::BreakTy>
59 where
60 V: VisitorMut<'a>,
61 {
62 match self {
63 Self::Namespaced { name: Some(name) } => visitor.visit_sym_mut(name),
64 Self::Namespaced { name: None } => ControlFlow::Continue(()),
65 Self::Named { names } => {
66 for name in &mut **names {
67 visitor.visit_export_specifier_mut(name)?;
68 }
69 ControlFlow::Continue(())
70 }
71 }
72 }
73}
74
75#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
82#[derive(Clone, Debug, PartialEq)]
83pub enum ExportDeclaration {
84 ReExport {
86 kind: ReExportKind,
88 specifier: ModuleSpecifier,
90 attributes: Box<[ImportAttribute]>,
92 },
93 List(Box<[ExportSpecifier]>),
95 VarStatement(VarDeclaration),
97 Declaration(Declaration),
99 DefaultFunctionDeclaration(FunctionDeclaration),
101 DefaultGeneratorDeclaration(GeneratorDeclaration),
103 DefaultAsyncFunctionDeclaration(AsyncFunctionDeclaration),
105 DefaultAsyncGeneratorDeclaration(AsyncGeneratorDeclaration),
107 DefaultClassDeclaration(Box<ClassDeclaration>),
109 DefaultAssignmentExpression(Expression),
111}
112
113impl VisitWith for ExportDeclaration {
114 fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow<V::BreakTy>
115 where
116 V: Visitor<'a>,
117 {
118 match self {
119 Self::ReExport {
120 specifier,
121 kind,
122 attributes,
123 } => {
124 visitor.visit_module_specifier(specifier)?;
125 visitor.visit_re_export_kind(kind)?;
126 for attribute in &**attributes {
127 visitor.visit_import_attribute(attribute)?;
128 }
129 ControlFlow::Continue(())
130 }
131 Self::List(list) => {
132 for item in &**list {
133 visitor.visit_export_specifier(item)?;
134 }
135 ControlFlow::Continue(())
136 }
137 Self::VarStatement(var) => visitor.visit_var_declaration(var),
138 Self::Declaration(decl) => visitor.visit_declaration(decl),
139 Self::DefaultFunctionDeclaration(f) => visitor.visit_function_declaration(f),
140 Self::DefaultGeneratorDeclaration(g) => visitor.visit_generator_declaration(g),
141 Self::DefaultAsyncFunctionDeclaration(af) => {
142 visitor.visit_async_function_declaration(af)
143 }
144 Self::DefaultAsyncGeneratorDeclaration(ag) => {
145 visitor.visit_async_generator_declaration(ag)
146 }
147 Self::DefaultClassDeclaration(c) => visitor.visit_class_declaration(c),
148 Self::DefaultAssignmentExpression(expr) => visitor.visit_expression(expr),
149 }
150 }
151
152 fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow<V::BreakTy>
153 where
154 V: VisitorMut<'a>,
155 {
156 match self {
157 Self::ReExport {
158 specifier,
159 kind,
160 attributes,
161 } => {
162 visitor.visit_module_specifier_mut(specifier)?;
163 visitor.visit_re_export_kind_mut(kind)?;
164 for attribute in &mut **attributes {
165 visitor.visit_import_attribute_mut(attribute)?;
166 }
167 ControlFlow::Continue(())
168 }
169 Self::List(list) => {
170 for item in &mut **list {
171 visitor.visit_export_specifier_mut(item)?;
172 }
173 ControlFlow::Continue(())
174 }
175 Self::VarStatement(var) => visitor.visit_var_declaration_mut(var),
176 Self::Declaration(decl) => visitor.visit_declaration_mut(decl),
177 Self::DefaultFunctionDeclaration(f) => visitor.visit_function_declaration_mut(f),
178 Self::DefaultGeneratorDeclaration(g) => visitor.visit_generator_declaration_mut(g),
179 Self::DefaultAsyncFunctionDeclaration(af) => {
180 visitor.visit_async_function_declaration_mut(af)
181 }
182 Self::DefaultAsyncGeneratorDeclaration(ag) => {
183 visitor.visit_async_generator_declaration_mut(ag)
184 }
185 Self::DefaultClassDeclaration(c) => visitor.visit_class_declaration_mut(c),
186 Self::DefaultAssignmentExpression(expr) => visitor.visit_expression_mut(expr),
187 }
188 }
189}
190
191#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
198#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
199#[derive(Clone, Debug, Copy, PartialEq, Eq)]
200pub struct ExportSpecifier {
201 alias: Sym,
202 private_name: Sym,
203 string_literal: bool,
204}
205
206impl ExportSpecifier {
207 #[inline]
209 #[must_use]
210 pub const fn new(alias: Sym, private_name: Sym, string_literal: bool) -> Self {
211 Self {
212 alias,
213 private_name,
214 string_literal,
215 }
216 }
217
218 #[inline]
220 #[must_use]
221 pub const fn alias(self) -> Sym {
222 self.alias
223 }
224
225 #[inline]
227 #[must_use]
228 pub const fn private_name(self) -> Sym {
229 self.private_name
230 }
231
232 #[inline]
234 #[must_use]
235 pub const fn string_literal(&self) -> bool {
236 self.string_literal
237 }
238}
239
240impl VisitWith for ExportSpecifier {
241 fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow<V::BreakTy>
242 where
243 V: Visitor<'a>,
244 {
245 visitor.visit_sym(&self.alias)?;
246 visitor.visit_sym(&self.private_name)
247 }
248
249 fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow<V::BreakTy>
250 where
251 V: VisitorMut<'a>,
252 {
253 visitor.visit_sym_mut(&mut self.alias)?;
254 visitor.visit_sym_mut(&mut self.private_name)
255 }
256}
257
258#[derive(Debug, Clone, Copy)]
264pub enum ReExportImportName {
265 Name(Sym),
267 Star,
269}
270
271#[derive(Debug, Clone)]
275pub enum ExportEntry {
276 Ordinary(LocalExportEntry),
278 StarReExport {
280 module_request: Sym,
282 attributes: Box<[ImportAttribute]>,
284 },
285 ReExport(IndirectExportEntry),
287}
288
289impl From<IndirectExportEntry> for ExportEntry {
290 fn from(v: IndirectExportEntry) -> Self {
291 Self::ReExport(v)
292 }
293}
294
295impl From<LocalExportEntry> for ExportEntry {
296 fn from(v: LocalExportEntry) -> Self {
297 Self::Ordinary(v)
298 }
299}
300
301#[derive(Debug, Clone, Copy)]
303pub struct LocalExportEntry {
304 local_name: Sym,
305 export_name: Sym,
306}
307
308impl LocalExportEntry {
309 #[must_use]
311 pub const fn new(local_name: Sym, export_name: Sym) -> Self {
312 Self {
313 local_name,
314 export_name,
315 }
316 }
317
318 #[must_use]
320 pub const fn local_name(&self) -> Sym {
321 self.local_name
322 }
323
324 #[must_use]
326 pub const fn export_name(&self) -> Sym {
327 self.export_name
328 }
329}
330
331#[derive(Debug, Clone)]
333pub struct IndirectExportEntry {
334 module_request: Sym,
335 import_name: ReExportImportName,
336 export_name: Sym,
337 attributes: Box<[ImportAttribute]>,
338}
339
340impl IndirectExportEntry {
341 #[must_use]
343 pub fn new(
344 module_request: Sym,
345 import_name: ReExportImportName,
346 export_name: Sym,
347 attributes: Box<[ImportAttribute]>,
348 ) -> Self {
349 Self {
350 module_request,
351 import_name,
352 export_name,
353 attributes,
354 }
355 }
356
357 #[must_use]
359 pub const fn module_request(&self) -> Sym {
360 self.module_request
361 }
362
363 #[must_use]
365 pub const fn import_name(&self) -> ReExportImportName {
366 self.import_name
367 }
368
369 #[must_use]
371 pub const fn export_name(&self) -> Sym {
372 self.export_name
373 }
374
375 #[must_use]
377 pub fn attributes(&self) -> &[ImportAttribute] {
378 &self.attributes
379 }
380}