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);