Skip to main content

swc_ecma_ast/
expr.rs

1#![allow(clippy::vec_box)]
2
3use is_macro::Is;
4use string_enum::StringEnum;
5use swc_atoms::{Atom, Wtf8Atom};
6use swc_common::{
7    ast_node, util::take::Take, BytePos, EqIgnoreSpan, Span, Spanned, SyntaxContext, DUMMY_SP,
8};
9
10use crate::{
11    class::Class,
12    function::{Function, FunctionBody},
13    ident::{Ident, PrivateName},
14    jsx::{JSXElement, JSXEmptyExpr, JSXFragment, JSXMemberExpr, JSXNamespacedName},
15    lit::Lit,
16    operators::{AssignOp, BinaryOp, UnaryOp, UpdateOp},
17    pat::Pat,
18    prop::Prop,
19    typescript::{
20        TsAsExpr, TsConstAssertion, TsInstantiation, TsNonNullExpr, TsSatisfiesExpr, TsTypeAnn,
21        TsTypeAssertion, TsTypeParamDecl, TsTypeParamInstantiation,
22    },
23    ArrayPat, BindingIdent, ComputedPropName, Id, IdentName, ImportPhase, Invalid, KeyValueProp,
24    Number, ObjectPat, PropName, Str,
25};
26
27#[ast_node(no_clone)]
28#[derive(Eq, Hash, Is, EqIgnoreSpan)]
29#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
30#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
31pub enum Expr {
32    #[tag("ThisExpression")]
33    This(ThisExpr),
34
35    #[tag("ArrayExpression")]
36    Array(ArrayLit),
37
38    #[tag("ObjectExpression")]
39    Object(ObjectLit),
40
41    #[tag("FunctionExpression")]
42    #[is(name = "fn_expr")]
43    Fn(FnExpr),
44
45    #[tag("UnaryExpression")]
46    Unary(UnaryExpr),
47
48    /// `++v`, `--v`, `v++`, `v--`
49    #[tag("UpdateExpression")]
50    Update(UpdateExpr),
51
52    #[tag("BinaryExpression")]
53    Bin(BinExpr),
54
55    #[tag("AssignmentExpression")]
56    Assign(AssignExpr),
57
58    //
59    // Logical {
60    //
61    //     op: LogicalOp,
62    //     left: Box<Expr>,
63    //     right: Box<Expr>,
64    // },
65    /// A member expression. If computed is true, the node corresponds to a
66    /// computed (a[b]) member expression and property is an Expression. If
67    /// computed is false, the node corresponds to a static (a.b) member
68    /// expression and property is an Identifier.
69    #[tag("MemberExpression")]
70    Member(MemberExpr),
71
72    #[tag("SuperPropExpression")]
73    SuperProp(SuperPropExpr),
74
75    /// true ? 'a' : 'b'
76    #[tag("ConditionalExpression")]
77    Cond(CondExpr),
78
79    #[tag("CallExpression")]
80    Call(CallExpr),
81
82    /// `new Cat()`
83    #[tag("NewExpression")]
84    New(NewExpr),
85
86    #[tag("SequenceExpression")]
87    Seq(SeqExpr),
88
89    #[tag("Identifier")]
90    Ident(Ident),
91
92    #[tag("StringLiteral")]
93    #[tag("BooleanLiteral")]
94    #[tag("NullLiteral")]
95    #[tag("NumericLiteral")]
96    #[tag("RegExpLiteral")]
97    #[tag("JSXText")]
98    #[tag("BigIntLiteral")]
99    Lit(Lit),
100
101    #[tag("TemplateLiteral")]
102    Tpl(Tpl),
103
104    #[tag("TaggedTemplateExpression")]
105    TaggedTpl(TaggedTpl),
106
107    #[tag("ArrowFunctionExpression")]
108    Arrow(ArrowExpr),
109
110    #[tag("ClassExpression")]
111    Class(ClassExpr),
112
113    #[tag("YieldExpression")]
114    #[is(name = "yield_expr")]
115    Yield(YieldExpr),
116
117    #[tag("MetaProperty")]
118    MetaProp(MetaPropExpr),
119
120    #[tag("AwaitExpression")]
121    #[is(name = "await_expr")]
122    Await(AwaitExpr),
123
124    #[tag("ParenthesisExpression")]
125    Paren(ParenExpr),
126
127    #[tag("JSXMemberExpression")]
128    JSXMember(JSXMemberExpr),
129
130    #[tag("JSXNamespacedName")]
131    JSXNamespacedName(JSXNamespacedName),
132
133    #[tag("JSXEmptyExpression")]
134    JSXEmpty(JSXEmptyExpr),
135
136    #[tag("JSXElement")]
137    JSXElement(Box<JSXElement>),
138
139    #[tag("JSXFragment")]
140    JSXFragment(JSXFragment),
141
142    #[tag("TsTypeAssertion")]
143    TsTypeAssertion(TsTypeAssertion),
144
145    #[tag("TsConstAssertion")]
146    TsConstAssertion(TsConstAssertion),
147
148    #[tag("TsNonNullExpression")]
149    TsNonNull(TsNonNullExpr),
150
151    #[tag("TsAsExpression")]
152    TsAs(TsAsExpr),
153
154    #[tag("TsInstantiation")]
155    TsInstantiation(TsInstantiation),
156
157    #[tag("TsSatisfiesExpression")]
158    TsSatisfies(TsSatisfiesExpr),
159
160    #[tag("PrivateName")]
161    PrivateName(PrivateName),
162
163    #[tag("OptionalChainingExpression")]
164    OptChain(OptChainExpr),
165
166    #[tag("Invalid")]
167    Invalid(Invalid),
168}
169
170bridge_from!(Box<Expr>, Box<JSXElement>, JSXElement);
171
172// Memory layout depends on the version of rustc.
173// #[cfg(target_pointer_width = "64")]
174// assert_eq_size!(Expr, [u8; 80]);
175
176impl Expr {
177    /// Creates `void 0`.
178    #[inline]
179    pub fn undefined(span: Span) -> Box<Expr> {
180        UnaryExpr {
181            span,
182            op: op!("void"),
183            arg: Lit::Num(Number {
184                span,
185                value: 0.0,
186                raw: None,
187            })
188            .into(),
189        }
190        .into()
191    }
192
193    pub fn is_null(&self) -> bool {
194        matches!(self, Expr::Lit(Lit::Null(_)))
195    }
196
197    pub fn leftmost(&self) -> Option<&Ident> {
198        match self {
199            Expr::Ident(i) => Some(i),
200            Expr::Member(MemberExpr { obj, .. }) => obj.leftmost(),
201            Expr::OptChain(opt) => opt.base.as_member()?.obj.leftmost(),
202            _ => None,
203        }
204    }
205
206    pub fn is_ident_ref_to<S>(&self, ident: &S) -> bool
207    where
208        S: ?Sized,
209        Atom: PartialEq<S>,
210    {
211        match self {
212            Expr::Ident(i) => i.sym == *ident,
213            _ => false,
214        }
215    }
216
217    /// Unwraps an expression with a given function.
218    ///
219    /// If the provided function returns [Some], the function is called again
220    /// with the returned value. If the provided functions returns [None],
221    /// the last expression is returned.
222    pub fn unwrap_with<'a, F>(&'a self, mut op: F) -> &'a Expr
223    where
224        F: FnMut(&'a Expr) -> Option<&'a Expr>,
225    {
226        let mut cur = self;
227        loop {
228            match op(cur) {
229                Some(next) => cur = next,
230                None => return cur,
231            }
232        }
233    }
234
235    /// Unwraps an expression with a given function.
236    ///
237    /// If the provided function returns [Some], the function is called again
238    /// with the returned value. If the provided functions returns [None],
239    /// the last expression is returned.
240    ///
241    /// The function receives a fresh mutable reborrow on each invocation. It
242    /// can return a nested expression borrowed from its argument, but it cannot
243    /// retain that argument after the invocation.
244    ///
245    /// # Source compatibility
246    ///
247    /// The higher-ranked callback bound rejects functions that retain the
248    /// argument outside the callback. Such functions were accepted by older
249    /// versions of this method, but could create aliased mutable references.
250    /// Callbacks that only return an expression nested within the argument
251    /// remain supported.
252    ///
253    /// ```compile_fail
254    /// use swc_ecma_ast::Expr;
255    ///
256    /// fn stash_callback_argument(expr: &mut Expr) {
257    ///     let mut stashed: Option<&mut Expr> = None;
258    ///
259    ///     let returned = expr.unwrap_mut_with(|current| {
260    ///         stashed = Some(current);
261    ///         None
262    ///     });
263    ///
264    ///     let _aliases = (returned, stashed.unwrap());
265    /// }
266    /// ```
267    pub fn unwrap_mut_with<'root, F>(&'root mut self, mut op: F) -> &'root mut Expr
268    where
269        F: for<'call> FnMut(&'call mut Expr) -> Option<&'call mut Expr>,
270    {
271        // Stable borrow checking cannot yet express that the callback's borrow
272        // ends in the `None` branch, so keep the cursor raw between calls.
273        let mut cur: *mut Expr = self;
274
275        loop {
276            // SAFETY:
277            // - `cur` starts as the pointer behind the exclusive `'root` borrow, and is
278            //   only replaced with a pointer obtained from the callback's exclusive return
279            //   value.
280            // - The higher-ranked bound gives every call its own lifetime, so safe callback
281            //   code cannot retain this reborrow in captured state. While `op` runs, no
282            //   other reference is created from `cur`.
283            // - A returned reference is consumed into `cur` before the next iteration. Safe
284            //   code cannot return a reference whose storage expires at the end of the
285            //   call.
286            match unsafe { op(&mut *cur) } {
287                Some(next) => cur = next,
288                None => {
289                    // SAFETY: `None` contains no reference from the last
290                    // reborrow, and the higher-ranked callback cannot have
291                    // retained it. Thus `cur` is still valid and exclusively
292                    // borrowed, and its reference can be returned for the
293                    // remainder of `'root`.
294                    return unsafe { &mut *cur };
295                }
296            }
297        }
298    }
299
300    /// Normalize parenthesized expressions.
301    ///
302    /// This will normalize `(foo)`, `((foo))`, ... to `foo`.
303    ///
304    /// If `self` is not a parenthesized expression, it will be returned as is.
305    pub fn unwrap_parens(&self) -> &Expr {
306        self.unwrap_with(|e| {
307            if let Expr::Paren(expr) = e {
308                Some(&expr.expr)
309            } else {
310                None
311            }
312        })
313    }
314
315    /// Normalize parenthesized expressions.
316    ///
317    /// This will normalize `(foo)`, `((foo))`, ... to `foo`.
318    ///
319    /// If `self` is not a parenthesized expression, it will be returned as is.
320    pub fn unwrap_parens_mut(&mut self) -> &mut Expr {
321        self.unwrap_mut_with(|e| {
322            if let Expr::Paren(expr) = e {
323                Some(&mut expr.expr)
324            } else {
325                None
326            }
327        })
328    }
329
330    /// Normalize sequences and parenthesized expressions.
331    ///
332    /// This returns the last expression of a sequence expression or the
333    /// expression of a parenthesized expression.
334    pub fn unwrap_seqs_and_parens(&self) -> &Self {
335        self.unwrap_with(|expr| match expr {
336            Expr::Seq(SeqExpr { exprs, .. }) => exprs.last().map(|v| &**v),
337            Expr::Paren(ParenExpr { expr, .. }) => Some(expr),
338            _ => None,
339        })
340    }
341
342    /// Creates an expression from `exprs`. This will return first element if
343    /// the length is 1 and a sequential expression otherwise.
344    ///
345    /// # Panics
346    ///
347    /// Panics if `exprs` is empty.
348    pub fn from_exprs(mut exprs: Vec<Box<Expr>>) -> Box<Expr> {
349        debug_assert!(!exprs.is_empty(), "`exprs` must not be empty");
350
351        if exprs.len() == 1 {
352            exprs.remove(0)
353        } else {
354            SeqExpr {
355                span: DUMMY_SP,
356                exprs,
357            }
358            .into()
359        }
360    }
361
362    #[deprecated(note = "Use `directness_matters` instead")]
363    pub fn directness_maters(&self) -> bool {
364        self.directness_matters()
365    }
366
367    /// Returns true for `eval` and member expressions.
368    pub fn directness_matters(&self) -> bool {
369        self.is_ident_ref_to("eval") || matches!(self, Expr::Member(..))
370    }
371
372    pub fn with_span(mut self, span: Span) -> Expr {
373        self.set_span(span);
374        self
375    }
376
377    pub fn set_span(&mut self, span: Span) {
378        match self {
379            Expr::Ident(i) => {
380                i.span = span;
381            }
382            Expr::This(e) => e.span = span,
383            Expr::Array(e) => e.span = span,
384            Expr::Object(e) => e.span = span,
385            Expr::Fn(e) => e.function.span = span,
386            Expr::Unary(e) => e.span = span,
387            Expr::Update(e) => e.span = span,
388            Expr::Bin(e) => e.span = span,
389            Expr::Assign(e) => e.span = span,
390            Expr::Member(e) => e.span = span,
391            Expr::SuperProp(e) => e.span = span,
392            Expr::Cond(e) => e.span = span,
393            Expr::Call(e) => e.span = span,
394            Expr::New(e) => e.span = span,
395            Expr::Seq(e) => e.span = span,
396            Expr::Tpl(e) => e.span = span,
397            Expr::TaggedTpl(e) => e.span = span,
398            Expr::Arrow(e) => e.span = span,
399            Expr::Class(e) => e.class.span = span,
400            Expr::Yield(e) => e.span = span,
401            Expr::Invalid(e) => e.span = span,
402            Expr::TsAs(e) => e.span = span,
403            Expr::TsTypeAssertion(e) => e.span = span,
404            Expr::TsConstAssertion(e) => e.span = span,
405            Expr::TsSatisfies(e) => e.span = span,
406            Expr::TsNonNull(e) => e.span = span,
407            Expr::TsInstantiation(e) => e.span = span,
408            Expr::MetaProp(e) => e.span = span,
409            Expr::Await(e) => e.span = span,
410            Expr::Paren(e) => e.span = span,
411            Expr::JSXMember(e) => e.span = span,
412            Expr::JSXNamespacedName(e) => e.span = span,
413            Expr::JSXEmpty(e) => e.span = span,
414            Expr::JSXElement(e) => e.span = span,
415            Expr::JSXFragment(e) => e.span = span,
416            Expr::PrivateName(e) => e.span = span,
417            Expr::OptChain(e) => e.span = span,
418            Expr::Lit(e) => e.set_span(span),
419            #[cfg(all(swc_ast_unknown, feature = "encoding-impl"))]
420            _ => swc_common::unknown!(),
421        }
422    }
423}
424
425// Implement Clone without inline to avoid multiple copies of the
426// implementation.
427impl Clone for Expr {
428    fn clone(&self) -> Self {
429        use Expr::*;
430        match self {
431            #[cfg(all(swc_ast_unknown, feature = "encoding-impl"))]
432            Unknown(tag, v) => Unknown(*tag, v.clone()),
433            This(e) => This(e.clone()),
434            Array(e) => Array(e.clone()),
435            Object(e) => Object(e.clone()),
436            Fn(e) => Fn(e.clone()),
437            Unary(e) => Unary(e.clone()),
438            Update(e) => Update(e.clone()),
439            Bin(e) => Bin(e.clone()),
440            Assign(e) => Assign(e.clone()),
441            Member(e) => Member(e.clone()),
442            SuperProp(e) => SuperProp(e.clone()),
443            Cond(e) => Cond(e.clone()),
444            Call(e) => Call(e.clone()),
445            New(e) => New(e.clone()),
446            Seq(e) => Seq(e.clone()),
447            Ident(e) => Ident(e.clone()),
448            Lit(e) => Lit(e.clone()),
449            Tpl(e) => Tpl(e.clone()),
450            TaggedTpl(e) => TaggedTpl(e.clone()),
451            Arrow(e) => Arrow(e.clone()),
452            Class(e) => Class(e.clone()),
453            Yield(e) => Yield(e.clone()),
454            MetaProp(e) => MetaProp(e.clone()),
455            Await(e) => Await(e.clone()),
456            Paren(e) => Paren(e.clone()),
457            JSXMember(e) => JSXMember(e.clone()),
458            JSXNamespacedName(e) => JSXNamespacedName(e.clone()),
459            JSXEmpty(e) => JSXEmpty(e.clone()),
460            JSXElement(e) => JSXElement(e.clone()),
461            JSXFragment(e) => JSXFragment(e.clone()),
462            TsTypeAssertion(e) => TsTypeAssertion(e.clone()),
463            TsConstAssertion(e) => TsConstAssertion(e.clone()),
464            TsNonNull(e) => TsNonNull(e.clone()),
465            TsAs(e) => TsAs(e.clone()),
466            TsInstantiation(e) => TsInstantiation(e.clone()),
467            PrivateName(e) => PrivateName(e.clone()),
468            OptChain(e) => OptChain(e.clone()),
469            Invalid(e) => Invalid(e.clone()),
470            TsSatisfies(e) => TsSatisfies(e.clone()),
471        }
472    }
473}
474
475impl Take for Expr {
476    fn dummy() -> Self {
477        Invalid { span: DUMMY_SP }.into()
478    }
479}
480
481impl Default for Expr {
482    fn default() -> Self {
483        Expr::Invalid(Default::default())
484    }
485}
486
487bridge_expr_from!(Ident, IdentName);
488bridge_expr_from!(Ident, Id);
489bridge_expr_from!(FnExpr, Function);
490bridge_expr_from!(ClassExpr, Class);
491
492macro_rules! boxed_expr {
493    ($T:ty) => {
494        bridge_from!(Box<Expr>, Expr, $T);
495    };
496}
497
498boxed_expr!(ThisExpr);
499boxed_expr!(ArrayLit);
500boxed_expr!(ObjectLit);
501boxed_expr!(FnExpr);
502boxed_expr!(UnaryExpr);
503boxed_expr!(UpdateExpr);
504boxed_expr!(BinExpr);
505boxed_expr!(AssignExpr);
506boxed_expr!(MemberExpr);
507boxed_expr!(SuperPropExpr);
508boxed_expr!(CondExpr);
509boxed_expr!(CallExpr);
510boxed_expr!(NewExpr);
511boxed_expr!(SeqExpr);
512bridge_from!(Box<Expr>, Expr, Ident);
513boxed_expr!(Lit);
514boxed_expr!(Tpl);
515boxed_expr!(TaggedTpl);
516boxed_expr!(ArrowExpr);
517boxed_expr!(ClassExpr);
518boxed_expr!(YieldExpr);
519boxed_expr!(MetaPropExpr);
520boxed_expr!(AwaitExpr);
521boxed_expr!(ParenExpr);
522boxed_expr!(JSXMemberExpr);
523boxed_expr!(JSXNamespacedName);
524boxed_expr!(JSXEmptyExpr);
525boxed_expr!(Box<JSXElement>);
526boxed_expr!(JSXFragment);
527boxed_expr!(TsTypeAssertion);
528boxed_expr!(TsSatisfiesExpr);
529boxed_expr!(TsConstAssertion);
530boxed_expr!(TsNonNullExpr);
531boxed_expr!(TsAsExpr);
532boxed_expr!(TsInstantiation);
533boxed_expr!(PrivateName);
534boxed_expr!(OptChainExpr);
535boxed_expr!(Invalid);
536
537#[ast_node("ThisExpression")]
538#[derive(Eq, Hash, Copy, EqIgnoreSpan)]
539#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
540#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
541pub struct ThisExpr {
542    pub span: Span,
543}
544
545impl Take for ThisExpr {
546    fn dummy() -> Self {
547        ThisExpr { span: DUMMY_SP }
548    }
549}
550
551/// Array literal.
552#[ast_node("ArrayExpression")]
553#[derive(Eq, Hash, EqIgnoreSpan, Default)]
554#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
555#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
556pub struct ArrayLit {
557    pub span: Span,
558
559    #[cfg_attr(feature = "serde-impl", serde(default, rename = "elements"))]
560    #[cfg_attr(
561        feature = "encoding-impl",
562        encoding(with = "swc_common::serializer::ArrayOption")
563    )]
564    pub elems: Vec<Option<ExprOrSpread>>,
565}
566
567impl Take for ArrayLit {
568    fn dummy() -> Self {
569        ArrayLit {
570            span: DUMMY_SP,
571            elems: Default::default(),
572        }
573    }
574}
575
576/// Object literal.
577#[ast_node("ObjectExpression")]
578#[derive(Eq, Hash, EqIgnoreSpan, Default)]
579#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
580#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
581pub struct ObjectLit {
582    pub span: Span,
583
584    #[cfg_attr(feature = "serde-impl", serde(default, rename = "properties"))]
585    pub props: Vec<PropOrSpread>,
586}
587
588impl ObjectLit {
589    /// See [ImportWith] for details.
590    ///
591    /// Returns [None] if this is not a valid for `with` of [crate::ImportDecl].
592    pub fn as_import_with(&self) -> Option<ImportWith> {
593        let mut values = Vec::new();
594        for prop in &self.props {
595            match prop {
596                PropOrSpread::Spread(..) => return None,
597                PropOrSpread::Prop(prop) => match &**prop {
598                    Prop::KeyValue(kv) => {
599                        let key = match &kv.key {
600                            PropName::Ident(i) => i.clone(),
601                            PropName::Str(s) => {
602                                let name = s.value.as_str()?;
603                                IdentName::new(name.to_string().into(), s.span)
604                            }
605                            _ => return None,
606                        };
607
608                        values.push(ImportWithItem {
609                            key,
610                            value: match &*kv.value {
611                                Expr::Lit(Lit::Str(s)) => s.clone(),
612                                _ => return None,
613                            },
614                        });
615                    }
616                    _ => return None,
617                },
618                #[cfg(all(swc_ast_unknown, feature = "encoding-impl"))]
619                _ => swc_common::unknown!(),
620            }
621        }
622
623        Some(ImportWith {
624            span: self.span,
625            values,
626        })
627    }
628}
629
630impl From<ImportWith> for ObjectLit {
631    fn from(v: ImportWith) -> Self {
632        ObjectLit {
633            span: v.span,
634            props: v
635                .values
636                .into_iter()
637                .map(|item| {
638                    PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
639                        key: PropName::Ident(item.key),
640                        value: Lit::Str(item.value).into(),
641                    })))
642                })
643                .collect(),
644        }
645    }
646}
647
648/// According to the current spec `with` of [crate::ImportDecl] can only have
649/// strings or idents as keys, can't be nested, can only have string literals as
650/// values:
651
652#[derive(Debug, Clone, PartialEq, Eq, Hash, EqIgnoreSpan)]
653pub struct ImportWith {
654    pub span: Span,
655    pub values: Vec<ImportWithItem>,
656}
657
658impl ImportWith {
659    pub fn get(&self, key: &str) -> Option<&Str> {
660        self.values.iter().find_map(|item| {
661            if item.key.sym == key {
662                Some(&item.value)
663            } else {
664                None
665            }
666        })
667    }
668}
669
670#[derive(Debug, Clone, PartialEq, Eq, Hash, EqIgnoreSpan)]
671pub struct ImportWithItem {
672    pub key: IdentName,
673    pub value: Str,
674}
675
676impl Take for ObjectLit {
677    fn dummy() -> Self {
678        ObjectLit {
679            span: DUMMY_SP,
680            props: Default::default(),
681        }
682    }
683}
684
685#[ast_node]
686#[derive(Eq, Hash, Is, EqIgnoreSpan)]
687#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
688#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
689pub enum PropOrSpread {
690    /// Spread properties, e.g., `{a: 1, ...obj, b: 2}`.
691    #[tag("SpreadElement")]
692    Spread(SpreadElement),
693
694    #[tag("*")]
695    Prop(Box<Prop>),
696}
697
698bridge_from!(PropOrSpread, Box<Prop>, Prop);
699
700impl Take for PropOrSpread {
701    fn dummy() -> Self {
702        PropOrSpread::Spread(SpreadElement {
703            dot3_token: DUMMY_SP,
704            expr: Take::dummy(),
705        })
706    }
707}
708
709#[ast_node("SpreadElement")]
710#[derive(Eq, Hash, EqIgnoreSpan, Default)]
711#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
712#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
713pub struct SpreadElement {
714    #[cfg_attr(feature = "serde-impl", serde(rename = "spread"))]
715    #[span(lo)]
716    pub dot3_token: Span,
717
718    #[cfg_attr(feature = "serde-impl", serde(rename = "arguments"))]
719    #[span(hi)]
720    pub expr: Box<Expr>,
721}
722
723impl Take for SpreadElement {
724    fn dummy() -> Self {
725        SpreadElement {
726            dot3_token: DUMMY_SP,
727            expr: Take::dummy(),
728        }
729    }
730}
731
732#[ast_node("UnaryExpression")]
733#[derive(Eq, Hash, EqIgnoreSpan, Default)]
734#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
735#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
736pub struct UnaryExpr {
737    pub span: Span,
738
739    #[cfg_attr(feature = "serde-impl", serde(rename = "operator"))]
740    pub op: UnaryOp,
741
742    #[cfg_attr(feature = "serde-impl", serde(rename = "argument"))]
743    pub arg: Box<Expr>,
744}
745
746impl Take for UnaryExpr {
747    fn dummy() -> Self {
748        UnaryExpr {
749            span: DUMMY_SP,
750            op: op!("!"),
751            arg: Take::dummy(),
752        }
753    }
754}
755
756#[ast_node("UpdateExpression")]
757#[derive(Eq, Hash, EqIgnoreSpan, Default)]
758#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
759#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
760pub struct UpdateExpr {
761    pub span: Span,
762
763    #[cfg_attr(feature = "serde-impl", serde(rename = "operator"))]
764    pub op: UpdateOp,
765
766    pub prefix: bool,
767
768    #[cfg_attr(feature = "serde-impl", serde(rename = "argument"))]
769    pub arg: Box<Expr>,
770}
771
772impl Take for UpdateExpr {
773    fn dummy() -> Self {
774        UpdateExpr {
775            span: DUMMY_SP,
776            op: op!("++"),
777            prefix: false,
778            arg: Take::dummy(),
779        }
780    }
781}
782
783#[ast_node("BinaryExpression")]
784#[derive(Eq, Hash, EqIgnoreSpan, Default)]
785#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
786#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
787pub struct BinExpr {
788    pub span: Span,
789
790    #[cfg_attr(feature = "serde-impl", serde(rename = "operator"))]
791    pub op: BinaryOp,
792
793    pub left: Box<Expr>,
794
795    pub right: Box<Expr>,
796}
797
798impl Take for BinExpr {
799    fn dummy() -> Self {
800        BinExpr {
801            span: DUMMY_SP,
802            op: op!("*"),
803            left: Take::dummy(),
804            right: Take::dummy(),
805        }
806    }
807}
808
809/// Function expression.
810#[ast_node("FunctionExpression")]
811#[derive(Eq, Hash, EqIgnoreSpan, Default)]
812#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
813#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
814pub struct FnExpr {
815    #[cfg_attr(feature = "serde-impl", serde(default, rename = "identifier"))]
816    #[cfg_attr(
817        feature = "encoding-impl",
818        encoding(with = "cbor4ii::core::types::Maybe")
819    )]
820    pub ident: Option<Ident>,
821
822    #[cfg_attr(feature = "serde-impl", serde(flatten))]
823    #[span]
824    pub function: Box<Function>,
825}
826
827impl Take for FnExpr {
828    fn dummy() -> Self {
829        FnExpr {
830            ident: None,
831            function: Take::dummy(),
832        }
833    }
834}
835
836impl From<Box<Function>> for FnExpr {
837    fn from(function: Box<Function>) -> Self {
838        Self {
839            ident: None,
840            function,
841        }
842    }
843}
844
845bridge_from!(FnExpr, Box<Function>, Function);
846bridge_expr_from!(FnExpr, Box<Function>);
847
848/// Class expression.
849#[ast_node("ClassExpression")]
850#[derive(Eq, Hash, EqIgnoreSpan, Default)]
851#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
852#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
853pub struct ClassExpr {
854    #[cfg_attr(feature = "serde-impl", serde(default, rename = "identifier"))]
855    #[cfg_attr(
856        feature = "encoding-impl",
857        encoding(with = "cbor4ii::core::types::Maybe")
858    )]
859    pub ident: Option<Ident>,
860
861    #[cfg_attr(feature = "serde-impl", serde(flatten))]
862    #[span]
863    pub class: Box<Class>,
864}
865
866impl Take for ClassExpr {
867    fn dummy() -> Self {
868        ClassExpr {
869            ident: None,
870            class: Take::dummy(),
871        }
872    }
873}
874
875impl From<Box<Class>> for ClassExpr {
876    fn from(class: Box<Class>) -> Self {
877        Self { ident: None, class }
878    }
879}
880
881bridge_from!(ClassExpr, Box<Class>, Class);
882bridge_expr_from!(ClassExpr, Box<Class>);
883
884#[ast_node("AssignmentExpression")]
885#[derive(Eq, Hash, EqIgnoreSpan, Default)]
886#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
887#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
888pub struct AssignExpr {
889    pub span: Span,
890
891    #[cfg_attr(feature = "serde-impl", serde(rename = "operator"))]
892    pub op: AssignOp,
893
894    pub left: AssignTarget,
895
896    pub right: Box<Expr>,
897}
898
899impl Take for AssignExpr {
900    fn dummy() -> Self {
901        AssignExpr {
902            span: DUMMY_SP,
903            op: op!("="),
904            left: Take::dummy(),
905            right: Take::dummy(),
906        }
907    }
908}
909
910impl AssignExpr {
911    pub fn is_simple_assign(&self) -> bool {
912        self.op == op!("=") && self.left.as_ident().is_some()
913    }
914}
915
916#[ast_node("MemberExpression")]
917#[derive(Eq, Hash, EqIgnoreSpan, Default)]
918#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
919#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
920pub struct MemberExpr {
921    pub span: Span,
922
923    #[cfg_attr(feature = "serde-impl", serde(rename = "object"))]
924    pub obj: Box<Expr>,
925
926    #[cfg_attr(feature = "serde-impl", serde(rename = "property"))]
927    pub prop: MemberProp,
928}
929
930#[ast_node]
931#[derive(Eq, Hash, Is, EqIgnoreSpan)]
932#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
933#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
934pub enum MemberProp {
935    #[tag("Identifier")]
936    Ident(IdentName),
937    #[tag("PrivateName")]
938    PrivateName(PrivateName),
939    #[tag("Computed")]
940    Computed(ComputedPropName),
941}
942
943impl MemberProp {
944    pub fn is_ident_with(&self, sym: &str) -> bool {
945        matches!(self, MemberProp::Ident(i) if i.sym == sym)
946    }
947}
948
949#[ast_node("SuperPropExpression")]
950#[derive(Eq, Hash, EqIgnoreSpan, Default)]
951#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
952#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
953pub struct SuperPropExpr {
954    pub span: Span,
955
956    pub obj: Super,
957
958    #[cfg_attr(feature = "serde-impl", serde(rename = "property"))]
959    pub prop: SuperProp,
960}
961
962#[ast_node]
963#[derive(Eq, Hash, Is, EqIgnoreSpan)]
964#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
965#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
966pub enum SuperProp {
967    #[tag("Identifier")]
968    Ident(IdentName),
969    #[tag("Computed")]
970    Computed(ComputedPropName),
971}
972
973impl Take for MemberExpr {
974    fn dummy() -> Self {
975        MemberExpr {
976            span: DUMMY_SP,
977            obj: Take::dummy(),
978            prop: Take::dummy(),
979        }
980    }
981}
982
983impl Take for MemberProp {
984    fn dummy() -> Self {
985        Default::default()
986    }
987}
988
989impl Default for MemberProp {
990    fn default() -> Self {
991        MemberProp::Ident(Default::default())
992    }
993}
994
995impl Take for SuperProp {
996    fn dummy() -> Self {
997        SuperProp::Ident(Default::default())
998    }
999}
1000
1001impl Default for SuperProp {
1002    fn default() -> Self {
1003        SuperProp::Ident(Default::default())
1004    }
1005}
1006
1007#[ast_node("ConditionalExpression")]
1008#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1009#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1010#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1011pub struct CondExpr {
1012    pub span: Span,
1013
1014    pub test: Box<Expr>,
1015
1016    #[cfg_attr(feature = "serde-impl", serde(rename = "consequent"))]
1017    pub cons: Box<Expr>,
1018
1019    #[cfg_attr(feature = "serde-impl", serde(rename = "alternate"))]
1020    pub alt: Box<Expr>,
1021}
1022
1023impl Take for CondExpr {
1024    fn dummy() -> Self {
1025        CondExpr {
1026            span: DUMMY_SP,
1027            test: Take::dummy(),
1028            cons: Take::dummy(),
1029            alt: Take::dummy(),
1030        }
1031    }
1032}
1033
1034#[ast_node("CallExpression")]
1035#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1036#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1037#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1038pub struct CallExpr {
1039    pub span: Span,
1040    pub ctxt: SyntaxContext,
1041
1042    pub callee: Callee,
1043
1044    #[cfg_attr(feature = "serde-impl", serde(default, rename = "arguments"))]
1045    pub args: Vec<ExprOrSpread>,
1046
1047    #[cfg_attr(feature = "serde-impl", serde(default, rename = "typeArguments"))]
1048    #[cfg_attr(
1049        feature = "encoding-impl",
1050        encoding(with = "cbor4ii::core::types::Maybe")
1051    )]
1052    pub type_args: Option<Box<TsTypeParamInstantiation>>,
1053    // pub type_params: Option<TsTypeParamInstantiation>,
1054}
1055
1056impl Take for CallExpr {
1057    fn dummy() -> Self {
1058        Default::default()
1059    }
1060}
1061
1062#[ast_node("NewExpression")]
1063#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1064#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1065#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1066pub struct NewExpr {
1067    pub span: Span,
1068
1069    pub ctxt: SyntaxContext,
1070
1071    pub callee: Box<Expr>,
1072
1073    #[cfg_attr(feature = "serde-impl", serde(default, rename = "arguments"))]
1074    #[cfg_attr(
1075        feature = "encoding-impl",
1076        encoding(with = "::cbor4ii::core::types::Maybe")
1077    )]
1078    pub args: Option<Vec<ExprOrSpread>>,
1079
1080    #[cfg_attr(feature = "serde-impl", serde(default, rename = "typeArguments"))]
1081    #[cfg_attr(
1082        feature = "encoding-impl",
1083        encoding(with = "::cbor4ii::core::types::Maybe")
1084    )]
1085    pub type_args: Option<Box<TsTypeParamInstantiation>>,
1086    // pub type_params: Option<TsTypeParamInstantiation>,
1087}
1088
1089impl Take for NewExpr {
1090    fn dummy() -> Self {
1091        Default::default()
1092    }
1093}
1094
1095#[ast_node("SequenceExpression")]
1096#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1097#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1098#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1099pub struct SeqExpr {
1100    pub span: Span,
1101
1102    #[cfg_attr(feature = "serde-impl", serde(rename = "expressions"))]
1103    pub exprs: Vec<Box<Expr>>,
1104}
1105
1106impl Take for SeqExpr {
1107    fn dummy() -> Self {
1108        SeqExpr {
1109            span: DUMMY_SP,
1110            exprs: Take::dummy(),
1111        }
1112    }
1113}
1114
1115#[ast_node("ArrowFunctionExpression")]
1116#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1117#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1118#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1119pub struct ArrowExpr {
1120    pub span: Span,
1121
1122    pub ctxt: SyntaxContext,
1123
1124    pub params: Vec<Pat>,
1125
1126    /// This is boxed to reduce the type size of [Expr].
1127    pub body: Box<ArrowFunctionBody>,
1128
1129    #[cfg_attr(feature = "serde-impl", serde(default, rename = "async"))]
1130    pub is_async: bool,
1131
1132    #[cfg_attr(feature = "serde-impl", serde(default, rename = "generator"))]
1133    pub is_generator: bool,
1134
1135    #[cfg_attr(feature = "serde-impl", serde(default, rename = "typeParameters"))]
1136    #[cfg_attr(
1137        feature = "encoding-impl",
1138        encoding(with = "cbor4ii::core::types::Maybe")
1139    )]
1140    pub type_params: Option<Box<TsTypeParamDecl>>,
1141
1142    #[cfg_attr(feature = "serde-impl", serde(default))]
1143    #[cfg_attr(
1144        feature = "encoding-impl",
1145        encoding(with = "cbor4ii::core::types::Maybe")
1146    )]
1147    pub return_type: Option<Box<TsTypeAnn>>,
1148}
1149
1150impl Take for ArrowExpr {
1151    fn dummy() -> Self {
1152        ArrowExpr {
1153            ..Default::default()
1154        }
1155    }
1156}
1157
1158#[ast_node("YieldExpression")]
1159#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1160#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1161#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1162pub struct YieldExpr {
1163    pub span: Span,
1164
1165    #[cfg_attr(feature = "serde-impl", serde(default, rename = "argument"))]
1166    #[cfg_attr(
1167        feature = "encoding-impl",
1168        encoding(with = "cbor4ii::core::types::Maybe")
1169    )]
1170    pub arg: Option<Box<Expr>>,
1171
1172    #[cfg_attr(feature = "serde-impl", serde(default))]
1173    pub delegate: bool,
1174}
1175
1176impl Take for YieldExpr {
1177    fn dummy() -> Self {
1178        YieldExpr {
1179            span: DUMMY_SP,
1180            arg: Take::dummy(),
1181            delegate: false,
1182        }
1183    }
1184}
1185
1186#[ast_node("MetaProperty")]
1187#[derive(Eq, Hash, EqIgnoreSpan, Copy)]
1188#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1189#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1190pub struct MetaPropExpr {
1191    pub span: Span,
1192    pub kind: MetaPropKind,
1193}
1194
1195#[derive(StringEnum, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash, EqIgnoreSpan)]
1196#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1197#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1198#[cfg_attr(
1199    feature = "encoding-impl",
1200    derive(::swc_common::Encode, ::swc_common::Decode)
1201)]
1202#[cfg_attr(swc_ast_unknown, non_exhaustive)]
1203pub enum MetaPropKind {
1204    /// `new.target`
1205    NewTarget,
1206    /// `import.meta`
1207    ImportMeta,
1208}
1209
1210#[ast_node("AwaitExpression")]
1211#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1212#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1213#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1214pub struct AwaitExpr {
1215    pub span: Span,
1216
1217    #[cfg_attr(feature = "serde-impl", serde(rename = "argument"))]
1218    pub arg: Box<Expr>,
1219}
1220
1221#[ast_node("TemplateLiteral")]
1222#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1223#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1224#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1225pub struct Tpl {
1226    pub span: Span,
1227
1228    #[cfg_attr(feature = "serde-impl", serde(rename = "expressions"))]
1229    pub exprs: Vec<Box<Expr>>,
1230
1231    pub quasis: Vec<TplElement>,
1232}
1233
1234impl Take for Tpl {
1235    fn dummy() -> Self {
1236        Tpl {
1237            span: DUMMY_SP,
1238            exprs: Take::dummy(),
1239            quasis: Take::dummy(),
1240        }
1241    }
1242}
1243
1244#[ast_node("TaggedTemplateExpression")]
1245#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1246#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1247#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1248pub struct TaggedTpl {
1249    pub span: Span,
1250
1251    pub ctxt: SyntaxContext,
1252
1253    pub tag: Box<Expr>,
1254
1255    #[cfg_attr(feature = "serde-impl", serde(default, rename = "typeParameters"))]
1256    #[cfg_attr(
1257        feature = "encoding-impl",
1258        encoding(with = "cbor4ii::core::types::Maybe")
1259    )]
1260    pub type_params: Option<Box<TsTypeParamInstantiation>>,
1261
1262    /// This is boxed to reduce the type size of [Expr].
1263    #[cfg_attr(feature = "serde-impl", serde(rename = "template"))]
1264    pub tpl: Box<Tpl>,
1265}
1266
1267impl Take for TaggedTpl {
1268    fn dummy() -> Self {
1269        Default::default()
1270    }
1271}
1272
1273#[ast_node("TemplateElement")]
1274#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1275#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1276pub struct TplElement {
1277    pub span: Span,
1278    pub tail: bool,
1279
1280    /// This value is never used by `swc_ecma_codegen`, and this fact is
1281    /// considered as a public API.
1282    ///
1283    /// If you are going to use codegen right after creating a [TplElement], you
1284    /// don't have to worry about this value.
1285    #[cfg_attr(
1286        feature = "encoding-impl",
1287        encoding(with = "cbor4ii::core::types::Maybe")
1288    )]
1289    pub cooked: Option<Wtf8Atom>,
1290
1291    /// You may need to perform. `.replace("\r\n", "\n").replace('\r', "\n")` on
1292    /// this value.
1293    pub raw: Atom,
1294}
1295
1296impl Take for TplElement {
1297    fn dummy() -> Self {
1298        TplElement {
1299            span: DUMMY_SP,
1300            tail: Default::default(),
1301            cooked: None,
1302            raw: Default::default(),
1303        }
1304    }
1305}
1306
1307#[cfg(feature = "arbitrary")]
1308#[cfg_attr(docsrs, doc(cfg(feature = "arbitrary")))]
1309impl<'a> arbitrary::Arbitrary<'a> for TplElement {
1310    fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
1311        let span = u.arbitrary()?;
1312        let cooked = Some(u.arbitrary::<Wtf8Atom>()?.into());
1313        let raw = u.arbitrary::<String>()?.into();
1314
1315        Ok(Self {
1316            span,
1317            tail: false,
1318            cooked,
1319            raw,
1320        })
1321    }
1322}
1323
1324#[ast_node("ParenthesisExpression")]
1325#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1326#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1327#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1328pub struct ParenExpr {
1329    pub span: Span,
1330
1331    #[cfg_attr(feature = "serde-impl", serde(rename = "expression"))]
1332    pub expr: Box<Expr>,
1333}
1334impl Take for ParenExpr {
1335    fn dummy() -> Self {
1336        ParenExpr {
1337            span: DUMMY_SP,
1338            expr: Take::dummy(),
1339        }
1340    }
1341}
1342
1343#[ast_node]
1344#[derive(Eq, Hash, Is, EqIgnoreSpan)]
1345#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1346#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1347pub enum Callee {
1348    #[tag("Super")]
1349    #[is(name = "super_")]
1350    Super(Super),
1351
1352    #[tag("Import")]
1353    Import(Import),
1354
1355    #[tag("*")]
1356    Expr(Box<Expr>),
1357}
1358
1359impl Default for Callee {
1360    fn default() -> Self {
1361        Callee::Super(Default::default())
1362    }
1363}
1364
1365impl Take for Callee {
1366    fn dummy() -> Self {
1367        Callee::Super(Take::dummy())
1368    }
1369}
1370
1371#[ast_node("Super")]
1372#[derive(Eq, Hash, Copy, EqIgnoreSpan, Default)]
1373#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1374#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1375pub struct Super {
1376    pub span: Span,
1377}
1378
1379impl Take for Super {
1380    fn dummy() -> Self {
1381        Super { span: DUMMY_SP }
1382    }
1383}
1384
1385#[ast_node("Import")]
1386#[derive(Eq, Hash, Copy, EqIgnoreSpan)]
1387#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1388#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1389pub struct Import {
1390    pub span: Span,
1391    pub phase: ImportPhase,
1392}
1393
1394impl Take for Import {
1395    fn dummy() -> Self {
1396        Import {
1397            span: DUMMY_SP,
1398            phase: ImportPhase::default(),
1399        }
1400    }
1401}
1402
1403#[derive(Clone, Debug, PartialEq, Eq, Hash, EqIgnoreSpan)]
1404#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1405#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1406#[cfg_attr(feature = "serde-impl", derive(serde::Serialize, serde::Deserialize))]
1407#[cfg_attr(
1408    feature = "encoding-impl",
1409    derive(::swc_common::Encode, ::swc_common::Decode)
1410)]
1411pub struct ExprOrSpread {
1412    #[cfg_attr(feature = "serde-impl", serde(default))]
1413    #[cfg_attr(
1414        feature = "encoding-impl",
1415        encoding(with = "cbor4ii::core::types::Maybe")
1416    )]
1417    pub spread: Option<Span>,
1418
1419    #[cfg_attr(feature = "serde-impl", serde(rename = "expression"))]
1420    pub expr: Box<Expr>,
1421}
1422
1423impl Spanned for ExprOrSpread {
1424    #[inline]
1425    fn span(&self) -> Span {
1426        let expr = self.expr.span();
1427        match self.spread {
1428            Some(spread) => expr.with_lo(spread.lo()),
1429            None => expr,
1430        }
1431    }
1432
1433    #[inline]
1434    fn span_lo(&self) -> BytePos {
1435        match self.spread {
1436            Some(s) => s.lo,
1437            None => self.expr.span_lo(),
1438        }
1439    }
1440
1441    #[inline]
1442    fn span_hi(&self) -> BytePos {
1443        self.expr.span_hi()
1444    }
1445}
1446
1447impl From<Box<Expr>> for ExprOrSpread {
1448    fn from(expr: Box<Expr>) -> Self {
1449        Self { expr, spread: None }
1450    }
1451}
1452
1453bridge_from!(ExprOrSpread, Box<Expr>, Expr);
1454
1455#[ast_node]
1456#[derive(Eq, Hash, Is, EqIgnoreSpan)]
1457#[allow(variant_size_differences)]
1458#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1459#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1460pub enum ArrowFunctionBody {
1461    #[tag("FunctionBody")]
1462    FunctionBody(FunctionBody),
1463    #[tag("*")]
1464    Expr(Box<Expr>),
1465}
1466
1467/// Deprecated alias for [`ArrowFunctionBody`].
1468///
1469/// This alias preserves only the former type name. The former
1470/// `BlockStmtOrExpr::BlockStmt` variant has been replaced by
1471/// [`ArrowFunctionBody::FunctionBody`].
1472#[deprecated(
1473    note = "Use `ArrowFunctionBody`; its block variant is `ArrowFunctionBody::FunctionBody`"
1474)]
1475pub type BlockStmtOrExpr = ArrowFunctionBody;
1476
1477impl Default for ArrowFunctionBody {
1478    fn default() -> Self {
1479        ArrowFunctionBody::FunctionBody(Default::default())
1480    }
1481}
1482
1483impl<T> From<T> for ArrowFunctionBody
1484where
1485    T: Into<Expr>,
1486{
1487    fn from(e: T) -> Self {
1488        Self::Expr(Box::new(e.into()))
1489    }
1490}
1491
1492impl Take for ArrowFunctionBody {
1493    fn dummy() -> Self {
1494        ArrowFunctionBody::Expr(Take::dummy())
1495    }
1496}
1497
1498#[ast_node]
1499#[derive(Is, Eq, Hash, EqIgnoreSpan)]
1500#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1501#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1502pub enum AssignTarget {
1503    #[tag("Identifier")]
1504    #[tag("MemberExpression")]
1505    #[tag("SuperPropExpression")]
1506    #[tag("OptionalChainingExpression")]
1507    #[tag("ParenthesisExpression")]
1508    #[tag("TsAsExpression")]
1509    #[tag("TsSatisfiesExpression")]
1510    #[tag("TsNonNullExpression")]
1511    #[tag("TsTypeAssertion")]
1512    #[tag("TsInstantiation")]
1513    Simple(SimpleAssignTarget),
1514    #[tag("ArrayPattern")]
1515    #[tag("ObjectPattern")]
1516    Pat(AssignTargetPat),
1517}
1518
1519impl TryFrom<Pat> for AssignTarget {
1520    type Error = Pat;
1521
1522    fn try_from(p: Pat) -> Result<Self, Self::Error> {
1523        Ok(match p {
1524            Pat::Array(a) => AssignTargetPat::Array(a).into(),
1525            Pat::Object(o) => AssignTargetPat::Object(o).into(),
1526
1527            Pat::Ident(i) => SimpleAssignTarget::Ident(i).into(),
1528            Pat::Invalid(i) => SimpleAssignTarget::Invalid(i).into(),
1529
1530            Pat::Expr(e) => Self::try_from(e).map_err(|e| -> Pat { e.into() })?,
1531
1532            _ => return Err(p),
1533        })
1534    }
1535}
1536impl TryFrom<Box<Pat>> for AssignTarget {
1537    type Error = Box<Pat>;
1538
1539    fn try_from(p: Box<Pat>) -> Result<Self, Self::Error> {
1540        (*p).try_into().map_err(Box::new)
1541    }
1542}
1543
1544impl TryFrom<Box<Expr>> for AssignTarget {
1545    type Error = Box<Expr>;
1546
1547    fn try_from(e: Box<Expr>) -> Result<Self, Self::Error> {
1548        Ok(Self::Simple(SimpleAssignTarget::try_from(e)?))
1549    }
1550}
1551
1552#[ast_node]
1553#[derive(Is, Eq, Hash, EqIgnoreSpan)]
1554#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1555#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1556pub enum AssignTargetPat {
1557    #[tag("ArrayPattern")]
1558    Array(ArrayPat),
1559    #[tag("ObjectPattern")]
1560    Object(ObjectPat),
1561    #[tag("Invalid")]
1562    Invalid(Invalid),
1563}
1564
1565impl Take for AssignTargetPat {
1566    fn dummy() -> Self {
1567        Default::default()
1568    }
1569}
1570
1571impl Default for AssignTargetPat {
1572    fn default() -> Self {
1573        AssignTargetPat::Invalid(Take::dummy())
1574    }
1575}
1576
1577impl From<AssignTargetPat> for Pat {
1578    fn from(pat: AssignTargetPat) -> Self {
1579        match pat {
1580            AssignTargetPat::Array(a) => a.into(),
1581            AssignTargetPat::Object(o) => o.into(),
1582            AssignTargetPat::Invalid(i) => i.into(),
1583            #[cfg(all(swc_ast_unknown, feature = "encoding-impl"))]
1584            _ => swc_common::unknown!(),
1585        }
1586    }
1587}
1588
1589impl From<AssignTargetPat> for Box<Pat> {
1590    fn from(pat: AssignTargetPat) -> Self {
1591        Box::new(pat.into())
1592    }
1593}
1594
1595impl TryFrom<Pat> for AssignTargetPat {
1596    type Error = Pat;
1597
1598    fn try_from(p: Pat) -> Result<Self, Self::Error> {
1599        Ok(match p {
1600            Pat::Array(a) => AssignTargetPat::Array(a),
1601            Pat::Object(o) => AssignTargetPat::Object(o),
1602            Pat::Invalid(i) => AssignTargetPat::Invalid(i),
1603
1604            _ => return Err(p),
1605        })
1606    }
1607}
1608
1609#[ast_node]
1610#[derive(Is, Eq, Hash, EqIgnoreSpan)]
1611#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1612#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1613pub enum SimpleAssignTarget {
1614    /// Note: This type is to help implementing visitor and the field `type_ann`
1615    /// is always [None].
1616    #[tag("Identifier")]
1617    Ident(BindingIdent),
1618    #[tag("MemberExpression")]
1619    Member(MemberExpr),
1620    #[tag("SuperPropExpression")]
1621    SuperProp(SuperPropExpr),
1622    #[tag("ParenthesisExpression")]
1623    Paren(ParenExpr),
1624    #[tag("OptionalChainingExpression")]
1625    OptChain(OptChainExpr),
1626    #[tag("TsAsExpression")]
1627    TsAs(TsAsExpr),
1628    #[tag("TsSatisfiesExpression")]
1629    TsSatisfies(TsSatisfiesExpr),
1630    #[tag("TsNonNullExpression")]
1631    TsNonNull(TsNonNullExpr),
1632    #[tag("TsTypeAssertion")]
1633    TsTypeAssertion(TsTypeAssertion),
1634    #[tag("TsInstantiation")]
1635    TsInstantiation(TsInstantiation),
1636
1637    #[tag("Invalid")]
1638    Invalid(Invalid),
1639}
1640
1641impl TryFrom<Box<Expr>> for SimpleAssignTarget {
1642    type Error = Box<Expr>;
1643
1644    fn try_from(e: Box<Expr>) -> Result<Self, Self::Error> {
1645        Ok(match *e {
1646            Expr::Ident(i) => SimpleAssignTarget::Ident(i.into()),
1647            Expr::Member(m) => SimpleAssignTarget::Member(m),
1648            Expr::SuperProp(s) => SimpleAssignTarget::SuperProp(s),
1649            Expr::OptChain(s) => SimpleAssignTarget::OptChain(s),
1650            Expr::Paren(s) => SimpleAssignTarget::Paren(s),
1651            Expr::TsAs(a) => SimpleAssignTarget::TsAs(a),
1652            Expr::TsSatisfies(s) => SimpleAssignTarget::TsSatisfies(s),
1653            Expr::TsNonNull(n) => SimpleAssignTarget::TsNonNull(n),
1654            Expr::TsTypeAssertion(a) => SimpleAssignTarget::TsTypeAssertion(a),
1655            Expr::TsInstantiation(a) => SimpleAssignTarget::TsInstantiation(a),
1656            _ => return Err(e),
1657        })
1658    }
1659}
1660
1661bridge_from!(SimpleAssignTarget, BindingIdent, Ident);
1662
1663impl SimpleAssignTarget {
1664    pub fn leftmost(&self) -> Option<&Ident> {
1665        match self {
1666            SimpleAssignTarget::Ident(i) => Some(&i.id),
1667            SimpleAssignTarget::Member(MemberExpr { obj, .. }) => obj.leftmost(),
1668            _ => None,
1669        }
1670    }
1671}
1672
1673impl Take for SimpleAssignTarget {
1674    fn dummy() -> Self {
1675        SimpleAssignTarget::Invalid(Take::dummy())
1676    }
1677}
1678
1679bridge_from!(AssignTarget, BindingIdent, Ident);
1680bridge_from!(AssignTarget, SimpleAssignTarget, BindingIdent);
1681bridge_from!(AssignTarget, SimpleAssignTarget, MemberExpr);
1682bridge_from!(AssignTarget, SimpleAssignTarget, SuperPropExpr);
1683bridge_from!(AssignTarget, SimpleAssignTarget, ParenExpr);
1684bridge_from!(AssignTarget, SimpleAssignTarget, TsAsExpr);
1685bridge_from!(AssignTarget, SimpleAssignTarget, TsSatisfiesExpr);
1686bridge_from!(AssignTarget, SimpleAssignTarget, TsNonNullExpr);
1687bridge_from!(AssignTarget, SimpleAssignTarget, TsTypeAssertion);
1688
1689bridge_from!(AssignTarget, AssignTargetPat, ArrayPat);
1690bridge_from!(AssignTarget, AssignTargetPat, ObjectPat);
1691
1692impl From<SimpleAssignTarget> for Box<Expr> {
1693    fn from(s: SimpleAssignTarget) -> Self {
1694        match s {
1695            SimpleAssignTarget::Ident(i) => i.into(),
1696            SimpleAssignTarget::Member(m) => m.into(),
1697            SimpleAssignTarget::SuperProp(s) => s.into(),
1698            SimpleAssignTarget::Paren(s) => s.into(),
1699            SimpleAssignTarget::OptChain(s) => s.into(),
1700            SimpleAssignTarget::TsAs(a) => a.into(),
1701            SimpleAssignTarget::TsSatisfies(s) => s.into(),
1702            SimpleAssignTarget::TsNonNull(n) => n.into(),
1703            SimpleAssignTarget::TsTypeAssertion(a) => a.into(),
1704            SimpleAssignTarget::TsInstantiation(a) => a.into(),
1705            SimpleAssignTarget::Invalid(i) => i.into(),
1706            #[cfg(all(swc_ast_unknown, feature = "encoding-impl"))]
1707            _ => swc_common::unknown!(),
1708        }
1709    }
1710}
1711
1712impl AssignTarget {
1713    pub fn as_ident(&self) -> Option<&BindingIdent> {
1714        self.as_simple()?.as_ident()
1715    }
1716
1717    pub fn as_ident_mut(&mut self) -> Option<&mut BindingIdent> {
1718        self.as_mut_simple()?.as_mut_ident()
1719    }
1720}
1721
1722impl Default for AssignTarget {
1723    fn default() -> Self {
1724        SimpleAssignTarget::dummy().into()
1725    }
1726}
1727
1728impl Take for AssignTarget {
1729    fn dummy() -> Self {
1730        Default::default()
1731    }
1732}
1733
1734#[ast_node("OptionalChainingExpression")]
1735#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1736#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1737#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1738pub struct OptChainExpr {
1739    pub span: Span,
1740    pub optional: bool,
1741    /// This is boxed to reduce the type size of [Expr].
1742    pub base: Box<OptChainBase>,
1743}
1744
1745#[ast_node]
1746#[derive(Eq, Hash, Is, EqIgnoreSpan)]
1747#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1748#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1749pub enum OptChainBase {
1750    #[tag("MemberExpression")]
1751    Member(MemberExpr),
1752    #[tag("CallExpression")]
1753    Call(OptCall),
1754}
1755
1756impl Default for OptChainBase {
1757    fn default() -> Self {
1758        OptChainBase::Member(Default::default())
1759    }
1760}
1761
1762#[ast_node("CallExpression")]
1763#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1764#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1765#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1766pub struct OptCall {
1767    pub span: Span,
1768
1769    pub ctxt: SyntaxContext,
1770
1771    pub callee: Box<Expr>,
1772
1773    #[cfg_attr(feature = "serde-impl", serde(default, rename = "arguments"))]
1774    pub args: Vec<ExprOrSpread>,
1775
1776    #[cfg_attr(feature = "serde-impl", serde(default, rename = "typeArguments"))]
1777    #[cfg_attr(
1778        feature = "encoding-impl",
1779        encoding(with = "cbor4ii::core::types::Maybe")
1780    )]
1781    pub type_args: Option<Box<TsTypeParamInstantiation>>,
1782    // pub type_params: Option<TsTypeParamInstantiation>,
1783}
1784
1785impl Take for OptChainExpr {
1786    fn dummy() -> Self {
1787        Self {
1788            span: DUMMY_SP,
1789            optional: false,
1790            base: Box::new(OptChainBase::Member(Take::dummy())),
1791        }
1792    }
1793}
1794
1795impl From<OptChainBase> for Expr {
1796    fn from(opt: OptChainBase) -> Self {
1797        match opt {
1798            OptChainBase::Call(OptCall {
1799                span,
1800                ctxt,
1801                callee,
1802                args,
1803                type_args,
1804            }) => Self::Call(CallExpr {
1805                callee: Callee::Expr(callee),
1806                args,
1807                span,
1808                type_args,
1809                ctxt,
1810            }),
1811            OptChainBase::Member(member) => Self::Member(member),
1812            #[cfg(all(swc_ast_unknown, feature = "encoding-impl"))]
1813            _ => swc_common::unknown!(),
1814        }
1815    }
1816}
1817
1818impl Take for OptCall {
1819    fn dummy() -> Self {
1820        Self {
1821            ..Default::default()
1822        }
1823    }
1824}
1825
1826impl From<OptCall> for CallExpr {
1827    fn from(
1828        OptCall {
1829            span,
1830            ctxt,
1831            callee,
1832            args,
1833            type_args,
1834        }: OptCall,
1835    ) -> Self {
1836        Self {
1837            span,
1838            callee: Callee::Expr(callee),
1839            args,
1840            type_args,
1841            ctxt,
1842        }
1843    }
1844}
1845
1846bridge_expr_from!(CallExpr, OptCall);
1847
1848test_de!(
1849    jsx_element,
1850    JSXElement,
1851    r#"{
1852      "type": "JSXElement",
1853      "span": {
1854        "start": 0,
1855        "end": 5,
1856        "ctxt": 0
1857      },
1858      "opening": {
1859        "type": "JSXOpeningElement",
1860        "name": {
1861          "type": "Identifier",
1862          "span": {
1863            "start": 1,
1864            "end": 2,
1865            "ctxt": 0
1866          },
1867          "value": "a",
1868          "optional": false
1869        },
1870        "span": {
1871          "start": 1,
1872          "end": 5,
1873          "ctxt": 0
1874        },
1875        "selfClosing": true
1876      },
1877      "children": [],
1878      "closing": null
1879    }"#
1880);