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 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))]
1119pub enum MetaPropKind {
1120    /// `new.target`
1121    NewTarget,
1122    /// `import.meta`
1123    ImportMeta,
1124}
1125
1126#[ast_node("AwaitExpression")]
1127#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1128#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1129#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1130pub struct AwaitExpr {
1131    pub span: Span,
1132
1133    #[cfg_attr(feature = "serde-impl", serde(rename = "argument"))]
1134    pub arg: Box<Expr>,
1135}
1136
1137#[ast_node("TemplateLiteral")]
1138#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1139#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1140#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1141pub struct Tpl {
1142    pub span: Span,
1143
1144    #[cfg_attr(feature = "serde-impl", serde(rename = "expressions"))]
1145    pub exprs: Vec<Box<Expr>>,
1146
1147    pub quasis: Vec<TplElement>,
1148}
1149
1150impl Take for Tpl {
1151    fn dummy() -> Self {
1152        Tpl {
1153            span: DUMMY_SP,
1154            exprs: Take::dummy(),
1155            quasis: Take::dummy(),
1156        }
1157    }
1158}
1159
1160#[ast_node("TaggedTemplateExpression")]
1161#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1162#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1163#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1164pub struct TaggedTpl {
1165    pub span: Span,
1166
1167    pub ctxt: SyntaxContext,
1168
1169    pub tag: Box<Expr>,
1170
1171    #[cfg_attr(feature = "serde-impl", serde(default, rename = "typeParameters"))]
1172    pub type_params: Option<Box<TsTypeParamInstantiation>>,
1173
1174    /// This is boxed to reduce the type size of [Expr].
1175    #[cfg_attr(feature = "serde-impl", serde(rename = "template"))]
1176    pub tpl: Box<Tpl>,
1177}
1178
1179impl Take for TaggedTpl {
1180    fn dummy() -> Self {
1181        Default::default()
1182    }
1183}
1184
1185#[ast_node("TemplateElement")]
1186#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1187#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1188pub struct TplElement {
1189    pub span: Span,
1190    pub tail: bool,
1191
1192    /// This value is never used by `swc_ecma_codegen`, and this fact is
1193    /// considered as a public API.
1194    ///
1195    /// If you are going to use codegen right after creating a [TplElement], you
1196    /// don't have to worry about this value.
1197    pub cooked: Option<Atom>,
1198
1199    /// You may need to perform. `.replace("\r\n", "\n").replace('\r', "\n")` on
1200    /// this value.
1201    pub raw: Atom,
1202}
1203
1204impl Take for TplElement {
1205    fn dummy() -> Self {
1206        TplElement {
1207            span: DUMMY_SP,
1208            tail: Default::default(),
1209            cooked: None,
1210            raw: Default::default(),
1211        }
1212    }
1213}
1214
1215#[cfg(feature = "arbitrary")]
1216#[cfg_attr(docsrs, doc(cfg(feature = "arbitrary")))]
1217impl<'a> arbitrary::Arbitrary<'a> for TplElement {
1218    fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
1219        let span = u.arbitrary()?;
1220        let cooked = Some(u.arbitrary::<String>()?.into());
1221        let raw = u.arbitrary::<String>()?.into();
1222
1223        Ok(Self {
1224            span,
1225            tail: false,
1226            cooked,
1227            raw,
1228        })
1229    }
1230}
1231
1232#[ast_node("ParenthesisExpression")]
1233#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1234#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1235#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1236pub struct ParenExpr {
1237    pub span: Span,
1238
1239    #[cfg_attr(feature = "serde-impl", serde(rename = "expression"))]
1240    pub expr: Box<Expr>,
1241}
1242impl Take for ParenExpr {
1243    fn dummy() -> Self {
1244        ParenExpr {
1245            span: DUMMY_SP,
1246            expr: Take::dummy(),
1247        }
1248    }
1249}
1250
1251#[ast_node]
1252#[derive(Eq, Hash, Is, EqIgnoreSpan)]
1253#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1254#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1255pub enum Callee {
1256    #[tag("Super")]
1257    #[is(name = "super_")]
1258    Super(Super),
1259
1260    #[tag("Import")]
1261    Import(Import),
1262
1263    #[tag("*")]
1264    Expr(Box<Expr>),
1265}
1266
1267impl Default for Callee {
1268    fn default() -> Self {
1269        Callee::Super(Default::default())
1270    }
1271}
1272
1273impl Take for Callee {
1274    fn dummy() -> Self {
1275        Callee::Super(Take::dummy())
1276    }
1277}
1278
1279#[ast_node("Super")]
1280#[derive(Eq, Hash, Copy, EqIgnoreSpan, Default)]
1281#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1282#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1283pub struct Super {
1284    pub span: Span,
1285}
1286
1287impl Take for Super {
1288    fn dummy() -> Self {
1289        Super { span: DUMMY_SP }
1290    }
1291}
1292
1293#[ast_node("Import")]
1294#[derive(Eq, Hash, Copy, EqIgnoreSpan)]
1295#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1296#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1297pub struct Import {
1298    pub span: Span,
1299    pub phase: ImportPhase,
1300}
1301
1302impl Take for Import {
1303    fn dummy() -> Self {
1304        Import {
1305            span: DUMMY_SP,
1306            phase: ImportPhase::default(),
1307        }
1308    }
1309}
1310
1311#[derive(Clone, Debug, PartialEq, Eq, Hash, EqIgnoreSpan)]
1312#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1313#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1314#[cfg_attr(
1315    any(feature = "rkyv-impl"),
1316    derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
1317)]
1318#[cfg_attr(
1319    feature = "rkyv",
1320    rkyv(serialize_bounds(__S: rkyv::ser::Writer + rkyv::ser::Allocator,
1321        __S::Error: rkyv::rancor::Source))
1322)]
1323#[cfg_attr(
1324    feature = "rkyv-impl",
1325    rkyv(deserialize_bounds(__D::Error: rkyv::rancor::Source))
1326)]
1327#[cfg_attr(
1328                    feature = "rkyv-impl",
1329                    rkyv(bytecheck(bounds(
1330                        __C: rkyv::validation::ArchiveContext,
1331                        __C::Error: rkyv::rancor::Source
1332                    )))
1333                )]
1334#[cfg_attr(feature = "rkyv-impl", repr(C))]
1335#[cfg_attr(feature = "serde-impl", derive(serde::Serialize, serde::Deserialize))]
1336pub struct ExprOrSpread {
1337    #[cfg_attr(feature = "serde-impl", serde(default))]
1338    #[cfg_attr(feature = "__rkyv", rkyv(omit_bounds))]
1339    pub spread: Option<Span>,
1340
1341    #[cfg_attr(feature = "serde-impl", serde(rename = "expression"))]
1342    #[cfg_attr(feature = "__rkyv", rkyv(omit_bounds))]
1343    pub expr: Box<Expr>,
1344}
1345
1346impl Spanned for ExprOrSpread {
1347    #[inline]
1348    fn span(&self) -> Span {
1349        let expr = self.expr.span();
1350        match self.spread {
1351            Some(spread) => expr.with_lo(spread.lo()),
1352            None => expr,
1353        }
1354    }
1355
1356    #[inline]
1357    fn span_lo(&self) -> BytePos {
1358        match self.spread {
1359            Some(s) => s.lo,
1360            None => self.expr.span_lo(),
1361        }
1362    }
1363
1364    #[inline]
1365    fn span_hi(&self) -> BytePos {
1366        self.expr.span_hi()
1367    }
1368}
1369
1370impl From<Box<Expr>> for ExprOrSpread {
1371    fn from(expr: Box<Expr>) -> Self {
1372        Self { expr, spread: None }
1373    }
1374}
1375
1376bridge_from!(ExprOrSpread, Box<Expr>, Expr);
1377
1378#[ast_node]
1379#[derive(Eq, Hash, Is, EqIgnoreSpan)]
1380#[allow(variant_size_differences)]
1381#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1382#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1383pub enum BlockStmtOrExpr {
1384    #[tag("BlockStatement")]
1385    BlockStmt(BlockStmt),
1386    #[tag("*")]
1387    Expr(Box<Expr>),
1388}
1389
1390impl Default for BlockStmtOrExpr {
1391    fn default() -> Self {
1392        BlockStmtOrExpr::BlockStmt(Default::default())
1393    }
1394}
1395
1396impl<T> From<T> for BlockStmtOrExpr
1397where
1398    T: Into<Expr>,
1399{
1400    fn from(e: T) -> Self {
1401        Self::Expr(Box::new(e.into()))
1402    }
1403}
1404
1405impl Take for BlockStmtOrExpr {
1406    fn dummy() -> Self {
1407        BlockStmtOrExpr::Expr(Take::dummy())
1408    }
1409}
1410
1411#[ast_node]
1412#[derive(Is, Eq, Hash, EqIgnoreSpan)]
1413#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1414#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1415pub enum AssignTarget {
1416    #[tag("Identifier")]
1417    #[tag("MemberExpression")]
1418    #[tag("SuperPropExpression")]
1419    #[tag("OptionalChainingExpression")]
1420    #[tag("ParenthesisExpression")]
1421    #[tag("TsAsExpression")]
1422    #[tag("TsSatisfiesExpression")]
1423    #[tag("TsNonNullExpression")]
1424    #[tag("TsTypeAssertion")]
1425    #[tag("TsInstantiation")]
1426    Simple(SimpleAssignTarget),
1427    #[tag("ArrayPattern")]
1428    #[tag("ObjectPattern")]
1429    Pat(AssignTargetPat),
1430}
1431
1432impl TryFrom<Pat> for AssignTarget {
1433    type Error = Pat;
1434
1435    fn try_from(p: Pat) -> Result<Self, Self::Error> {
1436        Ok(match p {
1437            Pat::Array(a) => AssignTargetPat::Array(a).into(),
1438            Pat::Object(o) => AssignTargetPat::Object(o).into(),
1439
1440            Pat::Ident(i) => SimpleAssignTarget::Ident(i).into(),
1441            Pat::Invalid(i) => SimpleAssignTarget::Invalid(i).into(),
1442
1443            Pat::Expr(e) => match Self::try_from(e) {
1444                Ok(v) => v,
1445                Err(e) => return Err(e.into()),
1446            },
1447
1448            _ => return Err(p),
1449        })
1450    }
1451}
1452impl TryFrom<Box<Pat>> for AssignTarget {
1453    type Error = Box<Pat>;
1454
1455    fn try_from(p: Box<Pat>) -> Result<Self, Self::Error> {
1456        (*p).try_into().map_err(Box::new)
1457    }
1458}
1459
1460impl TryFrom<Box<Expr>> for AssignTarget {
1461    type Error = Box<Expr>;
1462
1463    fn try_from(e: Box<Expr>) -> Result<Self, Self::Error> {
1464        Ok(Self::Simple(SimpleAssignTarget::try_from(e)?))
1465    }
1466}
1467
1468#[ast_node]
1469#[derive(Is, Eq, Hash, EqIgnoreSpan)]
1470#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1471#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1472pub enum AssignTargetPat {
1473    #[tag("ArrayPattern")]
1474    Array(ArrayPat),
1475    #[tag("ObjectPattern")]
1476    Object(ObjectPat),
1477    #[tag("Invalid")]
1478    Invalid(Invalid),
1479}
1480
1481impl Take for AssignTargetPat {
1482    fn dummy() -> Self {
1483        Default::default()
1484    }
1485}
1486
1487impl Default for AssignTargetPat {
1488    fn default() -> Self {
1489        AssignTargetPat::Invalid(Take::dummy())
1490    }
1491}
1492
1493impl From<AssignTargetPat> for Pat {
1494    fn from(pat: AssignTargetPat) -> Self {
1495        match pat {
1496            AssignTargetPat::Array(a) => a.into(),
1497            AssignTargetPat::Object(o) => o.into(),
1498            AssignTargetPat::Invalid(i) => i.into(),
1499        }
1500    }
1501}
1502
1503impl From<AssignTargetPat> for Box<Pat> {
1504    fn from(pat: AssignTargetPat) -> Self {
1505        Box::new(pat.into())
1506    }
1507}
1508
1509impl TryFrom<Pat> for AssignTargetPat {
1510    type Error = Pat;
1511
1512    fn try_from(p: Pat) -> Result<Self, Self::Error> {
1513        Ok(match p {
1514            Pat::Array(a) => AssignTargetPat::Array(a),
1515            Pat::Object(o) => AssignTargetPat::Object(o),
1516            Pat::Invalid(i) => AssignTargetPat::Invalid(i),
1517
1518            _ => return Err(p),
1519        })
1520    }
1521}
1522
1523#[ast_node]
1524#[derive(Is, Eq, Hash, EqIgnoreSpan)]
1525#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1526#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1527pub enum SimpleAssignTarget {
1528    /// Note: This type is to help implementing visitor and the field `type_ann`
1529    /// is always [None].
1530    #[tag("Identifier")]
1531    Ident(BindingIdent),
1532    #[tag("MemberExpression")]
1533    Member(MemberExpr),
1534    #[tag("SuperPropExpression")]
1535    SuperProp(SuperPropExpr),
1536    #[tag("ParenthesisExpression")]
1537    Paren(ParenExpr),
1538    #[tag("OptionalChainingExpression")]
1539    OptChain(OptChainExpr),
1540    #[tag("TsAsExpression")]
1541    TsAs(TsAsExpr),
1542    #[tag("TsSatisfiesExpression")]
1543    TsSatisfies(TsSatisfiesExpr),
1544    #[tag("TsNonNullExpression")]
1545    TsNonNull(TsNonNullExpr),
1546    #[tag("TsTypeAssertion")]
1547    TsTypeAssertion(TsTypeAssertion),
1548    #[tag("TsInstantiation")]
1549    TsInstantiation(TsInstantiation),
1550
1551    #[tag("Invaliid")]
1552    Invalid(Invalid),
1553}
1554
1555impl TryFrom<Box<Expr>> for SimpleAssignTarget {
1556    type Error = Box<Expr>;
1557
1558    fn try_from(e: Box<Expr>) -> Result<Self, Self::Error> {
1559        Ok(match *e {
1560            Expr::Ident(i) => SimpleAssignTarget::Ident(i.into()),
1561            Expr::Member(m) => SimpleAssignTarget::Member(m),
1562            Expr::SuperProp(s) => SimpleAssignTarget::SuperProp(s),
1563            Expr::OptChain(s) => SimpleAssignTarget::OptChain(s),
1564            Expr::Paren(s) => SimpleAssignTarget::Paren(s),
1565            Expr::TsAs(a) => SimpleAssignTarget::TsAs(a),
1566            Expr::TsSatisfies(s) => SimpleAssignTarget::TsSatisfies(s),
1567            Expr::TsNonNull(n) => SimpleAssignTarget::TsNonNull(n),
1568            Expr::TsTypeAssertion(a) => SimpleAssignTarget::TsTypeAssertion(a),
1569            Expr::TsInstantiation(a) => SimpleAssignTarget::TsInstantiation(a),
1570            _ => return Err(e),
1571        })
1572    }
1573}
1574
1575bridge_from!(SimpleAssignTarget, BindingIdent, Ident);
1576
1577impl SimpleAssignTarget {
1578    pub fn leftmost(&self) -> Option<Cow<Ident>> {
1579        match self {
1580            SimpleAssignTarget::Ident(i) => {
1581                Some(Cow::Owned(Ident::new(i.sym.clone(), i.span, i.ctxt)))
1582            }
1583            SimpleAssignTarget::Member(MemberExpr { obj, .. }) => obj.leftmost().map(Cow::Borrowed),
1584            _ => None,
1585        }
1586    }
1587}
1588
1589impl Take for SimpleAssignTarget {
1590    fn dummy() -> Self {
1591        SimpleAssignTarget::Invalid(Take::dummy())
1592    }
1593}
1594
1595bridge_from!(AssignTarget, BindingIdent, Ident);
1596bridge_from!(AssignTarget, SimpleAssignTarget, BindingIdent);
1597bridge_from!(AssignTarget, SimpleAssignTarget, MemberExpr);
1598bridge_from!(AssignTarget, SimpleAssignTarget, SuperPropExpr);
1599bridge_from!(AssignTarget, SimpleAssignTarget, ParenExpr);
1600bridge_from!(AssignTarget, SimpleAssignTarget, TsAsExpr);
1601bridge_from!(AssignTarget, SimpleAssignTarget, TsSatisfiesExpr);
1602bridge_from!(AssignTarget, SimpleAssignTarget, TsNonNullExpr);
1603bridge_from!(AssignTarget, SimpleAssignTarget, TsTypeAssertion);
1604
1605bridge_from!(AssignTarget, AssignTargetPat, ArrayPat);
1606bridge_from!(AssignTarget, AssignTargetPat, ObjectPat);
1607
1608impl From<SimpleAssignTarget> for Box<Expr> {
1609    fn from(s: SimpleAssignTarget) -> Self {
1610        match s {
1611            SimpleAssignTarget::Ident(i) => i.into(),
1612            SimpleAssignTarget::Member(m) => m.into(),
1613            SimpleAssignTarget::SuperProp(s) => s.into(),
1614            SimpleAssignTarget::Paren(s) => s.into(),
1615            SimpleAssignTarget::OptChain(s) => s.into(),
1616            SimpleAssignTarget::TsAs(a) => a.into(),
1617            SimpleAssignTarget::TsSatisfies(s) => s.into(),
1618            SimpleAssignTarget::TsNonNull(n) => n.into(),
1619            SimpleAssignTarget::TsTypeAssertion(a) => a.into(),
1620            SimpleAssignTarget::TsInstantiation(a) => a.into(),
1621            SimpleAssignTarget::Invalid(i) => i.into(),
1622        }
1623    }
1624}
1625
1626impl AssignTarget {
1627    pub fn as_ident(&self) -> Option<&BindingIdent> {
1628        self.as_simple()?.as_ident()
1629    }
1630
1631    pub fn as_ident_mut(&mut self) -> Option<&mut BindingIdent> {
1632        self.as_mut_simple()?.as_mut_ident()
1633    }
1634}
1635
1636impl Default for AssignTarget {
1637    fn default() -> Self {
1638        SimpleAssignTarget::dummy().into()
1639    }
1640}
1641
1642impl Take for AssignTarget {
1643    fn dummy() -> Self {
1644        Default::default()
1645    }
1646}
1647
1648#[ast_node("OptionalChainingExpression")]
1649#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1650#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1651#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1652pub struct OptChainExpr {
1653    pub span: Span,
1654    pub optional: bool,
1655    /// This is boxed to reduce the type size of [Expr].
1656    pub base: Box<OptChainBase>,
1657}
1658
1659#[ast_node]
1660#[derive(Eq, Hash, Is, EqIgnoreSpan)]
1661#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1662#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1663pub enum OptChainBase {
1664    #[tag("MemberExpression")]
1665    Member(MemberExpr),
1666    #[tag("CallExpression")]
1667    Call(OptCall),
1668}
1669
1670impl Default for OptChainBase {
1671    fn default() -> Self {
1672        OptChainBase::Member(Default::default())
1673    }
1674}
1675
1676#[ast_node("CallExpression")]
1677#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1678#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1679#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1680pub struct OptCall {
1681    pub span: Span,
1682
1683    pub ctxt: SyntaxContext,
1684
1685    pub callee: Box<Expr>,
1686
1687    #[cfg_attr(feature = "serde-impl", serde(default, rename = "arguments"))]
1688    pub args: Vec<ExprOrSpread>,
1689
1690    #[cfg_attr(feature = "serde-impl", serde(default, rename = "typeArguments"))]
1691    pub type_args: Option<Box<TsTypeParamInstantiation>>,
1692    // pub type_params: Option<TsTypeParamInstantiation>,
1693}
1694
1695impl Take for OptChainExpr {
1696    fn dummy() -> Self {
1697        Self {
1698            span: DUMMY_SP,
1699            optional: false,
1700            base: Box::new(OptChainBase::Member(Take::dummy())),
1701        }
1702    }
1703}
1704
1705impl From<OptChainBase> for Expr {
1706    fn from(opt: OptChainBase) -> Self {
1707        match opt {
1708            OptChainBase::Call(OptCall {
1709                span,
1710                ctxt,
1711                callee,
1712                args,
1713                type_args,
1714            }) => Self::Call(CallExpr {
1715                callee: Callee::Expr(callee),
1716                args,
1717                span,
1718                type_args,
1719                ctxt,
1720            }),
1721            OptChainBase::Member(member) => Self::Member(member),
1722        }
1723    }
1724}
1725
1726impl Take for OptCall {
1727    fn dummy() -> Self {
1728        Self {
1729            ..Default::default()
1730        }
1731    }
1732}
1733
1734impl From<OptCall> for CallExpr {
1735    fn from(
1736        OptCall {
1737            span,
1738            ctxt,
1739            callee,
1740            args,
1741            type_args,
1742        }: OptCall,
1743    ) -> Self {
1744        Self {
1745            span,
1746            callee: Callee::Expr(callee),
1747            args,
1748            type_args,
1749            ctxt,
1750        }
1751    }
1752}
1753
1754bridge_expr_from!(CallExpr, OptCall);
1755
1756test_de!(
1757    jsx_element,
1758    JSXElement,
1759    r#"{
1760      "type": "JSXElement",
1761      "span": {
1762        "start": 0,
1763        "end": 5,
1764        "ctxt": 0
1765      },
1766      "opening": {
1767        "type": "JSXOpeningElement",
1768        "name": {
1769          "type": "Identifier",
1770          "span": {
1771            "start": 1,
1772            "end": 2,
1773            "ctxt": 0
1774          },
1775          "value": "a",
1776          "optional": false
1777        },
1778        "span": {
1779          "start": 1,
1780          "end": 5,
1781          "ctxt": 0
1782        },
1783        "selfClosing": true
1784      },
1785      "children": [],
1786      "closing": null
1787    }"#
1788);