boa_ast/declaration/
import.rs1use std::ops::ControlFlow;
13
14use crate::{
15 expression::Identifier,
16 visitor::{VisitWith, Visitor, VisitorMut},
17};
18use boa_interner::Sym;
19
20use super::{ImportAttribute, ModuleSpecifier};
21
22#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
24#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
25#[derive(Clone, Debug, PartialEq, Eq)]
26pub enum ImportKind {
27 DefaultOrUnnamed,
29 Namespaced {
31 binding: Identifier,
33 },
34 Named {
36 names: Box<[ImportSpecifier]>,
38 },
39}
40
41impl VisitWith for ImportKind {
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::DefaultOrUnnamed => ControlFlow::Continue(()),
48 Self::Namespaced { binding } => visitor.visit_identifier(binding),
49 Self::Named { names } => {
50 for name in &**names {
51 visitor.visit_import_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::DefaultOrUnnamed => ControlFlow::Continue(()),
64 Self::Namespaced { binding } => visitor.visit_identifier_mut(binding),
65 Self::Named { names } => {
66 for name in &mut **names {
67 visitor.visit_import_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, Eq)]
83pub struct ImportDeclaration {
84 default: Option<Identifier>,
86 kind: ImportKind,
88 specifier: ModuleSpecifier,
90 attributes: Box<[ImportAttribute]>,
92}
93
94impl ImportDeclaration {
95 #[inline]
97 #[must_use]
98 pub fn new(
99 default: Option<Identifier>,
100 kind: ImportKind,
101 specifier: ModuleSpecifier,
102 attributes: Box<[ImportAttribute]>,
103 ) -> Self {
104 Self {
105 default,
106 kind,
107 specifier,
108 attributes,
109 }
110 }
111
112 #[inline]
114 #[must_use]
115 pub const fn default(&self) -> Option<Identifier> {
116 self.default
117 }
118
119 #[inline]
121 #[must_use]
122 pub const fn specifier(&self) -> ModuleSpecifier {
123 self.specifier
124 }
125
126 #[inline]
128 #[must_use]
129 pub const fn kind(&self) -> &ImportKind {
130 &self.kind
131 }
132
133 #[inline]
135 #[must_use]
136 pub const fn attributes(&self) -> &[ImportAttribute] {
137 &self.attributes
138 }
139}
140
141impl VisitWith for ImportDeclaration {
142 fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow<V::BreakTy>
143 where
144 V: Visitor<'a>,
145 {
146 if let Some(default) = &self.default {
147 visitor.visit_identifier(default)?;
148 }
149 visitor.visit_import_kind(&self.kind)?;
150 visitor.visit_module_specifier(&self.specifier)?;
151 for attribute in &*self.attributes {
152 visitor.visit_import_attribute(attribute)?;
153 }
154 ControlFlow::Continue(())
155 }
156
157 fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow<V::BreakTy>
158 where
159 V: VisitorMut<'a>,
160 {
161 if let Some(default) = &mut self.default {
162 visitor.visit_identifier_mut(default)?;
163 }
164 visitor.visit_import_kind_mut(&mut self.kind)?;
165 visitor.visit_module_specifier_mut(&mut self.specifier)?;
166 for attribute in &mut *self.attributes {
167 visitor.visit_import_attribute_mut(attribute)?;
168 }
169 ControlFlow::Continue(())
170 }
171}
172
173#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
180#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
181#[derive(Debug, Clone, Copy, PartialEq, Eq)]
182pub struct ImportSpecifier {
183 binding: Identifier,
184 export_name: Sym,
185}
186
187impl ImportSpecifier {
188 #[inline]
190 #[must_use]
191 pub const fn new(binding: Identifier, export_name: Sym) -> Self {
192 Self {
193 binding,
194 export_name,
195 }
196 }
197
198 #[inline]
200 #[must_use]
201 pub const fn binding(self) -> Identifier {
202 self.binding
203 }
204
205 #[inline]
207 #[must_use]
208 pub const fn export_name(self) -> Sym {
209 self.export_name
210 }
211}
212
213impl VisitWith for ImportSpecifier {
214 fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow<V::BreakTy>
215 where
216 V: Visitor<'a>,
217 {
218 visitor.visit_identifier(&self.binding)?;
219 visitor.visit_sym(&self.export_name)
220 }
221
222 fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow<V::BreakTy>
223 where
224 V: VisitorMut<'a>,
225 {
226 visitor.visit_identifier_mut(&mut self.binding)?;
227 visitor.visit_sym_mut(&mut self.export_name)
228 }
229}
230
231#[derive(Debug, Clone, Copy)]
233pub enum ImportName {
234 Namespace,
236 Name(Sym),
238}
239
240#[derive(Debug, Clone)]
244pub struct ImportEntry {
245 module_request: Sym,
246 import_name: ImportName,
247 local_name: Identifier,
248 attributes: Box<[ImportAttribute]>,
249}
250
251impl ImportEntry {
252 #[must_use]
254 pub fn new(
255 module_request: Sym,
256 import_name: ImportName,
257 local_name: Identifier,
258 attributes: Box<[ImportAttribute]>,
259 ) -> Self {
260 Self {
261 module_request,
262 import_name,
263 local_name,
264 attributes,
265 }
266 }
267
268 #[must_use]
270 pub const fn module_request(&self) -> Sym {
271 self.module_request
272 }
273
274 #[must_use]
276 pub const fn import_name(&self) -> ImportName {
277 self.import_name
278 }
279
280 #[must_use]
282 pub const fn local_name(&self) -> Identifier {
283 self.local_name
284 }
285
286 #[must_use]
288 pub fn attributes(&self) -> &[ImportAttribute] {
289 &self.attributes
290 }
291}