swc_ecma_ast/
expr.rs

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