1#![allow(clippy::vec_box)]
2use std::mem::transmute;
3
4use is_macro::Is;
5use string_enum::StringEnum;
6use swc_atoms::{Atom, Wtf8Atom};
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    #[tag("UpdateExpression")]
52    Update(UpdateExpr),
53
54    #[tag("BinaryExpression")]
55    Bin(BinExpr),
56
57    #[tag("AssignmentExpression")]
58    Assign(AssignExpr),
59
60    #[tag("MemberExpression")]
72    Member(MemberExpr),
73
74    #[tag("SuperPropExpression")]
75    SuperProp(SuperPropExpr),
76
77    #[tag("ConditionalExpression")]
79    Cond(CondExpr),
80
81    #[tag("CallExpression")]
82    Call(CallExpr),
83
84    #[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
174impl Expr {
179    #[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    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    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                op(transmute::<&mut _, &mut _>(cur))
251            } {
252                Some(next) => cur = next,
253                None => {
254                    return cur;
255                }
256            }
257        }
258    }
259
260    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    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    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    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    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            #[cfg(all(swc_ast_unknown, feature = "encoding-impl"))]
380            _ => swc_common::unknown!(),
381        }
382    }
383}
384
385impl Clone for Expr {
388    fn clone(&self) -> Self {
389        use Expr::*;
390        match self {
391            #[cfg(all(swc_ast_unknown, feature = "encoding-impl"))]
392            Unknown(tag, v) => Unknown(*tag, v.clone()),
393            This(e) => This(e.clone()),
394            Array(e) => Array(e.clone()),
395            Object(e) => Object(e.clone()),
396            Fn(e) => Fn(e.clone()),
397            Unary(e) => Unary(e.clone()),
398            Update(e) => Update(e.clone()),
399            Bin(e) => Bin(e.clone()),
400            Assign(e) => Assign(e.clone()),
401            Member(e) => Member(e.clone()),
402            SuperProp(e) => SuperProp(e.clone()),
403            Cond(e) => Cond(e.clone()),
404            Call(e) => Call(e.clone()),
405            New(e) => New(e.clone()),
406            Seq(e) => Seq(e.clone()),
407            Ident(e) => Ident(e.clone()),
408            Lit(e) => Lit(e.clone()),
409            Tpl(e) => Tpl(e.clone()),
410            TaggedTpl(e) => TaggedTpl(e.clone()),
411            Arrow(e) => Arrow(e.clone()),
412            Class(e) => Class(e.clone()),
413            Yield(e) => Yield(e.clone()),
414            MetaProp(e) => MetaProp(e.clone()),
415            Await(e) => Await(e.clone()),
416            Paren(e) => Paren(e.clone()),
417            JSXMember(e) => JSXMember(e.clone()),
418            JSXNamespacedName(e) => JSXNamespacedName(e.clone()),
419            JSXEmpty(e) => JSXEmpty(e.clone()),
420            JSXElement(e) => JSXElement(e.clone()),
421            JSXFragment(e) => JSXFragment(e.clone()),
422            TsTypeAssertion(e) => TsTypeAssertion(e.clone()),
423            TsConstAssertion(e) => TsConstAssertion(e.clone()),
424            TsNonNull(e) => TsNonNull(e.clone()),
425            TsAs(e) => TsAs(e.clone()),
426            TsInstantiation(e) => TsInstantiation(e.clone()),
427            PrivateName(e) => PrivateName(e.clone()),
428            OptChain(e) => OptChain(e.clone()),
429            Invalid(e) => Invalid(e.clone()),
430            TsSatisfies(e) => TsSatisfies(e.clone()),
431        }
432    }
433}
434
435impl Take for Expr {
436    fn dummy() -> Self {
437        Invalid { span: DUMMY_SP }.into()
438    }
439}
440
441impl Default for Expr {
442    fn default() -> Self {
443        Expr::Invalid(Default::default())
444    }
445}
446
447bridge_expr_from!(Ident, IdentName);
448bridge_expr_from!(Ident, Id);
449bridge_expr_from!(FnExpr, Function);
450bridge_expr_from!(ClassExpr, Class);
451
452macro_rules! boxed_expr {
453    ($T:ty) => {
454        bridge_from!(Box<Expr>, Expr, $T);
455    };
456}
457
458boxed_expr!(ThisExpr);
459boxed_expr!(ArrayLit);
460boxed_expr!(ObjectLit);
461boxed_expr!(FnExpr);
462boxed_expr!(UnaryExpr);
463boxed_expr!(UpdateExpr);
464boxed_expr!(BinExpr);
465boxed_expr!(AssignExpr);
466boxed_expr!(MemberExpr);
467boxed_expr!(SuperPropExpr);
468boxed_expr!(CondExpr);
469boxed_expr!(CallExpr);
470boxed_expr!(NewExpr);
471boxed_expr!(SeqExpr);
472bridge_from!(Box<Expr>, Expr, Ident);
473boxed_expr!(Lit);
474boxed_expr!(Tpl);
475boxed_expr!(TaggedTpl);
476boxed_expr!(ArrowExpr);
477boxed_expr!(ClassExpr);
478boxed_expr!(YieldExpr);
479boxed_expr!(MetaPropExpr);
480boxed_expr!(AwaitExpr);
481boxed_expr!(ParenExpr);
482boxed_expr!(JSXMemberExpr);
483boxed_expr!(JSXNamespacedName);
484boxed_expr!(JSXEmptyExpr);
485boxed_expr!(Box<JSXElement>);
486boxed_expr!(JSXFragment);
487boxed_expr!(TsTypeAssertion);
488boxed_expr!(TsSatisfiesExpr);
489boxed_expr!(TsConstAssertion);
490boxed_expr!(TsNonNullExpr);
491boxed_expr!(TsAsExpr);
492boxed_expr!(TsInstantiation);
493boxed_expr!(PrivateName);
494boxed_expr!(OptChainExpr);
495boxed_expr!(Invalid);
496
497#[ast_node("ThisExpression")]
498#[derive(Eq, Hash, Copy, EqIgnoreSpan)]
499#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
500#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
501pub struct ThisExpr {
502    pub span: Span,
503}
504
505impl Take for ThisExpr {
506    fn dummy() -> Self {
507        ThisExpr { span: DUMMY_SP }
508    }
509}
510
511#[ast_node("ArrayExpression")]
513#[derive(Eq, Hash, EqIgnoreSpan, Default)]
514#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
515#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
516pub struct ArrayLit {
517    pub span: Span,
518
519    #[cfg_attr(feature = "serde-impl", serde(default, rename = "elements"))]
520    #[cfg_attr(
521        feature = "encoding-impl",
522        encoding(with = "swc_common::serializer::ArrayOption")
523    )]
524    pub elems: Vec<Option<ExprOrSpread>>,
525}
526
527impl Take for ArrayLit {
528    fn dummy() -> Self {
529        ArrayLit {
530            span: DUMMY_SP,
531            elems: Default::default(),
532        }
533    }
534}
535
536#[ast_node("ObjectExpression")]
538#[derive(Eq, Hash, EqIgnoreSpan, Default)]
539#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
540#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
541pub struct ObjectLit {
542    pub span: Span,
543
544    #[cfg_attr(feature = "serde-impl", serde(default, rename = "properties"))]
545    pub props: Vec<PropOrSpread>,
546}
547
548impl ObjectLit {
549    pub fn as_import_with(&self) -> Option<ImportWith> {
553        let mut values = Vec::new();
554        for prop in &self.props {
555            match prop {
556                PropOrSpread::Spread(..) => return None,
557                PropOrSpread::Prop(prop) => match &**prop {
558                    Prop::KeyValue(kv) => {
559                        let key = match &kv.key {
560                            PropName::Ident(i) => i.clone(),
561                            PropName::Str(s) => {
562                                let name = s.value.as_str()?;
563                                IdentName::new(name.to_string().into(), s.span)
564                            }
565                            _ => return None,
566                        };
567
568                        values.push(ImportWithItem {
569                            key,
570                            value: match &*kv.value {
571                                Expr::Lit(Lit::Str(s)) => s.clone(),
572                                _ => return None,
573                            },
574                        });
575                    }
576                    _ => return None,
577                },
578                #[cfg(all(swc_ast_unknown, feature = "encoding-impl"))]
579                _ => swc_common::unknown!(),
580            }
581        }
582
583        Some(ImportWith {
584            span: self.span,
585            values,
586        })
587    }
588}
589
590impl From<ImportWith> for ObjectLit {
591    fn from(v: ImportWith) -> Self {
592        ObjectLit {
593            span: v.span,
594            props: v
595                .values
596                .into_iter()
597                .map(|item| {
598                    PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
599                        key: PropName::Ident(item.key),
600                        value: Lit::Str(item.value).into(),
601                    })))
602                })
603                .collect(),
604        }
605    }
606}
607
608#[derive(Debug, Clone, PartialEq, Eq, Hash, EqIgnoreSpan)]
613pub struct ImportWith {
614    pub span: Span,
615    pub values: Vec<ImportWithItem>,
616}
617
618impl ImportWith {
619    pub fn get(&self, key: &str) -> Option<&Str> {
620        self.values.iter().find_map(|item| {
621            if item.key.sym == key {
622                Some(&item.value)
623            } else {
624                None
625            }
626        })
627    }
628}
629
630#[derive(Debug, Clone, PartialEq, Eq, Hash, EqIgnoreSpan)]
631pub struct ImportWithItem {
632    pub key: IdentName,
633    pub value: Str,
634}
635
636impl Take for ObjectLit {
637    fn dummy() -> Self {
638        ObjectLit {
639            span: DUMMY_SP,
640            props: Default::default(),
641        }
642    }
643}
644
645#[ast_node]
646#[derive(Eq, Hash, Is, EqIgnoreSpan)]
647#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
648#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
649pub enum PropOrSpread {
650    #[tag("SpreadElement")]
652    Spread(SpreadElement),
653
654    #[tag("*")]
655    Prop(Box<Prop>),
656}
657
658bridge_from!(PropOrSpread, Box<Prop>, Prop);
659
660impl Take for PropOrSpread {
661    fn dummy() -> Self {
662        PropOrSpread::Spread(SpreadElement {
663            dot3_token: DUMMY_SP,
664            expr: Take::dummy(),
665        })
666    }
667}
668
669#[ast_node("SpreadElement")]
670#[derive(Eq, Hash, EqIgnoreSpan, Default)]
671#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
672#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
673pub struct SpreadElement {
674    #[cfg_attr(feature = "serde-impl", serde(rename = "spread"))]
675    #[span(lo)]
676    pub dot3_token: Span,
677
678    #[cfg_attr(feature = "serde-impl", serde(rename = "arguments"))]
679    #[span(hi)]
680    pub expr: Box<Expr>,
681}
682
683impl Take for SpreadElement {
684    fn dummy() -> Self {
685        SpreadElement {
686            dot3_token: DUMMY_SP,
687            expr: Take::dummy(),
688        }
689    }
690}
691
692#[ast_node("UnaryExpression")]
693#[derive(Eq, Hash, EqIgnoreSpan, Default)]
694#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
695#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
696pub struct UnaryExpr {
697    pub span: Span,
698
699    #[cfg_attr(feature = "serde-impl", serde(rename = "operator"))]
700    pub op: UnaryOp,
701
702    #[cfg_attr(feature = "serde-impl", serde(rename = "argument"))]
703    pub arg: Box<Expr>,
704}
705
706impl Take for UnaryExpr {
707    fn dummy() -> Self {
708        UnaryExpr {
709            span: DUMMY_SP,
710            op: op!("!"),
711            arg: Take::dummy(),
712        }
713    }
714}
715
716#[ast_node("UpdateExpression")]
717#[derive(Eq, Hash, EqIgnoreSpan, Default)]
718#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
719#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
720pub struct UpdateExpr {
721    pub span: Span,
722
723    #[cfg_attr(feature = "serde-impl", serde(rename = "operator"))]
724    pub op: UpdateOp,
725
726    pub prefix: bool,
727
728    #[cfg_attr(feature = "serde-impl", serde(rename = "argument"))]
729    pub arg: Box<Expr>,
730}
731
732impl Take for UpdateExpr {
733    fn dummy() -> Self {
734        UpdateExpr {
735            span: DUMMY_SP,
736            op: op!("++"),
737            prefix: false,
738            arg: Take::dummy(),
739        }
740    }
741}
742
743#[ast_node("BinaryExpression")]
744#[derive(Eq, Hash, EqIgnoreSpan, Default)]
745#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
746#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
747pub struct BinExpr {
748    pub span: Span,
749
750    #[cfg_attr(feature = "serde-impl", serde(rename = "operator"))]
751    pub op: BinaryOp,
752
753    pub left: Box<Expr>,
754
755    pub right: Box<Expr>,
756}
757
758impl Take for BinExpr {
759    fn dummy() -> Self {
760        BinExpr {
761            span: DUMMY_SP,
762            op: op!("*"),
763            left: Take::dummy(),
764            right: Take::dummy(),
765        }
766    }
767}
768
769#[ast_node("FunctionExpression")]
771#[derive(Eq, Hash, EqIgnoreSpan, Default)]
772#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
773#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
774pub struct FnExpr {
775    #[cfg_attr(feature = "serde-impl", serde(default, rename = "identifier"))]
776    #[cfg_attr(
777        feature = "encoding-impl",
778        encoding(with = "cbor4ii::core::types::Maybe")
779    )]
780    pub ident: Option<Ident>,
781
782    #[cfg_attr(feature = "serde-impl", serde(flatten))]
783    #[span]
784    pub function: Box<Function>,
785}
786
787impl Take for FnExpr {
788    fn dummy() -> Self {
789        FnExpr {
790            ident: None,
791            function: Take::dummy(),
792        }
793    }
794}
795
796impl From<Box<Function>> for FnExpr {
797    fn from(function: Box<Function>) -> Self {
798        Self {
799            ident: None,
800            function,
801        }
802    }
803}
804
805bridge_from!(FnExpr, Box<Function>, Function);
806bridge_expr_from!(FnExpr, Box<Function>);
807
808#[ast_node("ClassExpression")]
810#[derive(Eq, Hash, EqIgnoreSpan, Default)]
811#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
812#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
813pub struct ClassExpr {
814    #[cfg_attr(feature = "serde-impl", serde(default, rename = "identifier"))]
815    #[cfg_attr(
816        feature = "encoding-impl",
817        encoding(with = "cbor4ii::core::types::Maybe")
818    )]
819    pub ident: Option<Ident>,
820
821    #[cfg_attr(feature = "serde-impl", serde(flatten))]
822    #[span]
823    pub class: Box<Class>,
824}
825
826impl Take for ClassExpr {
827    fn dummy() -> Self {
828        ClassExpr {
829            ident: None,
830            class: Take::dummy(),
831        }
832    }
833}
834
835impl From<Box<Class>> for ClassExpr {
836    fn from(class: Box<Class>) -> Self {
837        Self { ident: None, class }
838    }
839}
840
841bridge_from!(ClassExpr, Box<Class>, Class);
842bridge_expr_from!(ClassExpr, Box<Class>);
843
844#[ast_node("AssignmentExpression")]
845#[derive(Eq, Hash, EqIgnoreSpan, Default)]
846#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
847#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
848pub struct AssignExpr {
849    pub span: Span,
850
851    #[cfg_attr(feature = "serde-impl", serde(rename = "operator"))]
852    pub op: AssignOp,
853
854    pub left: AssignTarget,
855
856    pub right: Box<Expr>,
857}
858
859impl Take for AssignExpr {
860    fn dummy() -> Self {
861        AssignExpr {
862            span: DUMMY_SP,
863            op: op!("="),
864            left: Take::dummy(),
865            right: Take::dummy(),
866        }
867    }
868}
869
870impl AssignExpr {
871    pub fn is_simple_assign(&self) -> bool {
872        self.op == op!("=") && self.left.as_ident().is_some()
873    }
874}
875
876#[ast_node("MemberExpression")]
877#[derive(Eq, Hash, EqIgnoreSpan, Default)]
878#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
879#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
880pub struct MemberExpr {
881    pub span: Span,
882
883    #[cfg_attr(feature = "serde-impl", serde(rename = "object"))]
884    pub obj: Box<Expr>,
885
886    #[cfg_attr(feature = "serde-impl", serde(rename = "property"))]
887    pub prop: MemberProp,
888}
889
890#[ast_node]
891#[derive(Eq, Hash, Is, EqIgnoreSpan)]
892#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
893#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
894pub enum MemberProp {
895    #[tag("Identifier")]
896    Ident(IdentName),
897    #[tag("PrivateName")]
898    PrivateName(PrivateName),
899    #[tag("Computed")]
900    Computed(ComputedPropName),
901}
902
903impl MemberProp {
904    pub fn is_ident_with(&self, sym: &str) -> bool {
905        matches!(self, MemberProp::Ident(i) if i.sym == sym)
906    }
907}
908
909#[ast_node("SuperPropExpression")]
910#[derive(Eq, Hash, EqIgnoreSpan, Default)]
911#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
912#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
913pub struct SuperPropExpr {
914    pub span: Span,
915
916    pub obj: Super,
917
918    #[cfg_attr(feature = "serde-impl", serde(rename = "property"))]
919    pub prop: SuperProp,
920}
921
922#[ast_node]
923#[derive(Eq, Hash, Is, EqIgnoreSpan)]
924#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
925#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
926pub enum SuperProp {
927    #[tag("Identifier")]
928    Ident(IdentName),
929    #[tag("Computed")]
930    Computed(ComputedPropName),
931}
932
933impl Take for MemberExpr {
934    fn dummy() -> Self {
935        MemberExpr {
936            span: DUMMY_SP,
937            obj: Take::dummy(),
938            prop: Take::dummy(),
939        }
940    }
941}
942
943impl Take for MemberProp {
944    fn dummy() -> Self {
945        Default::default()
946    }
947}
948
949impl Default for MemberProp {
950    fn default() -> Self {
951        MemberProp::Ident(Default::default())
952    }
953}
954
955impl Take for SuperProp {
956    fn dummy() -> Self {
957        SuperProp::Ident(Default::default())
958    }
959}
960
961impl Default for SuperProp {
962    fn default() -> Self {
963        SuperProp::Ident(Default::default())
964    }
965}
966
967#[ast_node("ConditionalExpression")]
968#[derive(Eq, Hash, EqIgnoreSpan, Default)]
969#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
970#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
971pub struct CondExpr {
972    pub span: Span,
973
974    pub test: Box<Expr>,
975
976    #[cfg_attr(feature = "serde-impl", serde(rename = "consequent"))]
977    pub cons: Box<Expr>,
978
979    #[cfg_attr(feature = "serde-impl", serde(rename = "alternate"))]
980    pub alt: Box<Expr>,
981}
982
983impl Take for CondExpr {
984    fn dummy() -> Self {
985        CondExpr {
986            span: DUMMY_SP,
987            test: Take::dummy(),
988            cons: Take::dummy(),
989            alt: Take::dummy(),
990        }
991    }
992}
993
994#[ast_node("CallExpression")]
995#[derive(Eq, Hash, EqIgnoreSpan, Default)]
996#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
997#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
998pub struct CallExpr {
999    pub span: Span,
1000    pub ctxt: SyntaxContext,
1001
1002    pub callee: Callee,
1003
1004    #[cfg_attr(feature = "serde-impl", serde(default, rename = "arguments"))]
1005    pub args: Vec<ExprOrSpread>,
1006
1007    #[cfg_attr(feature = "serde-impl", serde(default, rename = "typeArguments"))]
1008    #[cfg_attr(
1009        feature = "encoding-impl",
1010        encoding(with = "cbor4ii::core::types::Maybe")
1011    )]
1012    pub type_args: Option<Box<TsTypeParamInstantiation>>,
1013    }
1015
1016impl Take for CallExpr {
1017    fn dummy() -> Self {
1018        Default::default()
1019    }
1020}
1021
1022#[ast_node("NewExpression")]
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 NewExpr {
1027    pub span: Span,
1028
1029    pub ctxt: SyntaxContext,
1030
1031    pub callee: Box<Expr>,
1032
1033    #[cfg_attr(feature = "serde-impl", serde(default, rename = "arguments"))]
1034    #[cfg_attr(
1035        feature = "encoding-impl",
1036        encoding(with = "::cbor4ii::core::types::Maybe")
1037    )]
1038    pub args: Option<Vec<ExprOrSpread>>,
1039
1040    #[cfg_attr(feature = "serde-impl", serde(default, rename = "typeArguments"))]
1041    #[cfg_attr(
1042        feature = "encoding-impl",
1043        encoding(with = "::cbor4ii::core::types::Maybe")
1044    )]
1045    pub type_args: Option<Box<TsTypeParamInstantiation>>,
1046    }
1048
1049impl Take for NewExpr {
1050    fn dummy() -> Self {
1051        Default::default()
1052    }
1053}
1054
1055#[ast_node("SequenceExpression")]
1056#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1057#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1058#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1059pub struct SeqExpr {
1060    pub span: Span,
1061
1062    #[cfg_attr(feature = "serde-impl", serde(rename = "expressions"))]
1063    pub exprs: Vec<Box<Expr>>,
1064}
1065
1066impl Take for SeqExpr {
1067    fn dummy() -> Self {
1068        SeqExpr {
1069            span: DUMMY_SP,
1070            exprs: Take::dummy(),
1071        }
1072    }
1073}
1074
1075#[ast_node("ArrowFunctionExpression")]
1076#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1077#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1078#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1079pub struct ArrowExpr {
1080    pub span: Span,
1081
1082    pub ctxt: SyntaxContext,
1083
1084    pub params: Vec<Pat>,
1085
1086    pub body: Box<BlockStmtOrExpr>,
1088
1089    #[cfg_attr(feature = "serde-impl", serde(default, rename = "async"))]
1090    pub is_async: bool,
1091
1092    #[cfg_attr(feature = "serde-impl", serde(default, rename = "generator"))]
1093    pub is_generator: bool,
1094
1095    #[cfg_attr(feature = "serde-impl", serde(default, rename = "typeParameters"))]
1096    #[cfg_attr(
1097        feature = "encoding-impl",
1098        encoding(with = "cbor4ii::core::types::Maybe")
1099    )]
1100    pub type_params: Option<Box<TsTypeParamDecl>>,
1101
1102    #[cfg_attr(feature = "serde-impl", serde(default))]
1103    #[cfg_attr(
1104        feature = "encoding-impl",
1105        encoding(with = "cbor4ii::core::types::Maybe")
1106    )]
1107    pub return_type: Option<Box<TsTypeAnn>>,
1108}
1109
1110impl Take for ArrowExpr {
1111    fn dummy() -> Self {
1112        ArrowExpr {
1113            ..Default::default()
1114        }
1115    }
1116}
1117
1118#[ast_node("YieldExpression")]
1119#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1120#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1121#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1122pub struct YieldExpr {
1123    pub span: Span,
1124
1125    #[cfg_attr(feature = "serde-impl", serde(default, rename = "argument"))]
1126    #[cfg_attr(
1127        feature = "encoding-impl",
1128        encoding(with = "cbor4ii::core::types::Maybe")
1129    )]
1130    pub arg: Option<Box<Expr>>,
1131
1132    #[cfg_attr(feature = "serde-impl", serde(default))]
1133    pub delegate: bool,
1134}
1135
1136impl Take for YieldExpr {
1137    fn dummy() -> Self {
1138        YieldExpr {
1139            span: DUMMY_SP,
1140            arg: Take::dummy(),
1141            delegate: false,
1142        }
1143    }
1144}
1145
1146#[ast_node("MetaProperty")]
1147#[derive(Eq, Hash, EqIgnoreSpan, Copy)]
1148#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1149#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1150pub struct MetaPropExpr {
1151    pub span: Span,
1152    pub kind: MetaPropKind,
1153}
1154
1155#[derive(StringEnum, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash, EqIgnoreSpan)]
1156#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1157#[cfg_attr(
1158    any(feature = "rkyv-impl"),
1159    derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
1160)]
1161#[cfg_attr(feature = "rkyv-impl", derive(bytecheck::CheckBytes))]
1162#[cfg_attr(feature = "rkyv-impl", repr(u32))]
1163#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1164#[cfg_attr(
1165    feature = "encoding-impl",
1166    derive(::swc_common::Encode, ::swc_common::Decode)
1167)]
1168#[cfg_attr(swc_ast_unknown, non_exhaustive)]
1169pub enum MetaPropKind {
1170    NewTarget,
1172    ImportMeta,
1174}
1175
1176#[ast_node("AwaitExpression")]
1177#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1178#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1179#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1180pub struct AwaitExpr {
1181    pub span: Span,
1182
1183    #[cfg_attr(feature = "serde-impl", serde(rename = "argument"))]
1184    pub arg: Box<Expr>,
1185}
1186
1187#[ast_node("TemplateLiteral")]
1188#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1189#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1190#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1191pub struct Tpl {
1192    pub span: Span,
1193
1194    #[cfg_attr(feature = "serde-impl", serde(rename = "expressions"))]
1195    pub exprs: Vec<Box<Expr>>,
1196
1197    pub quasis: Vec<TplElement>,
1198}
1199
1200impl Take for Tpl {
1201    fn dummy() -> Self {
1202        Tpl {
1203            span: DUMMY_SP,
1204            exprs: Take::dummy(),
1205            quasis: Take::dummy(),
1206        }
1207    }
1208}
1209
1210#[ast_node("TaggedTemplateExpression")]
1211#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1212#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1213#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1214pub struct TaggedTpl {
1215    pub span: Span,
1216
1217    pub ctxt: SyntaxContext,
1218
1219    pub tag: Box<Expr>,
1220
1221    #[cfg_attr(feature = "serde-impl", serde(default, rename = "typeParameters"))]
1222    #[cfg_attr(
1223        feature = "encoding-impl",
1224        encoding(with = "cbor4ii::core::types::Maybe")
1225    )]
1226    pub type_params: Option<Box<TsTypeParamInstantiation>>,
1227
1228    #[cfg_attr(feature = "serde-impl", serde(rename = "template"))]
1230    pub tpl: Box<Tpl>,
1231}
1232
1233impl Take for TaggedTpl {
1234    fn dummy() -> Self {
1235        Default::default()
1236    }
1237}
1238
1239#[ast_node("TemplateElement")]
1240#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1241#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1242pub struct TplElement {
1243    pub span: Span,
1244    pub tail: bool,
1245
1246    #[cfg_attr(
1252        feature = "encoding-impl",
1253        encoding(with = "cbor4ii::core::types::Maybe")
1254    )]
1255    pub cooked: Option<Wtf8Atom>,
1256
1257    pub raw: Atom,
1260}
1261
1262impl Take for TplElement {
1263    fn dummy() -> Self {
1264        TplElement {
1265            span: DUMMY_SP,
1266            tail: Default::default(),
1267            cooked: None,
1268            raw: Default::default(),
1269        }
1270    }
1271}
1272
1273#[cfg(feature = "arbitrary")]
1274#[cfg_attr(docsrs, doc(cfg(feature = "arbitrary")))]
1275impl<'a> arbitrary::Arbitrary<'a> for TplElement {
1276    fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
1277        let span = u.arbitrary()?;
1278        let cooked = Some(u.arbitrary::<Wtf8Atom>()?.into());
1279        let raw = u.arbitrary::<String>()?.into();
1280
1281        Ok(Self {
1282            span,
1283            tail: false,
1284            cooked,
1285            raw,
1286        })
1287    }
1288}
1289
1290#[ast_node("ParenthesisExpression")]
1291#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1292#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1293#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1294pub struct ParenExpr {
1295    pub span: Span,
1296
1297    #[cfg_attr(feature = "serde-impl", serde(rename = "expression"))]
1298    pub expr: Box<Expr>,
1299}
1300impl Take for ParenExpr {
1301    fn dummy() -> Self {
1302        ParenExpr {
1303            span: DUMMY_SP,
1304            expr: Take::dummy(),
1305        }
1306    }
1307}
1308
1309#[ast_node]
1310#[derive(Eq, Hash, Is, EqIgnoreSpan)]
1311#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1312#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1313pub enum Callee {
1314    #[tag("Super")]
1315    #[is(name = "super_")]
1316    Super(Super),
1317
1318    #[tag("Import")]
1319    Import(Import),
1320
1321    #[tag("*")]
1322    Expr(Box<Expr>),
1323}
1324
1325impl Default for Callee {
1326    fn default() -> Self {
1327        Callee::Super(Default::default())
1328    }
1329}
1330
1331impl Take for Callee {
1332    fn dummy() -> Self {
1333        Callee::Super(Take::dummy())
1334    }
1335}
1336
1337#[ast_node("Super")]
1338#[derive(Eq, Hash, Copy, EqIgnoreSpan, Default)]
1339#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1340#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1341pub struct Super {
1342    pub span: Span,
1343}
1344
1345impl Take for Super {
1346    fn dummy() -> Self {
1347        Super { span: DUMMY_SP }
1348    }
1349}
1350
1351#[ast_node("Import")]
1352#[derive(Eq, Hash, Copy, EqIgnoreSpan)]
1353#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1354#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1355pub struct Import {
1356    pub span: Span,
1357    pub phase: ImportPhase,
1358}
1359
1360impl Take for Import {
1361    fn dummy() -> Self {
1362        Import {
1363            span: DUMMY_SP,
1364            phase: ImportPhase::default(),
1365        }
1366    }
1367}
1368
1369#[derive(Clone, Debug, PartialEq, Eq, Hash, EqIgnoreSpan)]
1370#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1371#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1372#[cfg_attr(
1373    any(feature = "rkyv-impl"),
1374    derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
1375)]
1376#[cfg_attr(
1377    feature = "rkyv",
1378    rkyv(serialize_bounds(__S: rkyv::ser::Writer + rkyv::ser::Allocator,
1379        __S::Error: rkyv::rancor::Source))
1380)]
1381#[cfg_attr(
1382    feature = "rkyv-impl",
1383    rkyv(deserialize_bounds(__D::Error: rkyv::rancor::Source))
1384)]
1385#[cfg_attr(
1386                    feature = "rkyv-impl",
1387                    rkyv(bytecheck(bounds(
1388                        __C: rkyv::validation::ArchiveContext,
1389                        __C::Error: rkyv::rancor::Source
1390                    )))
1391                )]
1392#[cfg_attr(feature = "rkyv-impl", repr(C))]
1393#[cfg_attr(feature = "serde-impl", derive(serde::Serialize, serde::Deserialize))]
1394#[cfg_attr(
1395    feature = "encoding-impl",
1396    derive(::swc_common::Encode, ::swc_common::Decode)
1397)]
1398pub struct ExprOrSpread {
1399    #[cfg_attr(feature = "serde-impl", serde(default))]
1400    #[cfg_attr(feature = "__rkyv", rkyv(omit_bounds))]
1401    #[cfg_attr(
1402        feature = "encoding-impl",
1403        encoding(with = "cbor4ii::core::types::Maybe")
1404    )]
1405    pub spread: Option<Span>,
1406
1407    #[cfg_attr(feature = "serde-impl", serde(rename = "expression"))]
1408    #[cfg_attr(feature = "__rkyv", rkyv(omit_bounds))]
1409    pub expr: Box<Expr>,
1410}
1411
1412impl Spanned for ExprOrSpread {
1413    #[inline]
1414    fn span(&self) -> Span {
1415        let expr = self.expr.span();
1416        match self.spread {
1417            Some(spread) => expr.with_lo(spread.lo()),
1418            None => expr,
1419        }
1420    }
1421
1422    #[inline]
1423    fn span_lo(&self) -> BytePos {
1424        match self.spread {
1425            Some(s) => s.lo,
1426            None => self.expr.span_lo(),
1427        }
1428    }
1429
1430    #[inline]
1431    fn span_hi(&self) -> BytePos {
1432        self.expr.span_hi()
1433    }
1434}
1435
1436impl From<Box<Expr>> for ExprOrSpread {
1437    fn from(expr: Box<Expr>) -> Self {
1438        Self { expr, spread: None }
1439    }
1440}
1441
1442bridge_from!(ExprOrSpread, Box<Expr>, Expr);
1443
1444#[ast_node]
1445#[derive(Eq, Hash, Is, EqIgnoreSpan)]
1446#[allow(variant_size_differences)]
1447#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1448#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1449pub enum BlockStmtOrExpr {
1450    #[tag("BlockStatement")]
1451    BlockStmt(BlockStmt),
1452    #[tag("*")]
1453    Expr(Box<Expr>),
1454}
1455
1456impl Default for BlockStmtOrExpr {
1457    fn default() -> Self {
1458        BlockStmtOrExpr::BlockStmt(Default::default())
1459    }
1460}
1461
1462impl<T> From<T> for BlockStmtOrExpr
1463where
1464    T: Into<Expr>,
1465{
1466    fn from(e: T) -> Self {
1467        Self::Expr(Box::new(e.into()))
1468    }
1469}
1470
1471impl Take for BlockStmtOrExpr {
1472    fn dummy() -> Self {
1473        BlockStmtOrExpr::Expr(Take::dummy())
1474    }
1475}
1476
1477#[ast_node]
1478#[derive(Is, Eq, Hash, EqIgnoreSpan)]
1479#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1480#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1481pub enum AssignTarget {
1482    #[tag("Identifier")]
1483    #[tag("MemberExpression")]
1484    #[tag("SuperPropExpression")]
1485    #[tag("OptionalChainingExpression")]
1486    #[tag("ParenthesisExpression")]
1487    #[tag("TsAsExpression")]
1488    #[tag("TsSatisfiesExpression")]
1489    #[tag("TsNonNullExpression")]
1490    #[tag("TsTypeAssertion")]
1491    #[tag("TsInstantiation")]
1492    Simple(SimpleAssignTarget),
1493    #[tag("ArrayPattern")]
1494    #[tag("ObjectPattern")]
1495    Pat(AssignTargetPat),
1496}
1497
1498impl TryFrom<Pat> for AssignTarget {
1499    type Error = Pat;
1500
1501    fn try_from(p: Pat) -> Result<Self, Self::Error> {
1502        Ok(match p {
1503            Pat::Array(a) => AssignTargetPat::Array(a).into(),
1504            Pat::Object(o) => AssignTargetPat::Object(o).into(),
1505
1506            Pat::Ident(i) => SimpleAssignTarget::Ident(i).into(),
1507            Pat::Invalid(i) => SimpleAssignTarget::Invalid(i).into(),
1508
1509            Pat::Expr(e) => match Self::try_from(e) {
1510                Ok(v) => v,
1511                Err(e) => return Err(e.into()),
1512            },
1513
1514            _ => return Err(p),
1515        })
1516    }
1517}
1518impl TryFrom<Box<Pat>> for AssignTarget {
1519    type Error = Box<Pat>;
1520
1521    fn try_from(p: Box<Pat>) -> Result<Self, Self::Error> {
1522        (*p).try_into().map_err(Box::new)
1523    }
1524}
1525
1526impl TryFrom<Box<Expr>> for AssignTarget {
1527    type Error = Box<Expr>;
1528
1529    fn try_from(e: Box<Expr>) -> Result<Self, Self::Error> {
1530        Ok(Self::Simple(SimpleAssignTarget::try_from(e)?))
1531    }
1532}
1533
1534#[ast_node]
1535#[derive(Is, Eq, Hash, EqIgnoreSpan)]
1536#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1537#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1538pub enum AssignTargetPat {
1539    #[tag("ArrayPattern")]
1540    Array(ArrayPat),
1541    #[tag("ObjectPattern")]
1542    Object(ObjectPat),
1543    #[tag("Invalid")]
1544    Invalid(Invalid),
1545}
1546
1547impl Take for AssignTargetPat {
1548    fn dummy() -> Self {
1549        Default::default()
1550    }
1551}
1552
1553impl Default for AssignTargetPat {
1554    fn default() -> Self {
1555        AssignTargetPat::Invalid(Take::dummy())
1556    }
1557}
1558
1559impl From<AssignTargetPat> for Pat {
1560    fn from(pat: AssignTargetPat) -> Self {
1561        match pat {
1562            AssignTargetPat::Array(a) => a.into(),
1563            AssignTargetPat::Object(o) => o.into(),
1564            AssignTargetPat::Invalid(i) => i.into(),
1565            #[cfg(all(swc_ast_unknown, feature = "encoding-impl"))]
1566            _ => swc_common::unknown!(),
1567        }
1568    }
1569}
1570
1571impl From<AssignTargetPat> for Box<Pat> {
1572    fn from(pat: AssignTargetPat) -> Self {
1573        Box::new(pat.into())
1574    }
1575}
1576
1577impl TryFrom<Pat> for AssignTargetPat {
1578    type Error = Pat;
1579
1580    fn try_from(p: Pat) -> Result<Self, Self::Error> {
1581        Ok(match p {
1582            Pat::Array(a) => AssignTargetPat::Array(a),
1583            Pat::Object(o) => AssignTargetPat::Object(o),
1584            Pat::Invalid(i) => AssignTargetPat::Invalid(i),
1585
1586            _ => return Err(p),
1587        })
1588    }
1589}
1590
1591#[ast_node]
1592#[derive(Is, Eq, Hash, EqIgnoreSpan)]
1593#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1594#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1595pub enum SimpleAssignTarget {
1596    #[tag("Identifier")]
1599    Ident(BindingIdent),
1600    #[tag("MemberExpression")]
1601    Member(MemberExpr),
1602    #[tag("SuperPropExpression")]
1603    SuperProp(SuperPropExpr),
1604    #[tag("ParenthesisExpression")]
1605    Paren(ParenExpr),
1606    #[tag("OptionalChainingExpression")]
1607    OptChain(OptChainExpr),
1608    #[tag("TsAsExpression")]
1609    TsAs(TsAsExpr),
1610    #[tag("TsSatisfiesExpression")]
1611    TsSatisfies(TsSatisfiesExpr),
1612    #[tag("TsNonNullExpression")]
1613    TsNonNull(TsNonNullExpr),
1614    #[tag("TsTypeAssertion")]
1615    TsTypeAssertion(TsTypeAssertion),
1616    #[tag("TsInstantiation")]
1617    TsInstantiation(TsInstantiation),
1618
1619    #[tag("Invaliid")]
1620    Invalid(Invalid),
1621}
1622
1623impl TryFrom<Box<Expr>> for SimpleAssignTarget {
1624    type Error = Box<Expr>;
1625
1626    fn try_from(e: Box<Expr>) -> Result<Self, Self::Error> {
1627        Ok(match *e {
1628            Expr::Ident(i) => SimpleAssignTarget::Ident(i.into()),
1629            Expr::Member(m) => SimpleAssignTarget::Member(m),
1630            Expr::SuperProp(s) => SimpleAssignTarget::SuperProp(s),
1631            Expr::OptChain(s) => SimpleAssignTarget::OptChain(s),
1632            Expr::Paren(s) => SimpleAssignTarget::Paren(s),
1633            Expr::TsAs(a) => SimpleAssignTarget::TsAs(a),
1634            Expr::TsSatisfies(s) => SimpleAssignTarget::TsSatisfies(s),
1635            Expr::TsNonNull(n) => SimpleAssignTarget::TsNonNull(n),
1636            Expr::TsTypeAssertion(a) => SimpleAssignTarget::TsTypeAssertion(a),
1637            Expr::TsInstantiation(a) => SimpleAssignTarget::TsInstantiation(a),
1638            _ => return Err(e),
1639        })
1640    }
1641}
1642
1643bridge_from!(SimpleAssignTarget, BindingIdent, Ident);
1644
1645impl SimpleAssignTarget {
1646    pub fn leftmost(&self) -> Option<&Ident> {
1647        match self {
1648            SimpleAssignTarget::Ident(i) => Some(&i.id),
1649            SimpleAssignTarget::Member(MemberExpr { obj, .. }) => obj.leftmost(),
1650            _ => None,
1651        }
1652    }
1653}
1654
1655impl Take for SimpleAssignTarget {
1656    fn dummy() -> Self {
1657        SimpleAssignTarget::Invalid(Take::dummy())
1658    }
1659}
1660
1661bridge_from!(AssignTarget, BindingIdent, Ident);
1662bridge_from!(AssignTarget, SimpleAssignTarget, BindingIdent);
1663bridge_from!(AssignTarget, SimpleAssignTarget, MemberExpr);
1664bridge_from!(AssignTarget, SimpleAssignTarget, SuperPropExpr);
1665bridge_from!(AssignTarget, SimpleAssignTarget, ParenExpr);
1666bridge_from!(AssignTarget, SimpleAssignTarget, TsAsExpr);
1667bridge_from!(AssignTarget, SimpleAssignTarget, TsSatisfiesExpr);
1668bridge_from!(AssignTarget, SimpleAssignTarget, TsNonNullExpr);
1669bridge_from!(AssignTarget, SimpleAssignTarget, TsTypeAssertion);
1670
1671bridge_from!(AssignTarget, AssignTargetPat, ArrayPat);
1672bridge_from!(AssignTarget, AssignTargetPat, ObjectPat);
1673
1674impl From<SimpleAssignTarget> for Box<Expr> {
1675    fn from(s: SimpleAssignTarget) -> Self {
1676        match s {
1677            SimpleAssignTarget::Ident(i) => i.into(),
1678            SimpleAssignTarget::Member(m) => m.into(),
1679            SimpleAssignTarget::SuperProp(s) => s.into(),
1680            SimpleAssignTarget::Paren(s) => s.into(),
1681            SimpleAssignTarget::OptChain(s) => s.into(),
1682            SimpleAssignTarget::TsAs(a) => a.into(),
1683            SimpleAssignTarget::TsSatisfies(s) => s.into(),
1684            SimpleAssignTarget::TsNonNull(n) => n.into(),
1685            SimpleAssignTarget::TsTypeAssertion(a) => a.into(),
1686            SimpleAssignTarget::TsInstantiation(a) => a.into(),
1687            SimpleAssignTarget::Invalid(i) => i.into(),
1688            #[cfg(all(swc_ast_unknown, feature = "encoding-impl"))]
1689            _ => swc_common::unknown!(),
1690        }
1691    }
1692}
1693
1694impl AssignTarget {
1695    pub fn as_ident(&self) -> Option<&BindingIdent> {
1696        self.as_simple()?.as_ident()
1697    }
1698
1699    pub fn as_ident_mut(&mut self) -> Option<&mut BindingIdent> {
1700        self.as_mut_simple()?.as_mut_ident()
1701    }
1702}
1703
1704impl Default for AssignTarget {
1705    fn default() -> Self {
1706        SimpleAssignTarget::dummy().into()
1707    }
1708}
1709
1710impl Take for AssignTarget {
1711    fn dummy() -> Self {
1712        Default::default()
1713    }
1714}
1715
1716#[ast_node("OptionalChainingExpression")]
1717#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1718#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1719#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1720pub struct OptChainExpr {
1721    pub span: Span,
1722    pub optional: bool,
1723    pub base: Box<OptChainBase>,
1725}
1726
1727#[ast_node]
1728#[derive(Eq, Hash, Is, EqIgnoreSpan)]
1729#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1730#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1731pub enum OptChainBase {
1732    #[tag("MemberExpression")]
1733    Member(MemberExpr),
1734    #[tag("CallExpression")]
1735    Call(OptCall),
1736}
1737
1738impl Default for OptChainBase {
1739    fn default() -> Self {
1740        OptChainBase::Member(Default::default())
1741    }
1742}
1743
1744#[ast_node("CallExpression")]
1745#[derive(Eq, Hash, EqIgnoreSpan, Default)]
1746#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1747#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
1748pub struct OptCall {
1749    pub span: Span,
1750
1751    pub ctxt: SyntaxContext,
1752
1753    pub callee: Box<Expr>,
1754
1755    #[cfg_attr(feature = "serde-impl", serde(default, rename = "arguments"))]
1756    pub args: Vec<ExprOrSpread>,
1757
1758    #[cfg_attr(feature = "serde-impl", serde(default, rename = "typeArguments"))]
1759    #[cfg_attr(
1760        feature = "encoding-impl",
1761        encoding(with = "cbor4ii::core::types::Maybe")
1762    )]
1763    pub type_args: Option<Box<TsTypeParamInstantiation>>,
1764    }
1766
1767impl Take for OptChainExpr {
1768    fn dummy() -> Self {
1769        Self {
1770            span: DUMMY_SP,
1771            optional: false,
1772            base: Box::new(OptChainBase::Member(Take::dummy())),
1773        }
1774    }
1775}
1776
1777impl From<OptChainBase> for Expr {
1778    fn from(opt: OptChainBase) -> Self {
1779        match opt {
1780            OptChainBase::Call(OptCall {
1781                span,
1782                ctxt,
1783                callee,
1784                args,
1785                type_args,
1786            }) => Self::Call(CallExpr {
1787                callee: Callee::Expr(callee),
1788                args,
1789                span,
1790                type_args,
1791                ctxt,
1792            }),
1793            OptChainBase::Member(member) => Self::Member(member),
1794            #[cfg(all(swc_ast_unknown, feature = "encoding-impl"))]
1795            _ => swc_common::unknown!(),
1796        }
1797    }
1798}
1799
1800impl Take for OptCall {
1801    fn dummy() -> Self {
1802        Self {
1803            ..Default::default()
1804        }
1805    }
1806}
1807
1808impl From<OptCall> for CallExpr {
1809    fn from(
1810        OptCall {
1811            span,
1812            ctxt,
1813            callee,
1814            args,
1815            type_args,
1816        }: OptCall,
1817    ) -> Self {
1818        Self {
1819            span,
1820            callee: Callee::Expr(callee),
1821            args,
1822            type_args,
1823            ctxt,
1824        }
1825    }
1826}
1827
1828bridge_expr_from!(CallExpr, OptCall);
1829
1830test_de!(
1831    jsx_element,
1832    JSXElement,
1833    r#"{
1834      "type": "JSXElement",
1835      "span": {
1836        "start": 0,
1837        "end": 5,
1838        "ctxt": 0
1839      },
1840      "opening": {
1841        "type": "JSXOpeningElement",
1842        "name": {
1843          "type": "Identifier",
1844          "span": {
1845            "start": 1,
1846            "end": 2,
1847            "ctxt": 0
1848          },
1849          "value": "a",
1850          "optional": false
1851        },
1852        "span": {
1853          "start": 1,
1854          "end": 5,
1855          "ctxt": 0
1856        },
1857        "selfClosing": true
1858      },
1859      "children": [],
1860      "closing": null
1861    }"#
1862);