1use source_map::SourceId;
4
5use crate::{
6 ArrayDestructuringField, Expression, ObjectDestructuringField, PropertyKey,
7 StatementOrDeclaration, WithComment,
8};
9
10pub use temporary_annex::Annex;
11
12pub use ast::*;
13pub use structures::*;
14pub use visitors::*;
15pub use visitors_mut::*;
16
17mod ast {
18 use temporary_annex::Annex;
19
20 use crate::block::{BlockLike, BlockLikeMut};
21
22 use super::{
23 BlockItem, BlockItemMut, Chain, Expression, ImmutableVariableOrProperty,
24 MutableVariableOrProperty, VisitorMutReceiver, VisitorReceiver,
25 };
26
27 pub struct VisitOptions {
30 pub reverse_statements: bool,
38 pub visit_nested_blocks: bool,
40 }
41
42 impl Default for VisitOptions {
43 fn default() -> Self {
44 Self { reverse_statements: false, visit_nested_blocks: true }
45 }
46 }
47
48 macro_rules! mark_items {
50 (impl $trait:ident for $($t:ty),*) => {
51 $(
52 impl $trait for $t {}
53 )*
54 }
55 }
56
57 pub trait SelfVisitable {}
59
60 pub trait SelfVisitableMut {}
62
63 mark_items! {
64 impl SelfVisitable for Expression, BlockItem<'_>, BlockLike<'_>, ImmutableVariableOrProperty<'_>
65 }
66
67 mark_items! {
68 impl SelfVisitableMut for Expression, BlockLikeMut<'_>, BlockItemMut<'_>, MutableVariableOrProperty<'_>
69 }
70
71 pub trait Visitable {
73 fn visit<TData>(
74 &self,
75 visitors: &mut (impl VisitorReceiver<TData> + ?Sized),
76 data: &mut TData,
77 options: &VisitOptions,
78 chain: &mut Annex<Chain>,
79 );
80
81 fn visit_mut<TData>(
82 &mut self,
83 visitors: &mut (impl VisitorMutReceiver<TData> + ?Sized),
84 data: &mut TData,
85 options: &VisitOptions,
86 chain: &mut Annex<Chain>,
87 );
88 }
89
90 impl<T: Visitable> Visitable for Box<T> {
92 fn visit<TData>(
93 &self,
94 v: &mut (impl VisitorReceiver<TData> + ?Sized),
95 d: &mut TData,
96 s: &VisitOptions,
97 c: &mut Annex<Chain>,
98 ) {
99 Visitable::visit(&**self, v, d, s, c);
100 }
101
102 fn visit_mut<TData>(
103 &mut self,
104 v: &mut (impl VisitorMutReceiver<TData> + ?Sized),
105 d: &mut TData,
106 s: &VisitOptions,
107 c: &mut Annex<Chain>,
108 ) {
109 Visitable::visit_mut(&mut **self, v, d, s, c);
110 }
111 }
112
113 impl<T: Visitable> Visitable for Vec<T> {
114 fn visit<TData>(
115 &self,
116 v: &mut (impl VisitorReceiver<TData> + ?Sized),
117 d: &mut TData,
118 s: &VisitOptions,
119 c: &mut Annex<Chain>,
120 ) {
121 self.iter().for_each(|item| item.visit(v, d, s, c));
122 }
123
124 fn visit_mut<TData>(
125 &mut self,
126 v: &mut (impl VisitorMutReceiver<TData> + ?Sized),
127 d: &mut TData,
128 s: &VisitOptions,
129 c: &mut Annex<Chain>,
130 ) {
131 self.iter_mut().for_each(|item| item.visit_mut(v, d, s, c));
132 }
133 }
134
135 impl<T: Visitable> Visitable for Option<T> {
136 fn visit<TData>(
137 &self,
138 v: &mut (impl VisitorReceiver<TData> + ?Sized),
139 d: &mut TData,
140 s: &VisitOptions,
141 c: &mut Annex<Chain>,
142 ) {
143 if let Some(item) = self {
144 item.visit(v, d, s, c);
145 }
146 }
147
148 fn visit_mut<TData>(
149 &mut self,
150 v: &mut (impl VisitorMutReceiver<TData> + ?Sized),
151 d: &mut TData,
152 s: &VisitOptions,
153 c: &mut Annex<Chain>,
154 ) {
155 if let Some(item) = self {
156 item.visit_mut(v, d, s, c);
157 }
158 }
159 }
160
161 impl<T: Visitable, U: Visitable> Visitable for (T, U) {
162 fn visit<TData>(
163 &self,
164 v: &mut (impl VisitorReceiver<TData> + ?Sized),
165 d: &mut TData,
166 s: &VisitOptions,
167 c: &mut Annex<Chain>,
168 ) {
169 self.0.visit(v, d, s, c);
170 self.1.visit(v, d, s, c);
171 }
172
173 fn visit_mut<TData>(
174 &mut self,
175 v: &mut (impl VisitorMutReceiver<TData> + ?Sized),
176 d: &mut TData,
177 s: &VisitOptions,
178 c: &mut Annex<Chain>,
179 ) {
180 self.0.visit_mut(v, d, s, c);
181 self.1.visit_mut(v, d, s, c);
182 }
183 }
184
185 macro_rules! create_blank_visiting_implementations {
186 ($($T:ty),*) => {
187 $(
188 impl Visitable for $T {
189 fn visit<TData>(
190 &self,
191 _visitors: &mut (impl VisitorReceiver<TData> + ?Sized),
192 _data: &mut TData,
193 _options: &VisitOptions,
194 _chain: &mut Annex<Chain>,
195 ) {}
196
197 fn visit_mut<TData>(
198 &mut self,
199 _visitors: &mut (impl VisitorMutReceiver<TData> + ?Sized),
200 _data: &mut TData,
201 _options: &VisitOptions,
202 _chain: &mut Annex<Chain>,
203 ) {}
204 }
205 )*
206 }
207 }
208
209 create_blank_visiting_implementations![
212 (),
213 bool,
214 isize,
215 usize,
216 i8,
217 u8,
218 i16,
219 u16,
220 i32,
221 u32,
222 i64,
223 u64,
224 i128,
225 u128,
226 f32,
227 f64,
228 char,
229 String,
230 Box<str>,
231 std::rc::Rc<str>,
232 std::path::Path,
233 std::path::PathBuf,
234 source_map::Span,
235 crate::TypeAnnotation,
236 crate::types::Visibility,
237 crate::number::NumberRepresentation,
238 crate::expressions::operators::BinaryOperator,
239 crate::expressions::operators::BinaryAssignmentOperator,
240 crate::expressions::operators::UnaryOperator,
241 crate::expressions::operators::UnaryPrefixAssignmentOperator,
242 crate::expressions::operators::UnaryPostfixAssignmentOperator,
243 crate::types::InterfaceDeclaration,
244 crate::types::type_alias::TypeAlias,
245 crate::types::type_annotations::IsItem,
246 crate::types::declare_variable::DeclareVariableDeclaration,
247 crate::VariableIdentifier,
248 crate::PropertyReference,
249 crate::Quoted,
250 crate::declarations::ImportExportName,
251 crate::declarations::ImportLocation,
252 crate::functions::FunctionHeader,
253 crate::functions::MethodHeader,
254 crate::VariableKeyword,
255 source_map::SourceId
256 ];
257}
258
259mod structures {
261 use crate::{
262 property_key::{AlwaysPublic, PublicOrPrivate},
263 Statement, VariableField, VariableIdentifier,
264 };
265
266 use super::{
267 ArrayDestructuringField, ObjectDestructuringField, PropertyKey, SourceId,
268 StatementOrDeclaration, WithComment,
269 };
270 use source_map::Span;
271 use temporary_annex::{Annex, Annexable};
272
273 #[derive(Debug, Clone)]
274 pub enum ChainVariable {
275 Module(SourceId),
276 Function(Span),
277 Block(Span),
278 }
279
280 #[derive(Debug, Clone)]
282 pub struct Chain(Vec<ChainVariable>);
283
284 impl Chain {
285 #[must_use]
286 pub fn new() -> Self {
287 Self(Vec::with_capacity(10))
288 }
289
290 #[must_use]
291 pub fn new_with_initial(initial: ChainVariable) -> Self {
292 let mut buf = Vec::with_capacity(10);
293 buf.push(initial);
294 Self(buf)
295 }
296
297 #[must_use]
298 pub fn len(&self) -> usize {
299 self.0.len()
300 }
301
302 #[must_use]
303 pub fn is_empty(&self) -> bool {
304 self.0.is_empty()
305 }
306
307 pub fn truncate(&mut self, to_size: usize) {
308 self.0.truncate(to_size);
309 }
310
311 #[must_use]
312 pub fn get_module(&self) -> SourceId {
313 if let ChainVariable::Module(source) = self.0.first().unwrap() {
314 source.to_owned()
315 } else {
316 source_map::Nullable::NULL
317 }
318 }
319
320 }
322
323 impl Annexable for Chain {
324 type NewItem = ChainVariable;
325
326 fn push_annex(&mut self, item: Self::NewItem) -> Annex<Self>
327 where
328 Self: Sized,
329 {
330 self.0.push(item);
331 Annex::new(self)
332 }
333
334 fn revert_annex(&mut self) {
335 self.0.pop();
336 }
337 }
338
339 #[derive(Debug)]
340 pub enum ImmutableVariableOrProperty<'a> {
341 VariableFieldName(&'a str, &'a Span),
343 ArrayDestructuringMember(&'a ArrayDestructuringField<VariableField>),
345 ObjectDestructuringMember(&'a WithComment<ObjectDestructuringField<VariableField>>),
346 ClassName(Option<&'a VariableIdentifier>),
347 FunctionName(Option<&'a VariableIdentifier>),
348 ClassPropertyKey(&'a PropertyKey<PublicOrPrivate>),
349 ObjectPropertyKey(&'a PropertyKey<AlwaysPublic>),
350 }
351
352 #[derive(Debug)]
353 pub enum MutableVariableOrProperty<'a> {
354 VariableFieldName(&'a mut String),
355 ArrayDestructuringMember(&'a mut ArrayDestructuringField<VariableField>),
357 ObjectDestructuringMember(&'a mut WithComment<ObjectDestructuringField<VariableField>>),
358 ClassName(Option<&'a mut VariableIdentifier>),
359 FunctionName(Option<&'a mut VariableIdentifier>),
360 ClassPropertyKey(&'a mut PropertyKey<PublicOrPrivate>),
361 ObjectPropertyKey(&'a mut PropertyKey<AlwaysPublic>),
362 }
363
364 impl<'a> ImmutableVariableOrProperty<'a> {
365 #[must_use]
366 pub fn get_variable_name(&self) -> Option<&'a str> {
367 match self {
368 ImmutableVariableOrProperty::VariableFieldName(name, _) => Some(name),
369 ImmutableVariableOrProperty::ArrayDestructuringMember(_) => None,
370 ImmutableVariableOrProperty::ObjectDestructuringMember(o) => {
371 match o.get_ast_ref() {
372 ObjectDestructuringField::Name(VariableIdentifier::Standard(a, ..), ..) => {
373 Some(a.as_str())
374 }
375 _ => None,
376 }
377 }
378 ImmutableVariableOrProperty::FunctionName(name)
379 | ImmutableVariableOrProperty::ClassName(name) => {
380 if let Some(VariableIdentifier::Standard(name, _)) = name {
381 Some(name)
382 } else {
383 None
384 }
385 }
386 ImmutableVariableOrProperty::ObjectPropertyKey(_property) => {
387 None
389 }
395 ImmutableVariableOrProperty::ClassPropertyKey(_property) => {
396 None
398 }
404 }
405 }
406
407 #[must_use]
408 pub fn get_position(&self) -> Span {
409 use crate::ASTNode;
410 match self {
411 ImmutableVariableOrProperty::FunctionName(pos)
412 | ImmutableVariableOrProperty::ClassName(pos) => match pos {
413 Some(p) => p.get_position(),
414 None => source_map::Nullable::NULL,
415 },
416 ImmutableVariableOrProperty::VariableFieldName(_, pos) => **pos,
417 ImmutableVariableOrProperty::ArrayDestructuringMember(m) => m.get_position(),
418 ImmutableVariableOrProperty::ObjectDestructuringMember(m) => m.get_position(),
419 ImmutableVariableOrProperty::ClassPropertyKey(k) => k.get_position(),
420 ImmutableVariableOrProperty::ObjectPropertyKey(k) => k.get_position(),
421 }
422 }
423 }
424
425 pub enum BlockItem<'a> {
428 StatementOrDeclaration(&'a crate::StatementOrDeclaration),
429 SingleStatement(&'a crate::Statement),
430 }
431
432 impl<'a> From<&'a StatementOrDeclaration> for BlockItem<'a> {
433 fn from(item: &'a StatementOrDeclaration) -> Self {
434 BlockItem::StatementOrDeclaration(item)
435 }
436 }
437
438 impl<'a> From<&'a Statement> for BlockItem<'a> {
439 fn from(item: &'a Statement) -> Self {
440 BlockItem::SingleStatement(item)
441 }
442 }
443
444 pub enum BlockItemMut<'a> {
447 StatementOrDeclaration(&'a mut crate::StatementOrDeclaration),
448 SingleStatement(&'a mut crate::Statement),
449 }
450
451 impl<'a> From<&'a mut StatementOrDeclaration> for BlockItemMut<'a> {
452 fn from(item: &'a mut StatementOrDeclaration) -> Self {
453 BlockItemMut::StatementOrDeclaration(item)
454 }
455 }
456
457 impl<'a> From<&'a mut Statement> for BlockItemMut<'a> {
458 fn from(item: &'a mut Statement) -> Self {
459 BlockItemMut::SingleStatement(item)
460 }
461 }
462}
463
464mod visitors {
465 use super::{BlockItem, Chain, Expression, ImmutableVariableOrProperty, SelfVisitable};
466 use crate::{block::BlockLike, TSXKeyword};
467 use source_map::Span;
468
469 pub trait Visitor<Item: SelfVisitable, Data> {
471 fn visit(&mut self, item: &Item, data: &mut Data, chain: &Chain);
472 }
473
474 #[allow(unused_variables)]
476 pub trait VisitorReceiver<T> {
477 fn visit_expression(&mut self, expression: &Expression, data: &mut T, chain: &Chain) {}
478
479 fn visit_statement(&mut self, statement: BlockItem, data: &mut T, chain: &Chain) {}
480
481 fn visit_variable(
482 &mut self,
483 variable: &ImmutableVariableOrProperty,
484 data: &mut T,
485 chain: &Chain,
486 ) {
487 }
488
489 fn visit_block(&mut self, block: &BlockLike, data: &mut T, chain: &Chain) {}
490
491 fn visit_keyword(&mut self, keyword: &(TSXKeyword, &Span), data: &mut T, chain: &Chain) {}
492 }
493
494 impl<T> VisitorReceiver<T> for Visitors<T> {
495 fn visit_expression(&mut self, expression: &Expression, data: &mut T, chain: &Chain) {
496 self.expression_visitors.iter_mut().for_each(|vis| vis.visit(expression, data, chain));
497 }
498
499 fn visit_statement(&mut self, statement: BlockItem, data: &mut T, chain: &Chain) {
500 self.statement_visitors.iter_mut().for_each(|vis| vis.visit(&statement, data, chain));
501 }
502
503 fn visit_variable(
504 &mut self,
505 variable: &ImmutableVariableOrProperty,
506 data: &mut T,
507 chain: &Chain,
508 ) {
509 self.variable_visitors.iter_mut().for_each(|vis| vis.visit(variable, data, chain));
510 }
511
512 fn visit_block(&mut self, block: &BlockLike, data: &mut T, chain: &Chain) {
513 self.block_visitors.iter_mut().for_each(|vis| vis.visit(block, data, chain));
514 }
515
516 fn visit_keyword(&mut self, _keyword: &(TSXKeyword, &Span), _data: &mut T, _chain: &Chain) {
517 }
518 }
519
520 type ExpressionVisitor<T> = Box<dyn Visitor<Expression, T>>;
521 type StatementVisitor<T> = Box<dyn for<'a> Visitor<BlockItem<'a>, T>>;
522 type VariableVisitor<T> = Box<dyn for<'a> Visitor<ImmutableVariableOrProperty<'a>, T>>;
523 type BlockVisitor<T> = Box<dyn for<'a> Visitor<BlockLike<'a>, T>>;
524
525 #[derive(Default)]
528 pub struct Visitors<T> {
529 pub expression_visitors: Vec<ExpressionVisitor<T>>,
530 pub statement_visitors: Vec<StatementVisitor<T>>,
531 pub variable_visitors: Vec<VariableVisitor<T>>,
532 pub block_visitors: Vec<BlockVisitor<T>>,
533 }
534
535 }
567
568mod visitors_mut {
569 use crate::block::BlockLikeMut;
570
571 use super::{BlockItemMut, Chain, Expression, MutableVariableOrProperty, SelfVisitableMut};
572
573 pub trait VisitorMut<Item: SelfVisitableMut, Data> {
575 fn visit_mut(&mut self, item: &mut Item, data: &mut Data, chain: &Chain);
576 }
577
578 #[allow(unused_variables)]
580 pub trait VisitorMutReceiver<T> {
581 fn visit_expression_mut(
582 &mut self,
583 expression: &mut Expression,
584 data: &mut T,
585 chain: &Chain,
586 ) {
587 }
588
589 fn visit_statement_mut(&mut self, statement: BlockItemMut, data: &mut T, chain: &Chain) {}
590
591 fn visit_variable_mut(
592 &mut self,
593 variable: &mut MutableVariableOrProperty,
594 data: &mut T,
595 chain: &Chain,
596 ) {
597 }
598
599 fn visit_block_mut(&mut self, block: &mut BlockLikeMut, data: &mut T, chain: &Chain) {}
600 }
601
602 type StatementVisitor<T> = Box<dyn for<'a> VisitorMut<BlockItemMut<'a>, T>>;
603 type VariableVisitor<T> = Box<dyn for<'a> VisitorMut<MutableVariableOrProperty<'a>, T>>;
604 type BlockVisitor<T> = Box<dyn for<'a> VisitorMut<BlockLikeMut<'a>, T>>;
605
606 pub struct VisitorsMut<T> {
609 pub expression_visitors_mut: Vec<Box<dyn VisitorMut<Expression, T>>>,
610 pub statement_visitors_mut: Vec<StatementVisitor<T>>,
611 pub variable_visitors_mut: Vec<VariableVisitor<T>>,
612 pub block_visitors_mut: Vec<BlockVisitor<T>>,
613 }
614
615 impl<T> Default for VisitorsMut<T> {
616 fn default() -> Self {
617 Self {
618 expression_visitors_mut: Default::default(),
619 statement_visitors_mut: Default::default(),
620 variable_visitors_mut: Default::default(),
621 block_visitors_mut: Default::default(),
622 }
623 }
624 }
625
626 impl<T> VisitorMutReceiver<T> for VisitorsMut<T> {
627 fn visit_expression_mut(
628 &mut self,
629 expression: &mut Expression,
630 data: &mut T,
631 chain: &Chain,
632 ) {
633 self.expression_visitors_mut
634 .iter_mut()
635 .for_each(|vis| vis.visit_mut(expression, data, chain));
636 }
637
638 fn visit_statement_mut(&mut self, mut item: BlockItemMut, data: &mut T, chain: &Chain) {
639 self.statement_visitors_mut
640 .iter_mut()
641 .for_each(|vis| vis.visit_mut(&mut item, data, chain));
642 }
643
644 fn visit_variable_mut(
645 &mut self,
646 variable: &mut MutableVariableOrProperty,
647 data: &mut T,
648 chain: &Chain,
649 ) {
650 self.variable_visitors_mut
651 .iter_mut()
652 .for_each(|vis| vis.visit_mut(variable, data, chain));
653 }
654
655 fn visit_block_mut(&mut self, block: &mut BlockLikeMut, data: &mut T, chain: &Chain) {
656 self.block_visitors_mut.iter_mut().for_each(|vis| vis.visit_mut(block, data, chain));
657 }
658 }
659
660 }