Skip to main content

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