swc_ecma_ast/
expr.rs

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