swc_estree_ast/
expr.rs

1use serde::{Deserialize, Serialize};
2use swc_atoms::Atom;
3use swc_common::ast_serde;
4
5use crate::{
6    class::{ClassBody, ClassImpl},
7    common::{
8        BaseNode, Decorator, Identifier, LVal, MetaProperty, Param, PrivateName, SpreadElement,
9        SuperTypeParams, TypeAnnotOrNoop, TypeParamDeclOrNoop,
10    },
11    flow::{
12        InterfaceExtends, TypeAnnotation, TypeParameterDeclaration, TypeParameterInstantiation,
13    },
14    jsx::{JSXElement, JSXFragment, JSXNamespacedName},
15    lit::{Literal, TemplateLiteral},
16    module::{Import, Program},
17    object::{ObjectMethod, ObjectProperty},
18    stmt::{BlockStatement, ExpressionStatement},
19    typescript::{
20        TSAsExpression, TSNonNullExpression, TSTypeAssertion, TSTypeParameterInstantiation,
21    },
22};
23
24#[derive(Debug, Clone, PartialEq)]
25#[ast_serde]
26pub enum Expression {
27    #[tag("ArrayExpression")]
28    Array(ArrayExpression),
29    #[tag("AssignmentExpression")]
30    Assignment(AssignmentExpression),
31    #[tag("BinaryExpression")]
32    Binary(BinaryExpression),
33    #[tag("CallExpression")]
34    Call(CallExpression),
35    #[tag("ConditionalExpression")]
36    Conditional(ConditionalExpression),
37    #[tag("FunctionExpression")]
38    Func(FunctionExpression),
39    #[tag("Identifier")]
40    Id(Identifier),
41    #[tag("StringLiteral")]
42    #[tag("NumericLiteral")]
43    #[tag("NullLiteral")]
44    #[tag("BooleanLiteral")]
45    #[tag("RegExpLiteral")]
46    #[tag("DecimalLiteral")]
47    #[tag("BigIntLiteral")]
48    Literal(Literal),
49    #[tag("LogicalExpression")]
50    Logical(LogicalExpression),
51    #[tag("MemberExpression")]
52    Member(MemberExpression),
53    #[tag("NewExpression")]
54    New(NewExpression),
55    #[tag("ObjectExpression")]
56    Object(ObjectExpression),
57    #[tag("SequenceExpression")]
58    Sequence(SequenceExpression),
59    #[tag("ParenthesizedExpression")]
60    Parenthesized(ParenthesizedExpression),
61    #[tag("ThisExpression")]
62    This(ThisExpression),
63    #[tag("UnaryExpression")]
64    Unary(UnaryExpression),
65    #[tag("UpdateExpression")]
66    Update(UpdateExpression),
67    #[tag("ArrowFunctionExpression")]
68    ArrowFunc(ArrowFunctionExpression),
69    #[tag("ClassExpression")]
70    Class(ClassExpression),
71    #[tag("MetaProperty")]
72    MetaProp(MetaProperty),
73    #[tag("Super")]
74    Super(Super),
75    #[tag("TaggedTemplateExpression")]
76    TaggedTemplate(TaggedTemplateExpression),
77    #[tag("TemplateLiteral")]
78    TemplateLiteral(TemplateLiteral),
79    #[tag("YieldExpression")]
80    Yield(YieldExpression),
81    #[tag("AwaitExpression")]
82    Await(AwaitExpression),
83    #[tag("Import")]
84    Import(Import),
85    #[tag("OptionalMemberExpression")]
86    OptionalMember(OptionalMemberExpression),
87    #[tag("OptionalCallExpression")]
88    OptionalCall(OptionalCallExpression),
89    #[tag("TypeCastExpression")]
90    TypeCast(TypeCastExpression),
91    #[tag("JSXElement")]
92    JSXElement(JSXElement),
93    #[tag("Fragment")]
94    JSXFragment(JSXFragment),
95    #[tag("BindExpression")]
96    Bind(BindExpression),
97    #[tag("PipelinePrimaryTopicReference")]
98    PipelinePrimaryTopicRef(PipelinePrimaryTopicReference),
99    #[tag("DoExpression")]
100    Do(DoExpression),
101    #[tag("RecordExpression")]
102    Record(RecordExpression),
103    #[tag("TupleExpression")]
104    Tuple(TupleExpression),
105    #[tag("ModuleExpression")]
106    Module(ModuleExpression),
107    #[tag("TSAsExpression")]
108    TSAs(TSAsExpression),
109    #[tag("TSTypeAssertion")]
110    TSTypeAssertion(TSTypeAssertion),
111    #[tag("TSNonNullExpression")]
112    TSNonNull(TSNonNullExpression),
113}
114
115#[derive(Debug, Clone, PartialEq)]
116#[ast_serde]
117pub enum ExpressionWrapper {
118    #[tag("ExpressionStatement")]
119    Stmt(ExpressionStatement),
120    #[tag("ParenthesizedExpression")]
121    Parenthesized(ParenthesizedExpression),
122    #[tag("TypeCastExpression")]
123    TypeCast(TypeCastExpression),
124}
125
126#[derive(Debug, Clone, PartialEq)]
127#[ast_serde]
128pub enum ArrayExprEl {
129    #[tag("SpreadElement")]
130    Spread(SpreadElement),
131    #[tag("*")]
132    Expr(Box<Expression>),
133}
134
135#[derive(Debug, Clone, PartialEq)]
136#[ast_serde("ArrayExpression")]
137pub struct ArrayExpression {
138    #[serde(flatten)]
139    pub base: BaseNode,
140    #[serde(default)]
141    pub elements: Vec<Option<ArrayExprEl>>,
142}
143
144#[derive(Debug, Clone, PartialEq)]
145#[ast_serde("AssignmentExpression")]
146pub struct AssignmentExpression {
147    #[serde(flatten)]
148    pub base: BaseNode,
149    #[serde(default)]
150    pub operator: Atom,
151    pub left: Box<LVal>,
152    pub right: Box<Expression>,
153}
154
155#[derive(Debug, Clone, PartialEq)]
156#[ast_serde]
157pub enum MemberExprProp {
158    #[tag("Identifier")]
159    Id(Identifier),
160    #[tag("PrivateName")]
161    PrivateName(PrivateName),
162    #[tag("*")]
163    Expr(Box<Expression>),
164}
165
166#[derive(Debug, Clone, PartialEq)]
167#[ast_serde("MemberExpression")]
168pub struct MemberExpression {
169    #[serde(flatten)]
170    pub base: BaseNode,
171    pub object: Box<Expression>,
172    pub property: Box<MemberExprProp>,
173    #[serde(default)]
174    pub computed: bool,
175    #[serde(default, serialize_with = "crate::ser::serialize_optional")]
176    pub optional: Option<bool>,
177}
178
179// Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
180#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
181pub enum BinaryExprOp {
182    #[serde(rename = "+")]
183    Addition,
184    #[serde(rename = "-")]
185    Subtraction,
186    #[serde(rename = "/")]
187    Division,
188    #[serde(rename = "%")]
189    Remainder,
190    #[serde(rename = "*")]
191    Multiplication,
192    #[serde(rename = "**")]
193    Exponentiation,
194    #[serde(rename = "&")]
195    And,
196    #[serde(rename = "|")]
197    Or,
198    #[serde(rename = ">>")]
199    RightShift,
200    #[serde(rename = ">>>")]
201    UnsignedRightShift,
202    #[serde(rename = "<<")]
203    LeftShift,
204    #[serde(rename = "^")]
205    Xor,
206    #[serde(rename = "==")]
207    Equal,
208    #[serde(rename = "===")]
209    StrictEqual,
210    #[serde(rename = "!=")]
211    NotEqual,
212    #[serde(rename = "!==")]
213    StrictNotEqual,
214    #[serde(rename = "in")]
215    In,
216    #[serde(rename = "instanceof")]
217    Instanceof,
218    #[serde(rename = ">")]
219    GreaterThan,
220    #[serde(rename = "<")]
221    LessThan,
222    #[serde(rename = ">=")]
223    GreaterThanOrEqual,
224    #[serde(rename = "<=")]
225    LessThanOrEqual,
226}
227
228#[derive(Debug, Clone, PartialEq)]
229#[ast_serde]
230pub enum BinaryExprLeft {
231    #[tag("PrivateName")]
232    Private(PrivateName),
233    #[tag("*")]
234    Expr(Box<Expression>),
235}
236
237#[derive(Debug, Clone, PartialEq)]
238#[ast_serde("BinaryExpression")]
239pub struct BinaryExpression {
240    #[serde(flatten)]
241    pub base: BaseNode,
242    pub operator: BinaryExprOp,
243    pub left: Box<BinaryExprLeft>,
244    pub right: Box<Expression>,
245}
246
247#[derive(Debug, Clone, PartialEq, Eq)]
248#[ast_serde("V8IntrinsicIdentifier")]
249pub struct V8IntrinsicIdentifier {
250    #[serde(flatten)]
251    pub base: BaseNode,
252    #[serde(default)]
253    pub name: Atom,
254}
255
256#[derive(Debug, Clone, PartialEq)]
257#[ast_serde]
258pub enum Callee {
259    #[tag("V8IntrinsicIdentifier")]
260    V8Id(V8IntrinsicIdentifier),
261    #[tag("*")]
262    Expr(Box<Expression>),
263}
264
265impl From<Expression> for Callee {
266    fn from(expr: Expression) -> Self {
267        Callee::Expr(Box::new(expr))
268    }
269}
270
271#[derive(Debug, Clone, PartialEq, Eq)]
272#[ast_serde("ArgumentPlaceholder")]
273pub struct ArgumentPlaceholder {
274    #[serde(flatten)]
275    pub base: BaseNode,
276}
277
278#[derive(Debug, Clone, PartialEq)]
279#[ast_serde]
280pub enum Arg {
281    #[tag("SpreadElement")]
282    Spread(SpreadElement),
283    #[tag("JSXNamespacedName")]
284    JSXName(JSXNamespacedName),
285    #[tag("ArgumentPlaceholder")]
286    Placeholder(ArgumentPlaceholder),
287    #[tag("*")]
288    Expr(Box<Expression>),
289}
290
291impl From<ArrayExprEl> for Arg {
292    fn from(el: ArrayExprEl) -> Self {
293        match el {
294            ArrayExprEl::Expr(e) => Arg::Expr(e),
295            ArrayExprEl::Spread(s) => Arg::Spread(s),
296        }
297    }
298}
299
300#[derive(Debug, Clone, PartialEq)]
301#[ast_serde("CallExpression")]
302pub struct CallExpression {
303    #[serde(flatten)]
304    pub base: BaseNode,
305    pub callee: Box<Callee>,
306    #[serde(default)]
307    pub arguments: Vec<Arg>,
308    #[serde(default, serialize_with = "crate::ser::serialize_optional")]
309    pub optional: Option<bool>,
310    #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")]
311    pub type_arguments: Option<TypeParameterInstantiation>,
312    #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")]
313    pub type_parameters: Option<TSTypeParameterInstantiation>,
314}
315
316#[derive(Debug, Clone, PartialEq)]
317#[ast_serde("ConditionalExpression")]
318pub struct ConditionalExpression {
319    #[serde(flatten)]
320    pub base: BaseNode,
321    pub test: Box<Expression>,
322    pub consequent: Box<Expression>,
323    pub alternate: Box<Expression>,
324}
325
326#[derive(Debug, Clone, PartialEq)]
327#[ast_serde("FunctionExpression")]
328pub struct FunctionExpression {
329    #[serde(flatten)]
330    pub base: BaseNode,
331    #[serde(default)]
332    pub id: Option<Identifier>,
333    #[serde(default)]
334    pub params: Vec<Param>,
335    pub body: BlockStatement,
336    #[serde(default)]
337    pub generator: Option<bool>,
338    #[serde(default, rename = "async")]
339    pub is_async: Option<bool>,
340    #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")]
341    pub return_type: Option<Box<TypeAnnotOrNoop>>,
342    #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")]
343    pub type_parameters: Option<TypeParamDeclOrNoop>,
344}
345
346#[derive(Debug, Clone, PartialEq)]
347#[ast_serde("NewExpression")]
348pub struct NewExpression {
349    #[serde(flatten)]
350    pub base: BaseNode,
351    pub callee: Callee,
352    #[serde(default)]
353    pub arguments: Vec<Arg>,
354    #[serde(
355        default,
356        skip_serializing_if = "crate::flavor::Flavor::skip_none_and_false"
357    )]
358    pub optional: Option<bool>,
359    #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")]
360    pub type_arguments: Option<TypeParameterInstantiation>,
361    #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")]
362    pub type_parameters: Option<TSTypeParameterInstantiation>,
363}
364
365// Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
366#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
367pub enum LogicalExprOp {
368    #[serde(rename = "||")]
369    Or,
370    #[serde(rename = "&&")]
371    And,
372    #[serde(rename = "??")]
373    Nullish,
374}
375
376#[derive(Debug, Clone, PartialEq)]
377#[ast_serde("LogicalExpression")]
378pub struct LogicalExpression {
379    #[serde(flatten)]
380    pub base: BaseNode,
381    pub operator: LogicalExprOp,
382    pub left: Box<Expression>,
383    pub right: Box<Expression>,
384}
385
386#[derive(Debug, Clone, PartialEq)]
387#[ast_serde]
388pub enum ObjectExprProp {
389    #[tag("ObjectMethod")]
390    Method(ObjectMethod),
391    #[tag("ObjectProperty")]
392    Prop(ObjectProperty),
393    #[tag("SpreadElement")]
394    Spread(SpreadElement),
395}
396
397#[derive(Debug, Clone, PartialEq)]
398#[ast_serde("ObjectExpression")]
399pub struct ObjectExpression {
400    #[serde(flatten)]
401    pub base: BaseNode,
402    #[serde(default)]
403    pub properties: Vec<ObjectExprProp>,
404}
405
406#[derive(Debug, Clone, PartialEq)]
407#[ast_serde("SequenceExpression")]
408pub struct SequenceExpression {
409    #[serde(flatten)]
410    pub base: BaseNode,
411    #[serde(default)]
412    pub expressions: Vec<Box<Expression>>,
413}
414
415#[derive(Debug, Clone, PartialEq)]
416#[ast_serde("ParenthesizedExpression")]
417pub struct ParenthesizedExpression {
418    #[serde(flatten)]
419    pub base: BaseNode,
420    pub expression: Box<Expression>,
421}
422
423#[derive(Debug, Clone, PartialEq, Eq)]
424#[ast_serde("ThisExpression")]
425pub struct ThisExpression {
426    #[serde(flatten)]
427    pub base: BaseNode,
428}
429
430// Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
431#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
432#[serde(rename_all = "lowercase")]
433pub enum UnaryExprOp {
434    Void,
435    Throw,
436    Delete,
437    #[serde(rename = "!")]
438    LogicalNot,
439    #[serde(rename = "+")]
440    Plus,
441    #[serde(rename = "-")]
442    Negation,
443    #[serde(rename = "~")]
444    BitwiseNot,
445    Typeof,
446}
447
448fn default_prefix() -> bool {
449    true
450}
451
452#[derive(Debug, Clone, PartialEq)]
453#[ast_serde("UnaryExpression")]
454pub struct UnaryExpression {
455    #[serde(flatten)]
456    pub base: BaseNode,
457    pub operator: UnaryExprOp,
458    pub argument: Box<Expression>,
459    #[serde(default = "default_prefix")]
460    pub prefix: bool,
461}
462
463// Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
464#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
465pub enum UpdateExprOp {
466    #[serde(rename = "++")]
467    Increment,
468    #[serde(rename = "--")]
469    Decrement,
470}
471
472#[derive(Debug, Clone, PartialEq)]
473#[ast_serde("UpdateExpression")]
474pub struct UpdateExpression {
475    #[serde(flatten)]
476    pub base: BaseNode,
477    pub operator: UpdateExprOp,
478    pub argument: Box<Expression>,
479    #[serde(default)]
480    pub prefix: bool,
481}
482
483#[derive(Debug, Clone, PartialEq)]
484#[ast_serde]
485pub enum ArrowFuncExprBody {
486    #[tag("BlockStatement")]
487    Block(BlockStatement),
488    #[tag("*")]
489    Expr(Box<Expression>),
490}
491
492#[derive(Debug, Clone, PartialEq)]
493#[ast_serde("ArrowFunctionExpression")]
494pub struct ArrowFunctionExpression {
495    #[serde(flatten)]
496    pub base: BaseNode,
497    #[serde(default)]
498    pub params: Vec<Param>,
499    pub body: Box<ArrowFuncExprBody>,
500    #[serde(default, rename = "async")]
501    pub is_async: bool,
502    #[serde(default)]
503    pub expression: bool,
504    #[serde(default)]
505    pub generator: bool,
506    #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")]
507    pub return_type: Option<Box<TypeAnnotOrNoop>>,
508    #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")]
509    pub type_parameters: Option<TypeParamDeclOrNoop>,
510}
511
512#[derive(Debug, Clone, PartialEq)]
513#[ast_serde("ClassExpression")]
514pub struct ClassExpression {
515    #[serde(flatten)]
516    pub base: BaseNode,
517    #[serde(default)]
518    pub id: Option<Identifier>,
519    #[serde(default)]
520    pub super_class: Option<Box<Expression>>,
521    pub body: ClassBody,
522    #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_empty")]
523    pub decorators: Option<Vec<Decorator>>,
524    #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_empty")]
525    pub implements: Option<Vec<ClassImpl>>,
526    #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")]
527    pub mixins: Option<InterfaceExtends>,
528    #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")]
529    pub super_type_parameters: Option<SuperTypeParams>,
530    #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")]
531    pub type_parameters: Option<TypeParamDeclOrNoop>,
532}
533
534#[derive(Debug, Clone, PartialEq)]
535#[ast_serde]
536pub enum TaggedTemplateExprTypeParams {
537    #[tag("TypeParameterDeclaration")]
538    Flow(TypeParameterDeclaration),
539    #[tag("TSTypeParameterInstantiation")]
540    TS(TSTypeParameterInstantiation),
541}
542
543#[derive(Debug, Clone, PartialEq)]
544#[ast_serde("TaggedTemplateExpression")]
545pub struct TaggedTemplateExpression {
546    #[serde(flatten)]
547    pub base: BaseNode,
548    pub tag: Box<Expression>,
549    pub quasi: TemplateLiteral,
550    #[serde(default)]
551    pub type_parameters: Option<TaggedTemplateExprTypeParams>,
552}
553
554#[derive(Debug, Clone, PartialEq)]
555#[ast_serde("YieldExpression")]
556pub struct YieldExpression {
557    #[serde(flatten)]
558    pub base: BaseNode,
559    #[serde(default)]
560    pub argument: Option<Box<Expression>>,
561    #[serde(default)]
562    pub delegate: bool,
563}
564
565#[derive(Debug, Clone, PartialEq)]
566#[ast_serde("AwaitExpression")]
567pub struct AwaitExpression {
568    #[serde(flatten)]
569    pub base: BaseNode,
570    pub argument: Box<Expression>,
571}
572
573#[derive(Debug, Clone, PartialEq)]
574#[ast_serde]
575pub enum OptionalMemberExprProp {
576    #[tag("Identifier")]
577    Id(Identifier),
578    #[tag("*")]
579    Expr(Box<Expression>),
580}
581
582#[derive(Debug, Clone, PartialEq)]
583#[ast_serde("OptionalMemberExpression")]
584pub struct OptionalMemberExpression {
585    #[serde(flatten)]
586    pub base: BaseNode,
587    pub object: Box<Expression>,
588    pub property: OptionalMemberExprProp,
589    #[serde(default)]
590    pub computed: bool,
591    #[serde(default)]
592    pub optional: bool,
593}
594
595#[derive(Debug, Clone, PartialEq)]
596#[ast_serde("OptionalCallExpression")]
597pub struct OptionalCallExpression {
598    #[serde(flatten)]
599    pub base: BaseNode,
600    pub callee: Box<Expression>,
601    #[serde(default)]
602    pub arguments: Vec<Arg>,
603    #[serde(default)]
604    pub optional: bool,
605    #[serde(default)]
606    pub type_arguments: Option<TypeParameterInstantiation>,
607    #[serde(default)]
608    pub type_parameters: Option<TSTypeParameterInstantiation>,
609}
610
611#[derive(Debug, Clone, PartialEq)]
612#[ast_serde("TypeCastExpression")]
613pub struct TypeCastExpression {
614    #[serde(flatten)]
615    pub base: BaseNode,
616    pub expression: Box<Expression>,
617    pub type_annotation: TypeAnnotation,
618}
619
620#[derive(Debug, Clone, PartialEq)]
621#[ast_serde("BindExpression")]
622pub struct BindExpression {
623    #[serde(flatten)]
624    pub base: BaseNode,
625    pub object: Box<Expression>,
626    pub callee: Box<Expression>,
627}
628
629#[derive(Debug, Clone, PartialEq, Eq)]
630#[ast_serde("PipelinePrimaryTopicReference")]
631pub struct PipelinePrimaryTopicReference {
632    #[serde(flatten)]
633    pub base: BaseNode,
634}
635
636#[derive(Debug, Clone, PartialEq)]
637#[ast_serde("DoExpression")]
638pub struct DoExpression {
639    #[serde(flatten)]
640    pub base: BaseNode,
641    pub body: BlockStatement,
642}
643
644#[derive(Debug, Clone, PartialEq)]
645#[ast_serde]
646pub enum RecordExprProp {
647    #[tag("ObjectProperty")]
648    Prop(ObjectProperty),
649    #[tag("SpreadElement")]
650    Spread(SpreadElement),
651}
652
653#[derive(Debug, Clone, PartialEq)]
654#[ast_serde("RecordExpression")]
655pub struct RecordExpression {
656    #[serde(flatten)]
657    pub base: BaseNode,
658    #[serde(default)]
659    pub properties: Vec<RecordExprProp>,
660}
661
662#[derive(Debug, Clone, PartialEq)]
663#[ast_serde]
664pub enum TupleExprEl {
665    #[tag("SpreadElement")]
666    Spread(SpreadElement),
667    #[tag("*")]
668    Expr(Box<Expression>),
669}
670
671#[derive(Debug, Clone, PartialEq)]
672#[ast_serde("TupleExpression")]
673pub struct TupleExpression {
674    #[serde(flatten)]
675    pub base: BaseNode,
676    #[serde(default)]
677    pub elements: Vec<TupleExprEl>,
678}
679
680#[derive(Debug, Clone, PartialEq)]
681#[ast_serde("ModuleExpression")]
682pub struct ModuleExpression {
683    #[serde(flatten)]
684    pub base: BaseNode,
685    pub body: Program,
686}
687
688#[derive(Debug, Clone, PartialEq, Eq)]
689#[ast_serde("Super")]
690pub struct Super {
691    #[serde(flatten)]
692    pub base: BaseNode,
693}