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