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