1use crate::class::Class;
4use crate::function::{ArrowFunction, Function};
5use crate::identifier::{Identifier, PrivateIdentifier};
6use crate::literal::Literal;
7use crate::operator::{
8 AssignmentOperator, BinaryOperator, LogicalOperator, UnaryOperator, UpdateOperator,
9};
10use crate::span::Spanned;
11
12pub type Expression = Spanned<ExpressionKind>;
14
15#[derive(Debug, Clone, PartialEq, Eq)]
17pub enum ExpressionKind {
18 This,
20 Super,
22 Identifier(Identifier),
24 PrivateIdentifier(PrivateIdentifier),
26 Literal(Literal),
28 Template {
31 quasis: Vec<String>,
33 expressions: Vec<Expression>,
35 },
36 TaggedTemplate {
38 tag: Box<Expression>,
40 quasis: Vec<String>,
42 expressions: Vec<Expression>,
44 },
45 Array {
48 elements: Vec<Option<Expression>>,
50 },
51 Object {
53 properties: Vec<ObjectMember>,
55 },
56 Member {
59 object: Box<Expression>,
61 property: MemberProperty,
63 optional: bool,
65 },
66 Call {
68 callee: Box<Expression>,
70 arguments: Vec<Expression>,
72 optional: bool,
74 },
75 New {
77 callee: Box<Expression>,
79 arguments: Vec<Expression>,
81 },
82 Update {
84 operator: UpdateOperator,
86 argument: Box<Expression>,
88 prefix: bool,
90 },
91 Unary {
93 operator: UnaryOperator,
95 argument: Box<Expression>,
97 },
98 Binary {
100 operator: BinaryOperator,
102 left: Box<Expression>,
104 right: Box<Expression>,
106 },
107 Logical {
109 operator: LogicalOperator,
111 left: Box<Expression>,
113 right: Box<Expression>,
115 },
116 Conditional {
118 test: Box<Expression>,
120 consequent: Box<Expression>,
122 alternate: Box<Expression>,
124 },
125 Assignment {
127 operator: AssignmentOperator,
129 left: Box<Expression>,
132 right: Box<Expression>,
134 },
135 Sequence {
138 expressions: Vec<Expression>,
140 },
141 Spread {
143 argument: Box<Expression>,
145 },
146 ArrowFunction(Box<ArrowFunction>),
148 FunctionExpression(Box<Function>),
150 ClassExpression(Box<Class>),
152 Yield {
154 argument: Option<Box<Expression>>,
156 delegate: bool,
158 },
159 Await {
161 argument: Box<Expression>,
163 },
164 Chain {
167 expression: Box<Expression>,
170 },
171 ImportExpression {
173 source: Box<Expression>,
175 options: Option<Box<Expression>>,
177 },
178 MetaProperty {
180 meta: Identifier,
182 property: Identifier,
184 },
185 Parenthesized {
188 expression: Box<Expression>,
190 },
191}
192
193#[derive(Debug, Clone, PartialEq, Eq)]
195pub enum MemberProperty {
196 Identifier(Identifier),
198 Computed(Box<Expression>),
200 Private(PrivateIdentifier),
202}
203
204#[derive(Debug, Clone, PartialEq)]
207pub enum PropertyKey {
208 Identifier(Identifier),
210 String(String),
212 Number(f64),
214 Computed(Box<Expression>),
216 Private(PrivateIdentifier),
218}
219
220impl Eq for PropertyKey {}
221
222impl std::fmt::Display for PropertyKey {
223 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
224 match self {
225 Self::Identifier(name) => write!(f, "{name}"),
226 Self::String(s) => write!(f, "{s:?}"),
227 Self::Number(n) => write!(f, "{n}"),
228 Self::Computed(expr) => write!(f, "[{expr}]"),
229 Self::Private(p) => write!(f, "{p}"),
230 }
231 }
232}
233
234#[derive(Debug, Clone, PartialEq, Eq)]
236pub enum ObjectMember {
237 Property {
239 key: PropertyKey,
241 value: Expression,
243 kind: ObjectPropertyKind,
246 computed: bool,
248 shorthand: bool,
250 },
251 Spread {
253 argument: Expression,
255 },
256}
257
258#[derive(Debug, Clone, Copy, PartialEq, Eq)]
260pub enum ObjectPropertyKind {
261 Init,
263 Get,
265 Set,
267 Method,
269}
270
271impl std::fmt::Display for ExpressionKind {
272 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
273 match self {
274 Self::This => f.write_str("this"),
275 Self::Super => f.write_str("super"),
276 Self::Identifier(id) => write!(f, "{id}"),
277 Self::PrivateIdentifier(id) => write!(f, "{id}"),
278 Self::Literal(lit) => write!(f, "{lit}"),
279 Self::Template {
280 quasis,
281 expressions,
282 } => write_template(f, None, quasis, expressions),
283 Self::TaggedTemplate {
284 tag,
285 quasis,
286 expressions,
287 } => write_template(f, Some(tag), quasis, expressions),
288 Self::Array { elements } => write_array(f, elements),
289 Self::Object { properties } => write_object(f, properties),
290 Self::Member {
291 object,
292 property,
293 optional,
294 } => write_member(f, object, property, *optional),
295 Self::Call {
296 callee,
297 arguments,
298 optional,
299 } => write_call(f, callee, arguments, *optional),
300 Self::New { callee, arguments } => write_new(f, callee, arguments),
301 Self::Update {
302 operator,
303 argument,
304 prefix,
305 } => write_update(f, *operator, argument, *prefix),
306 Self::Unary { operator, argument } => write!(f, "({operator} {argument})"),
307 Self::Binary {
308 operator,
309 left,
310 right,
311 } => write!(f, "({left} {operator} {right})"),
312 Self::Logical {
313 operator,
314 left,
315 right,
316 } => write!(f, "({left} {operator} {right})"),
317 Self::Conditional {
318 test,
319 consequent,
320 alternate,
321 } => write!(f, "({test} ? {consequent} : {alternate})"),
322 Self::Assignment {
323 operator,
324 left,
325 right,
326 } => write!(f, "({left} {operator} {right})"),
327 Self::Sequence { expressions } => write_sequence(f, expressions),
328 Self::Spread { argument } => write!(f, "...{argument}"),
329 Self::ArrowFunction(arrow) => write!(f, "{arrow}"),
330 Self::FunctionExpression(func) => write!(f, "{func}"),
331 Self::ClassExpression(class) => write!(f, "{class}"),
332 Self::Yield { argument, delegate } => write_yield(f, argument.as_deref(), *delegate),
333 Self::Await { argument } => write!(f, "(await {argument})"),
334 Self::Chain { expression } => write!(f, "{expression}"),
335 Self::ImportExpression { source, options } => {
336 write_import_expression(f, source, options.as_deref())
337 }
338 Self::MetaProperty { meta, property } => write!(f, "{meta}.{property}"),
339 Self::Parenthesized { expression } => write!(f, "({expression})"),
340 }
341 }
342}
343
344fn write_template(
345 f: &mut std::fmt::Formatter<'_>,
346 tag: Option<&Expression>,
347 quasis: &[String],
348 expressions: &[Expression],
349) -> std::fmt::Result {
350 if let Some(tag) = tag {
351 write!(f, "{tag}")?;
352 }
353 f.write_str("`")?;
354 let pieces: String = quasis
355 .iter()
356 .enumerate()
357 .map(|(i, quasi)| {
358 expressions
359 .get(i)
360 .map_or_else(|| quasi.clone(), |expr| format!("{quasi}${{{expr}}}"))
361 })
362 .collect();
363 f.write_str(&pieces)?;
364 f.write_str("`")
365}
366
367fn write_array(
368 f: &mut std::fmt::Formatter<'_>,
369 elements: &[Option<Expression>],
370) -> std::fmt::Result {
371 let body = elements
372 .iter()
373 .map(|e| {
374 e.as_ref()
375 .map_or_else(String::new, |expr| format!("{expr}"))
376 })
377 .collect::<Vec<_>>()
378 .join(", ");
379 write!(f, "[{body}]")
380}
381
382fn write_object(f: &mut std::fmt::Formatter<'_>, properties: &[ObjectMember]) -> std::fmt::Result {
383 let body = properties
384 .iter()
385 .map(|m| format!("{m}"))
386 .collect::<Vec<_>>()
387 .join(", ");
388 write!(f, "{{{body}}}")
389}
390
391fn write_member(
392 f: &mut std::fmt::Formatter<'_>,
393 object: &Expression,
394 property: &MemberProperty,
395 optional: bool,
396) -> std::fmt::Result {
397 let connector = if optional { "?." } else { "" };
398 match property {
399 MemberProperty::Identifier(name) => write!(f, "{object}{connector}.{name}"),
400 MemberProperty::Computed(expr) => write!(f, "{object}{connector}[{expr}]"),
401 MemberProperty::Private(p) => write!(f, "{object}{connector}.{p}"),
402 }
403}
404
405fn write_call(
406 f: &mut std::fmt::Formatter<'_>,
407 callee: &Expression,
408 arguments: &[Expression],
409 optional: bool,
410) -> std::fmt::Result {
411 let args = arguments
412 .iter()
413 .map(|a| format!("{a}"))
414 .collect::<Vec<_>>()
415 .join(", ");
416 let connector = if optional { "?." } else { "" };
417 write!(f, "{callee}{connector}({args})")
418}
419
420fn write_new(
421 f: &mut std::fmt::Formatter<'_>,
422 callee: &Expression,
423 arguments: &[Expression],
424) -> std::fmt::Result {
425 let args = arguments
426 .iter()
427 .map(|a| format!("{a}"))
428 .collect::<Vec<_>>()
429 .join(", ");
430 write!(f, "(new {callee}({args}))")
431}
432
433fn write_update(
434 f: &mut std::fmt::Formatter<'_>,
435 operator: UpdateOperator,
436 argument: &Expression,
437 prefix: bool,
438) -> std::fmt::Result {
439 if prefix {
440 write!(f, "({operator}{argument})")
441 } else {
442 write!(f, "({argument}{operator})")
443 }
444}
445
446fn write_sequence(f: &mut std::fmt::Formatter<'_>, expressions: &[Expression]) -> std::fmt::Result {
447 let body = expressions
448 .iter()
449 .map(|e| format!("{e}"))
450 .collect::<Vec<_>>()
451 .join(", ");
452 write!(f, "({body})")
453}
454
455fn write_yield(
456 f: &mut std::fmt::Formatter<'_>,
457 argument: Option<&Expression>,
458 delegate: bool,
459) -> std::fmt::Result {
460 let star = if delegate { "*" } else { "" };
461 match argument {
462 Some(arg) => write!(f, "(yield{star} {arg})"),
463 None => write!(f, "(yield{star})"),
464 }
465}
466
467fn write_import_expression(
468 f: &mut std::fmt::Formatter<'_>,
469 source: &Expression,
470 options: Option<&Expression>,
471) -> std::fmt::Result {
472 match options {
473 Some(opts) => write!(f, "import({source}, {opts})"),
474 None => write!(f, "import({source})"),
475 }
476}
477
478impl std::fmt::Display for ObjectMember {
479 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
480 match self {
481 Self::Property {
482 key,
483 value,
484 kind,
485 computed,
486 shorthand,
487 } => write_object_member_property(f, key, value, *kind, *computed, *shorthand),
488 Self::Spread { argument } => write!(f, "...{argument}"),
489 }
490 }
491}
492
493fn write_object_member_property(
494 f: &mut std::fmt::Formatter<'_>,
495 key: &PropertyKey,
496 value: &Expression,
497 kind: ObjectPropertyKind,
498 computed: bool,
499 shorthand: bool,
500) -> std::fmt::Result {
501 let key_repr = if computed {
502 format!("[{key}]")
503 } else {
504 format!("{key}")
505 };
506 match kind {
507 ObjectPropertyKind::Init if shorthand => write!(f, "{key_repr}"),
508 ObjectPropertyKind::Init => write!(f, "{key_repr}: {value}"),
509 ObjectPropertyKind::Get => write!(f, "get {key_repr}() {{ ... }}"),
510 ObjectPropertyKind::Set => write!(f, "set {key_repr}(v) {{ ... }}"),
511 ObjectPropertyKind::Method => write!(f, "{key_repr}() {{ ... }}"),
512 }
513}