1use serde::{ser::SerializeMap, Deserialize, Serialize};
2use swc_common::ast_serde;
3
4use crate::{
5 common::{
6 BaseNode, Decorator, Identifier, Param, PatternLike, TypeAnnotOrNoop, TypeParamDeclOrNoop,
7 },
8 expr::Expression,
9 flavor::Flavor,
10 flow::{
11 ObjectTypeCallProperty, ObjectTypeIndexer, ObjectTypeInternalSlot, ObjectTypeProperty,
12 ObjectTypeSpreadProperty,
13 },
14 lit::{NumericLiteral, StringLiteral},
15 stmt::BlockStatement,
16};
17
18#[derive(Debug, Clone, PartialEq)]
19#[ast_serde]
20pub enum UserWhitespacable {
21 #[tag("ObjectMethod")]
22 ObjectMethod(ObjectMethod),
23 #[tag("ObjectProperty")]
24 ObjectProperty(ObjectProperty),
25 #[tag("ObjectTypeInternalSlot")]
26 ObjectTypeInternalSlot(ObjectTypeInternalSlot),
27 #[tag("ObjectTypeCallProperty")]
28 ObjectTypeCallProperty(ObjectTypeCallProperty),
29 #[tag("ObjectTypeIndexer")]
30 ObjectTypeIndexer(ObjectTypeIndexer),
31 #[tag("ObjectTypeProperty")]
32 ObjectTypeProperty(ObjectTypeProperty),
33 #[tag("ObjectTypeSpreadProperty")]
34 ObjectTypeSpreadProperty(ObjectTypeSpreadProperty),
35}
36
37#[derive(Debug, Clone, PartialEq)]
38#[ast_serde]
39pub enum ObjectMember {
40 #[tag("ObjectMember")]
41 Method(ObjectMethod),
42 #[tag("ObjectProperty")]
43 Prop(ObjectProperty),
44}
45
46#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
47#[serde(rename_all = "lowercase")]
48pub enum ObjectMethodKind {
49 Method,
50 Get,
51 Set,
52}
53
54#[derive(Debug, Clone, PartialEq)]
55#[ast_serde]
56pub enum ObjectKey {
57 #[tag("Identifier")]
58 Id(Identifier),
59 #[tag("StringLiteral")]
60 String(StringLiteral),
61 #[tag("NumericLiteral")]
62 Numeric(NumericLiteral),
63 #[tag("*")]
64 Expr(Box<Expression>),
65}
66
67#[derive(Debug, Clone, Deserialize, PartialEq)]
68#[serde(rename_all = "camelCase")]
69#[serde(tag = "type")]
70pub struct ObjectMethod {
71 #[serde(flatten)]
72 pub base: BaseNode,
73 pub kind: ObjectMethodKind,
74 pub key: ObjectKey,
75 #[serde(default)]
76 pub params: Vec<Param>,
77 pub body: BlockStatement,
78 #[serde(default)]
79 pub computed: bool,
80 #[serde(default)]
81 pub generator: Option<bool>,
82 #[serde(default, rename = "async")]
83 pub is_async: Option<bool>,
84 #[serde(default)]
85 pub decorator: Option<Vec<Decorator>>,
86 #[serde(default)]
87 pub return_type: Option<Box<TypeAnnotOrNoop>>,
88 #[serde(default)]
89 pub type_parameters: Option<TypeParamDeclOrNoop>,
90}
91
92impl Serialize for ObjectMethod {
93 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
94 where
95 S: serde::Serializer,
96 {
97 match Flavor::current() {
98 Flavor::Babel => {
99 let actual = BabelObjectMethod {
100 type_: "ObjectMethod",
101 base: &self.base,
102 key: &self.key,
103 kind: self.kind,
104 params: &self.params,
105 body: &self.body,
106 computed: self.computed,
107 generator: self.generator,
108 is_async: self.is_async,
109 decorator: self.decorator.as_deref(),
110 return_type: self.return_type.as_deref(),
111 type_parameters: self.type_parameters.as_ref(),
112 };
113 actual.serialize(serializer)
114 }
115 Flavor::Acorn { .. } => {
116 let mut s = serializer.serialize_map(None)?;
117
118 {
119 self.base
121 .serialize(crate::flat_map_serializer::FlatMapSerializer(&mut s))?;
122 }
123
124 s.serialize_entry("type", "Property")?;
125 s.serialize_entry("kind", &self.kind)?;
126 s.serialize_entry("method", &false)?;
127 s.serialize_entry("shorthand", &false)?;
128 s.serialize_entry("key", &self.key)?;
129 s.serialize_entry("computed", &self.computed)?;
130
131 s.serialize_entry(
132 "value",
133 &AcornObjectMethodValue {
134 type_: "FunctionExpression",
135 base: &self.base,
136 body: &self.body,
137 params: &self.params,
138 generator: self.generator.unwrap_or(false),
139 is_async: self.is_async.unwrap_or(false),
140 },
141 )?;
142
143 s.end()
144 }
145 }
146 }
147}
148
149#[derive(Serialize)]
150struct AcornObjectMethodValue<'a> {
151 #[serde(rename = "type")]
153 type_: &'static str,
154 #[serde(flatten)]
155 base: &'a BaseNode,
156
157 body: &'a BlockStatement,
158
159 params: &'a [Param],
160
161 generator: bool,
162 #[serde(rename = "async")]
163 is_async: bool,
164}
165
166#[derive(Serialize)]
167#[serde(rename_all = "camelCase")]
168struct BabelObjectMethod<'a> {
169 #[serde(rename = "type")]
170 type_: &'static str,
171 #[serde(flatten)]
172 pub base: &'a BaseNode,
173 pub kind: ObjectMethodKind,
174 pub key: &'a ObjectKey,
175 #[serde(default)]
176 pub params: &'a [Param],
177 pub body: &'a BlockStatement,
178 #[serde(default)]
179 pub computed: bool,
180 #[serde(default)]
181 pub generator: Option<bool>,
182 #[serde(default, rename = "async")]
183 pub is_async: Option<bool>,
184 #[serde(default)]
185 pub decorator: Option<&'a [Decorator]>,
186 #[serde(default)]
187 pub return_type: Option<&'a TypeAnnotOrNoop>,
188 #[serde(default)]
189 pub type_parameters: Option<&'a TypeParamDeclOrNoop>,
190}
191
192#[derive(Debug, Clone, PartialEq)]
193#[ast_serde]
194pub enum ObjectPropVal {
195 #[tag("Identifier")]
196 #[tag("RestElement")]
197 #[tag("AssignmentPattern")]
198 #[tag("ArrayPattern")]
199 #[tag("ObjectPattern")]
200 Pattern(PatternLike),
201 #[tag("*")]
202 Expr(Box<Expression>),
203}
204
205#[derive(Debug, Clone, Deserialize, PartialEq)]
206pub struct ObjectProperty {
207 #[serde(flatten)]
208 pub base: BaseNode,
209 pub key: ObjectKey,
210 pub value: ObjectPropVal,
211 #[serde(default)]
212 pub computed: bool,
213 #[serde(default)]
214 pub shorthand: bool,
215 #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")]
216 pub decorators: Option<Vec<Decorator>>,
217}
218
219#[derive(Serialize)]
220struct BabelObjectProperty<'a> {
221 #[serde(rename = "type")]
222 type_: &'a str,
223 #[serde(flatten)]
224 base: &'a BaseNode,
225 key: &'a ObjectKey,
226 value: &'a ObjectPropVal,
227 method: bool,
228 computed: bool,
229 shorthand: bool,
230 #[serde(skip_serializing_if = "crate::flavor::Flavor::skip_none")]
231 decorators: Option<&'a [Decorator]>,
232}
233
234impl Serialize for ObjectProperty {
235 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
236 where
237 S: serde::Serializer,
238 {
239 match Flavor::current() {
240 Flavor::Babel => {
241 let actual = BabelObjectProperty {
242 type_: "ObjectProperty",
243 base: &self.base,
244 key: &self.key,
245 value: &self.value,
246 method: false,
247 computed: self.computed,
248 shorthand: self.shorthand,
249 decorators: self.decorators.as_deref(),
250 };
251 actual.serialize(serializer)
252 }
253 Flavor::Acorn { .. } => {
254 let mut s = serializer.serialize_map(None)?;
255
256 {
257 self.base
259 .serialize(crate::flat_map_serializer::FlatMapSerializer(&mut s))?;
260 }
261
262 s.serialize_entry("type", "Property")?;
263 s.serialize_entry("kind", "init")?;
264 s.serialize_entry("method", &false)?;
265 s.serialize_entry("shorthand", &self.shorthand)?;
266 s.serialize_entry("key", &self.key)?;
267 s.serialize_entry("value", &self.value)?;
268 s.serialize_entry("computed", &self.computed)?;
269 if let Some(decorators) = &self.decorators {
270 if !decorators.is_empty() {
271 s.serialize_entry("decorators", decorators)?;
272 }
273 }
274
275 s.end()
276 }
277 }
278 }
279}