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