swc_ecma_ast/
prop.rs

1use is_macro::Is;
2use swc_common::{ast_node, util::take::Take, EqIgnoreSpan, Span, DUMMY_SP};
3
4use crate::{
5    expr::Expr,
6    function::Function,
7    ident::Ident,
8    lit::{BigInt, Number, Str},
9    stmt::BlockStmt,
10    typescript::TsTypeAnn,
11    Id, IdentName, MemberProp, Pat,
12};
13
14#[ast_node]
15#[derive(Eq, Hash, Is, EqIgnoreSpan)]
16#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
17#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
18pub enum Prop {
19    /// `a` in `{ a, }`
20    #[tag("Identifier")]
21    Shorthand(Ident),
22
23    /// `key: value` in `{ key: value, }`
24    #[tag("KeyValueProperty")]
25    KeyValue(KeyValueProp),
26
27    /// This is **invalid** for object literal.
28    #[tag("AssignmentProperty")]
29    Assign(AssignProp),
30
31    #[tag("GetterProperty")]
32    Getter(GetterProp),
33
34    #[tag("SetterProperty")]
35    Setter(SetterProp),
36
37    #[tag("MethodProperty")]
38    Method(MethodProp),
39}
40
41bridge_from!(Prop, Ident, IdentName);
42
43#[ast_node("KeyValueProperty")]
44#[derive(Eq, Hash, EqIgnoreSpan)]
45#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
46#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
47pub struct KeyValueProp {
48    #[span(lo)]
49    pub key: PropName,
50
51    #[span(hi)]
52    pub value: Box<Expr>,
53}
54
55#[ast_node("AssignmentProperty")]
56#[derive(Eq, Hash, EqIgnoreSpan)]
57#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
58#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
59pub struct AssignProp {
60    pub span: Span,
61    pub key: Ident,
62    pub value: Box<Expr>,
63}
64
65#[ast_node("GetterProperty")]
66#[derive(Eq, Hash, EqIgnoreSpan, Default)]
67#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
68#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
69pub struct GetterProp {
70    pub span: Span,
71    pub key: PropName,
72    #[cfg_attr(feature = "serde-impl", serde(default, rename = "typeAnnotation"))]
73    pub type_ann: Option<Box<TsTypeAnn>>,
74    #[cfg_attr(feature = "serde-impl", serde(default))]
75    pub body: Option<BlockStmt>,
76}
77#[ast_node("SetterProperty")]
78#[derive(Eq, Hash, EqIgnoreSpan, Default)]
79#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
80#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
81pub struct SetterProp {
82    pub span: Span,
83    pub key: PropName,
84    pub this_param: Option<Pat>,
85    pub param: Box<Pat>,
86    #[cfg_attr(feature = "serde-impl", serde(default))]
87    pub body: Option<BlockStmt>,
88}
89#[ast_node("MethodProperty")]
90#[derive(Eq, Hash, EqIgnoreSpan)]
91#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
92#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
93pub struct MethodProp {
94    pub key: PropName,
95
96    #[cfg_attr(feature = "serde-impl", serde(flatten))]
97    #[span]
98    pub function: Box<Function>,
99}
100
101#[ast_node]
102#[derive(Eq, Hash, Is, EqIgnoreSpan)]
103#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
104#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
105pub enum PropName {
106    #[tag("Identifier")]
107    Ident(IdentName),
108    /// String literal.
109    #[tag("StringLiteral")]
110    Str(Str),
111    /// Numeric literal.
112    #[tag("NumericLiteral")]
113    Num(Number),
114    #[tag("Computed")]
115    Computed(ComputedPropName),
116    #[tag("BigIntLiteral")]
117    BigInt(BigInt),
118}
119
120bridge_from!(PropName, IdentName, Ident);
121bridge_from!(PropName, Ident, Id);
122
123impl Default for PropName {
124    fn default() -> Self {
125        PropName::Ident(Default::default())
126    }
127}
128
129impl Take for PropName {
130    fn dummy() -> Self {
131        PropName::Ident(Take::dummy())
132    }
133}
134
135impl From<PropName> for MemberProp {
136    fn from(p: PropName) -> Self {
137        match p {
138            PropName::Ident(p) => MemberProp::Ident(p),
139            PropName::Computed(p) => MemberProp::Computed(p),
140            PropName::Str(p) => MemberProp::Computed(ComputedPropName {
141                span: DUMMY_SP,
142                expr: p.into(),
143            }),
144            PropName::Num(p) => MemberProp::Computed(ComputedPropName {
145                span: DUMMY_SP,
146                expr: p.into(),
147            }),
148            PropName::BigInt(p) => MemberProp::Computed(ComputedPropName {
149                span: DUMMY_SP,
150                expr: p.into(),
151            }),
152        }
153    }
154}
155
156#[ast_node("Computed")]
157#[derive(Eq, Hash, EqIgnoreSpan)]
158#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
159#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
160pub struct ComputedPropName {
161    /// Span including `[` and `]`.
162    pub span: Span,
163    #[cfg_attr(feature = "serde-impl", serde(rename = "expression"))]
164    pub expr: Box<Expr>,
165}
166
167impl Take for ComputedPropName {
168    fn dummy() -> Self {
169        Self {
170            span: DUMMY_SP,
171            expr: Take::dummy(),
172        }
173    }
174}