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