mustardscript 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/Cargo.lock +1579 -0
  2. package/Cargo.toml +40 -0
  3. package/LICENSE +201 -0
  4. package/README.md +828 -0
  5. package/SECURITY.md +34 -0
  6. package/crates/mustard/Cargo.toml +31 -0
  7. package/crates/mustard/src/cancellation.rs +28 -0
  8. package/crates/mustard/src/diagnostic.rs +145 -0
  9. package/crates/mustard/src/ir.rs +435 -0
  10. package/crates/mustard/src/lib.rs +21 -0
  11. package/crates/mustard/src/limits.rs +22 -0
  12. package/crates/mustard/src/parser/expressions.rs +723 -0
  13. package/crates/mustard/src/parser/mod.rs +115 -0
  14. package/crates/mustard/src/parser/operators.rs +105 -0
  15. package/crates/mustard/src/parser/patterns.rs +123 -0
  16. package/crates/mustard/src/parser/scope.rs +107 -0
  17. package/crates/mustard/src/parser/statements.rs +298 -0
  18. package/crates/mustard/src/parser/tests/acceptance.rs +339 -0
  19. package/crates/mustard/src/parser/tests/mod.rs +2 -0
  20. package/crates/mustard/src/parser/tests/rejections.rs +107 -0
  21. package/crates/mustard/src/runtime/accounting.rs +613 -0
  22. package/crates/mustard/src/runtime/api.rs +192 -0
  23. package/crates/mustard/src/runtime/async_runtime/mod.rs +5 -0
  24. package/crates/mustard/src/runtime/async_runtime/promises.rs +246 -0
  25. package/crates/mustard/src/runtime/async_runtime/reactions.rs +400 -0
  26. package/crates/mustard/src/runtime/async_runtime/scheduler.rs +224 -0
  27. package/crates/mustard/src/runtime/builtins/arrays.rs +1205 -0
  28. package/crates/mustard/src/runtime/builtins/collections.rs +573 -0
  29. package/crates/mustard/src/runtime/builtins/install.rs +501 -0
  30. package/crates/mustard/src/runtime/builtins/intl.rs +553 -0
  31. package/crates/mustard/src/runtime/builtins/mod.rs +25 -0
  32. package/crates/mustard/src/runtime/builtins/objects.rs +405 -0
  33. package/crates/mustard/src/runtime/builtins/primitives.rs +859 -0
  34. package/crates/mustard/src/runtime/builtins/promises.rs +335 -0
  35. package/crates/mustard/src/runtime/builtins/regexp.rs +356 -0
  36. package/crates/mustard/src/runtime/builtins/strings.rs +803 -0
  37. package/crates/mustard/src/runtime/builtins/support.rs +561 -0
  38. package/crates/mustard/src/runtime/bytecode.rs +123 -0
  39. package/crates/mustard/src/runtime/compiler/assignments.rs +690 -0
  40. package/crates/mustard/src/runtime/compiler/bindings.rs +92 -0
  41. package/crates/mustard/src/runtime/compiler/context.rs +46 -0
  42. package/crates/mustard/src/runtime/compiler/control.rs +342 -0
  43. package/crates/mustard/src/runtime/compiler/expressions.rs +372 -0
  44. package/crates/mustard/src/runtime/compiler/mod.rs +173 -0
  45. package/crates/mustard/src/runtime/compiler/statements.rs +459 -0
  46. package/crates/mustard/src/runtime/conversions/boundary.rs +293 -0
  47. package/crates/mustard/src/runtime/conversions/coercions.rs +217 -0
  48. package/crates/mustard/src/runtime/conversions/errors.rs +118 -0
  49. package/crates/mustard/src/runtime/conversions/mod.rs +14 -0
  50. package/crates/mustard/src/runtime/conversions/operators.rs +334 -0
  51. package/crates/mustard/src/runtime/env.rs +355 -0
  52. package/crates/mustard/src/runtime/exceptions.rs +377 -0
  53. package/crates/mustard/src/runtime/gc.rs +595 -0
  54. package/crates/mustard/src/runtime/mod.rs +318 -0
  55. package/crates/mustard/src/runtime/properties.rs +1762 -0
  56. package/crates/mustard/src/runtime/serialization.rs +127 -0
  57. package/crates/mustard/src/runtime/shared.rs +108 -0
  58. package/crates/mustard/src/runtime/snapshot_validation_tests.rs +93 -0
  59. package/crates/mustard/src/runtime/state.rs +652 -0
  60. package/crates/mustard/src/runtime/tests/async_host.rs +104 -0
  61. package/crates/mustard/src/runtime/tests/collections.rs +50 -0
  62. package/crates/mustard/src/runtime/tests/diagnostics.rs +36 -0
  63. package/crates/mustard/src/runtime/tests/exceptions.rs +122 -0
  64. package/crates/mustard/src/runtime/tests/execution.rs +553 -0
  65. package/crates/mustard/src/runtime/tests/gc.rs +533 -0
  66. package/crates/mustard/src/runtime/tests/mod.rs +56 -0
  67. package/crates/mustard/src/runtime/tests/serialization.rs +170 -0
  68. package/crates/mustard/src/runtime/validation/bytecode.rs +484 -0
  69. package/crates/mustard/src/runtime/validation/mod.rs +14 -0
  70. package/crates/mustard/src/runtime/validation/policy.rs +94 -0
  71. package/crates/mustard/src/runtime/validation/snapshot.rs +406 -0
  72. package/crates/mustard/src/runtime/validation/walk.rs +206 -0
  73. package/crates/mustard/src/runtime/vm.rs +1016 -0
  74. package/crates/mustard/src/span.rs +22 -0
  75. package/crates/mustard/src/structured.rs +107 -0
  76. package/crates/mustard-bridge/Cargo.toml +17 -0
  77. package/crates/mustard-bridge/src/codec.rs +46 -0
  78. package/crates/mustard-bridge/src/dto.rs +99 -0
  79. package/crates/mustard-bridge/src/lib.rs +12 -0
  80. package/crates/mustard-bridge/src/operations.rs +142 -0
  81. package/crates/mustard-node/Cargo.toml +24 -0
  82. package/crates/mustard-node/build.rs +3 -0
  83. package/crates/mustard-node/src/lib.rs +236 -0
  84. package/crates/mustard-sidecar/Cargo.toml +21 -0
  85. package/crates/mustard-sidecar/src/lib.rs +134 -0
  86. package/crates/mustard-sidecar/src/main.rs +36 -0
  87. package/dist/index.js +20 -0
  88. package/dist/install.js +117 -0
  89. package/dist/lib/cancellation.js +124 -0
  90. package/dist/lib/errors.js +46 -0
  91. package/dist/lib/executor.js +555 -0
  92. package/dist/lib/policy.js +292 -0
  93. package/dist/lib/progress.js +356 -0
  94. package/dist/lib/runtime.js +109 -0
  95. package/dist/lib/structured.js +286 -0
  96. package/dist/native-loader.js +227 -0
  97. package/index.d.ts +23 -0
  98. package/mustard.d.ts +220 -0
  99. package/package.json +97 -0
@@ -0,0 +1,723 @@
1
+ use super::*;
2
+
3
+ impl<'a> Lowerer<'a> {
4
+ pub(super) fn lower_function(
5
+ &mut self,
6
+ function: &Function<'a>,
7
+ is_arrow: bool,
8
+ ) -> Option<FunctionExpr> {
9
+ if function.generator {
10
+ self.unsupported(
11
+ "generators are not supported in v1",
12
+ Some(function.span.into()),
13
+ );
14
+ return None;
15
+ }
16
+ let Some(body) = function.body.as_ref() else {
17
+ self.unsupported(
18
+ "functions without bodies are not supported",
19
+ Some(function.span.into()),
20
+ );
21
+ return None;
22
+ };
23
+ let (params, rest, param_init, length) = self.lower_function_params(&function.params)?;
24
+ self.push_scope();
25
+ for statement in &param_init {
26
+ if let Stmt::VariableDecl { declarators, .. } = statement {
27
+ for declarator in declarators {
28
+ self.collect_ir_pattern_bindings(&declarator.pattern);
29
+ }
30
+ }
31
+ }
32
+ self.predeclare_block(&body.statements);
33
+ let lowered = body
34
+ .statements
35
+ .iter()
36
+ .filter_map(|statement| self.lower_stmt(statement))
37
+ .collect();
38
+ self.pop_scope();
39
+ Some(FunctionExpr {
40
+ span: function.span.into(),
41
+ name: function.id.as_ref().map(|id| id.name.as_str().to_string()),
42
+ length,
43
+ display_source: self.source_snippet(function.span.into()),
44
+ params,
45
+ rest,
46
+ param_init,
47
+ body: lowered,
48
+ is_async: function.r#async,
49
+ is_arrow,
50
+ })
51
+ }
52
+
53
+ pub(super) fn lower_arrow_function(
54
+ &mut self,
55
+ function: &ArrowFunctionExpression<'a>,
56
+ ) -> Option<FunctionExpr> {
57
+ let (params, rest, param_init, length) = self.lower_function_params(&function.params)?;
58
+ self.push_scope();
59
+ for statement in &param_init {
60
+ if let Stmt::VariableDecl { declarators, .. } = statement {
61
+ for declarator in declarators {
62
+ self.collect_ir_pattern_bindings(&declarator.pattern);
63
+ }
64
+ }
65
+ }
66
+ self.predeclare_block(&function.body.statements);
67
+ let body = if function.expression {
68
+ if function.body.statements.len() == 1 {
69
+ match &function.body.statements[0] {
70
+ Statement::ExpressionStatement(statement) => vec![Stmt::Return {
71
+ span: statement.span.into(),
72
+ value: Some(self.lower_expr(&statement.expression)?),
73
+ }],
74
+ statement => vec![self.lower_stmt(statement)?],
75
+ }
76
+ } else {
77
+ function
78
+ .body
79
+ .statements
80
+ .iter()
81
+ .filter_map(|statement| self.lower_stmt(statement))
82
+ .collect()
83
+ }
84
+ } else {
85
+ function
86
+ .body
87
+ .statements
88
+ .iter()
89
+ .filter_map(|statement| self.lower_stmt(statement))
90
+ .collect()
91
+ };
92
+ self.pop_scope();
93
+ Some(FunctionExpr {
94
+ span: function.span.into(),
95
+ name: None,
96
+ length,
97
+ display_source: self.source_snippet(function.span.into()),
98
+ params,
99
+ rest,
100
+ param_init,
101
+ body,
102
+ is_async: function.r#async,
103
+ is_arrow: true,
104
+ })
105
+ }
106
+
107
+ pub(super) fn lower_for_init_expr(&mut self, init: &ForStatementInit<'a>) -> Option<Expr> {
108
+ match init {
109
+ ForStatementInit::VariableDeclaration(_) => None,
110
+ expression => self.lower_expr(expression.to_expression()),
111
+ }
112
+ }
113
+
114
+ fn lower_object_property_key(
115
+ &mut self,
116
+ key: &PropertyKey<'a>,
117
+ computed: bool,
118
+ ) -> Option<crate::ir::ObjectPropertyKey> {
119
+ if computed {
120
+ return Some(crate::ir::ObjectPropertyKey::Computed(Box::new(
121
+ self.lower_expr(key.to_expression())?,
122
+ )));
123
+ }
124
+
125
+ Some(crate::ir::ObjectPropertyKey::Static(
126
+ self.lower_property_name(key)?,
127
+ ))
128
+ }
129
+
130
+ fn object_method_name(key: &crate::ir::ObjectPropertyKey) -> Option<String> {
131
+ match key {
132
+ crate::ir::ObjectPropertyKey::Static(PropertyName::Identifier(name))
133
+ | crate::ir::ObjectPropertyKey::Static(PropertyName::String(name)) => {
134
+ Some(name.clone())
135
+ }
136
+ crate::ir::ObjectPropertyKey::Static(PropertyName::Number(number)) => {
137
+ Some(number.to_string())
138
+ }
139
+ crate::ir::ObjectPropertyKey::Computed(_) => None,
140
+ }
141
+ }
142
+
143
+ fn lower_object_literal_property(
144
+ &mut self,
145
+ property: &oxc_ast::ast::ObjectProperty<'a>,
146
+ ) -> Option<crate::ir::ObjectProperty> {
147
+ if property.kind != PropertyKind::Init {
148
+ self.unsupported(
149
+ "object literal accessors are not supported in v1",
150
+ Some(property.span.into()),
151
+ );
152
+ return None;
153
+ }
154
+
155
+ let key = self.lower_object_property_key(&property.key, property.computed)?;
156
+ let mut value = self.lower_expr(&property.value)?;
157
+ if let (Some(name), Expr::Function(function)) = (Self::object_method_name(&key), &mut value)
158
+ && function.name.is_none()
159
+ {
160
+ function.name = Some(name);
161
+ }
162
+
163
+ Some(crate::ir::ObjectProperty::Property {
164
+ span: property.span.into(),
165
+ key,
166
+ value,
167
+ })
168
+ }
169
+
170
+ pub(super) fn lower_expr(&mut self, expression: &Expression<'a>) -> Option<Expr> {
171
+ match expression {
172
+ Expression::BooleanLiteral(literal) => Some(Expr::Bool {
173
+ span: literal.span.into(),
174
+ value: literal.value,
175
+ }),
176
+ Expression::NullLiteral(literal) => Some(Expr::Null {
177
+ span: literal.span.into(),
178
+ }),
179
+ Expression::NumericLiteral(literal) => Some(Expr::Number {
180
+ span: literal.span.into(),
181
+ value: literal.value,
182
+ }),
183
+ Expression::BigIntLiteral(literal) => Some(Expr::BigInt {
184
+ span: literal.span.into(),
185
+ value: literal.value.as_str().to_string(),
186
+ }),
187
+ Expression::StringLiteral(literal) => Some(Expr::String {
188
+ span: literal.span.into(),
189
+ value: literal.value.as_str().to_string(),
190
+ }),
191
+ Expression::TemplateLiteral(literal) => Some(Expr::Template {
192
+ span: literal.span.into(),
193
+ quasis: literal
194
+ .quasis
195
+ .iter()
196
+ .map(|quasi| {
197
+ quasi
198
+ .value
199
+ .cooked
200
+ .as_ref()
201
+ .unwrap_or(&quasi.value.raw)
202
+ .as_str()
203
+ .to_string()
204
+ })
205
+ .collect(),
206
+ expressions: literal
207
+ .expressions
208
+ .iter()
209
+ .filter_map(|expr| self.lower_expr(expr))
210
+ .collect(),
211
+ }),
212
+ Expression::Identifier(identifier) => {
213
+ let name = identifier.name.as_str();
214
+ if !self.is_bound(name) && FORBIDDEN_AMBIENT_GLOBALS.contains(&name) {
215
+ self.unsupported(
216
+ format!("free reference to forbidden ambient global `{name}`"),
217
+ Some(identifier.span.into()),
218
+ );
219
+ return None;
220
+ }
221
+ if name == "undefined" {
222
+ return Some(Expr::Undefined {
223
+ span: identifier.span.into(),
224
+ });
225
+ }
226
+ Some(Expr::Identifier {
227
+ span: identifier.span.into(),
228
+ name: name.to_string(),
229
+ })
230
+ }
231
+ Expression::ThisExpression(this) => Some(Expr::This {
232
+ span: this.span.into(),
233
+ }),
234
+ Expression::ArrayExpression(array) => {
235
+ let mut elements = Vec::with_capacity(array.elements.len());
236
+ for element in &array.elements {
237
+ match element {
238
+ ArrayExpressionElement::SpreadElement(spread) => {
239
+ elements.push(crate::ir::ArrayElement::Spread {
240
+ span: spread.span.into(),
241
+ value: self.lower_expr(&spread.argument)?,
242
+ });
243
+ }
244
+ ArrayExpressionElement::Elision(elision) => {
245
+ elements.push(crate::ir::ArrayElement::Hole {
246
+ span: elision.span.into(),
247
+ });
248
+ }
249
+ element => elements.push(crate::ir::ArrayElement::Value(
250
+ self.lower_expr(element.to_expression())?,
251
+ )),
252
+ }
253
+ }
254
+ Some(Expr::Array {
255
+ span: array.span.into(),
256
+ elements,
257
+ })
258
+ }
259
+ Expression::ObjectExpression(object) => Some(Expr::Object {
260
+ span: object.span.into(),
261
+ properties: object
262
+ .properties
263
+ .iter()
264
+ .filter_map(|property| match property {
265
+ ObjectPropertyKind::ObjectProperty(property) => {
266
+ self.lower_object_literal_property(property)
267
+ }
268
+ ObjectPropertyKind::SpreadProperty(property) => {
269
+ Some(crate::ir::ObjectProperty::Spread {
270
+ span: property.span.into(),
271
+ value: self.lower_expr(&property.argument)?,
272
+ })
273
+ }
274
+ })
275
+ .collect(),
276
+ }),
277
+ Expression::ArrowFunctionExpression(function) => Some(Expr::Function(Box::new(
278
+ self.lower_arrow_function(function)?,
279
+ ))),
280
+ Expression::FunctionExpression(function) => Some(Expr::Function(Box::new(
281
+ self.lower_function(function, false)?,
282
+ ))),
283
+ Expression::UnaryExpression(expression) => Some(Expr::Unary {
284
+ span: expression.span.into(),
285
+ operator: self.lower_unary_op(expression.operator, expression.span)?,
286
+ argument: Box::new(self.lower_expr(&expression.argument)?),
287
+ }),
288
+ Expression::BinaryExpression(expression) => Some(Expr::Binary {
289
+ span: expression.span.into(),
290
+ operator: self.lower_binary_op(expression.operator, expression.span)?,
291
+ left: Box::new(self.lower_expr(&expression.left)?),
292
+ right: Box::new(self.lower_expr(&expression.right)?),
293
+ }),
294
+ Expression::SequenceExpression(expression) => {
295
+ let mut expressions = Vec::with_capacity(expression.expressions.len());
296
+ for entry in &expression.expressions {
297
+ expressions.push(self.lower_expr(entry)?);
298
+ }
299
+ Some(Expr::Sequence {
300
+ span: expression.span.into(),
301
+ expressions,
302
+ })
303
+ }
304
+ Expression::LogicalExpression(expression) => Some(Expr::Logical {
305
+ span: expression.span.into(),
306
+ operator: self.lower_logical_op(expression.operator, expression.span)?,
307
+ left: Box::new(self.lower_expr(&expression.left)?),
308
+ right: Box::new(self.lower_expr(&expression.right)?),
309
+ }),
310
+ Expression::ConditionalExpression(expression) => Some(Expr::Conditional {
311
+ span: expression.span.into(),
312
+ test: Box::new(self.lower_expr(&expression.test)?),
313
+ consequent: Box::new(self.lower_expr(&expression.consequent)?),
314
+ alternate: Box::new(self.lower_expr(&expression.alternate)?),
315
+ }),
316
+ Expression::AssignmentExpression(expression) => Some(Expr::Assignment {
317
+ span: expression.span.into(),
318
+ target: Box::new(self.lower_assignment_target(&expression.left)?),
319
+ operator: self.lower_assign_op(expression.operator, expression.span)?,
320
+ value: Box::new(self.lower_expr(&expression.right)?),
321
+ }),
322
+ Expression::CallExpression(expression) => Some(Expr::Call {
323
+ span: expression.span.into(),
324
+ callee: Box::new(self.lower_expr(&expression.callee)?),
325
+ arguments: self.lower_call_args(&expression.arguments)?,
326
+ optional: expression.optional,
327
+ }),
328
+ Expression::ChainExpression(expression) => match &expression.expression {
329
+ ChainElement::CallExpression(call) => Some(Expr::Call {
330
+ span: call.span.into(),
331
+ callee: Box::new(self.lower_expr(&call.callee)?),
332
+ arguments: self.lower_call_args(&call.arguments)?,
333
+ optional: true,
334
+ }),
335
+ ChainElement::ComputedMemberExpression(member) => Some(Expr::Member {
336
+ span: member.span.into(),
337
+ object: Box::new(self.lower_expr(&member.object)?),
338
+ property: MemberProperty::Computed(Box::new(
339
+ self.lower_expr(&member.expression)?,
340
+ )),
341
+ optional: true,
342
+ }),
343
+ ChainElement::StaticMemberExpression(member) => Some(Expr::Member {
344
+ span: member.span.into(),
345
+ object: Box::new(self.lower_expr(&member.object)?),
346
+ property: MemberProperty::Static(PropertyName::Identifier(
347
+ member.property.name.as_str().to_string(),
348
+ )),
349
+ optional: true,
350
+ }),
351
+ ChainElement::PrivateFieldExpression(member) => {
352
+ self.unsupported(
353
+ "private fields are not supported in v1",
354
+ Some(member.span.into()),
355
+ );
356
+ None
357
+ }
358
+ ChainElement::TSNonNullExpression(expression) => {
359
+ self.lower_expr(&expression.expression)
360
+ }
361
+ },
362
+ Expression::ComputedMemberExpression(member) => Some(Expr::Member {
363
+ span: member.span.into(),
364
+ object: Box::new(self.lower_expr(&member.object)?),
365
+ property: MemberProperty::Computed(Box::new(self.lower_expr(&member.expression)?)),
366
+ optional: member.optional,
367
+ }),
368
+ Expression::StaticMemberExpression(member) => Some(Expr::Member {
369
+ span: member.span.into(),
370
+ object: Box::new(self.lower_expr(&member.object)?),
371
+ property: MemberProperty::Static(PropertyName::Identifier(
372
+ member.property.name.as_str().to_string(),
373
+ )),
374
+ optional: member.optional,
375
+ }),
376
+ Expression::AwaitExpression(expression) => Some(Expr::Await {
377
+ span: expression.span.into(),
378
+ value: Box::new(self.lower_expr(&expression.argument)?),
379
+ }),
380
+ Expression::NewExpression(expression) => Some(Expr::New {
381
+ span: expression.span.into(),
382
+ callee: Box::new(self.lower_expr(&expression.callee)?),
383
+ arguments: self.lower_call_args(&expression.arguments)?,
384
+ }),
385
+ Expression::ParenthesizedExpression(expression) => {
386
+ self.lower_expr(&expression.expression)
387
+ }
388
+ Expression::MetaProperty(property) => {
389
+ self.unsupported(
390
+ "meta properties are not supported",
391
+ Some(property.span.into()),
392
+ );
393
+ None
394
+ }
395
+ Expression::ImportExpression(expression) => {
396
+ self.unsupported(
397
+ "dynamic import() is not supported",
398
+ Some(expression.span.into()),
399
+ );
400
+ None
401
+ }
402
+ Expression::RegExpLiteral(expression) => Some(Expr::RegExp {
403
+ span: expression.span.into(),
404
+ pattern: expression.regex.pattern.text.as_str().to_string(),
405
+ flags: expression.regex.flags.to_inline_string().to_string(),
406
+ }),
407
+ Expression::Super(expression) => {
408
+ self.unsupported("super is not supported in v1", Some(expression.span.into()));
409
+ None
410
+ }
411
+ Expression::PrivateFieldExpression(expression) => {
412
+ self.unsupported(
413
+ "private fields are not supported in v1",
414
+ Some(expression.span.into()),
415
+ );
416
+ None
417
+ }
418
+ Expression::UpdateExpression(expression) => Some(Expr::Update {
419
+ span: expression.span.into(),
420
+ target: Box::new(self.lower_simple_assignment_target(&expression.argument)?),
421
+ operator: match expression.operator {
422
+ UpdateOperator::Increment => UpdateOp::Increment,
423
+ UpdateOperator::Decrement => UpdateOp::Decrement,
424
+ },
425
+ prefix: expression.prefix,
426
+ }),
427
+ Expression::YieldExpression(expression) => {
428
+ self.unsupported("yield is not supported in v1", Some(expression.span.into()));
429
+ None
430
+ }
431
+ Expression::TaggedTemplateExpression(expression) => {
432
+ self.unsupported(
433
+ "tagged templates are not supported in v1",
434
+ Some(expression.span.into()),
435
+ );
436
+ None
437
+ }
438
+ Expression::ClassExpression(expression) => {
439
+ self.unsupported(
440
+ "classes are not supported in v1",
441
+ Some(expression.span.into()),
442
+ );
443
+ None
444
+ }
445
+ Expression::JSXElement(_)
446
+ | Expression::JSXFragment(_)
447
+ | Expression::TSAsExpression(_)
448
+ | Expression::TSSatisfiesExpression(_)
449
+ | Expression::TSInstantiationExpression(_)
450
+ | Expression::TSNonNullExpression(_)
451
+ | Expression::TSTypeAssertion(_)
452
+ | Expression::PrivateInExpression(_) => {
453
+ self.unsupported(
454
+ "unsupported expression form in v1",
455
+ Some(expression.span().into()),
456
+ );
457
+ None
458
+ }
459
+ _ => {
460
+ self.unsupported(
461
+ "unsupported expression form in v1",
462
+ Some(expression.span().into()),
463
+ );
464
+ None
465
+ }
466
+ }
467
+ }
468
+
469
+ pub(super) fn lower_call_args(
470
+ &mut self,
471
+ args: &[Argument<'a>],
472
+ ) -> Option<Vec<crate::ir::CallArgument>> {
473
+ let mut lowered = Vec::with_capacity(args.len());
474
+ for arg in args {
475
+ match arg {
476
+ Argument::SpreadElement(spread) => {
477
+ lowered.push(crate::ir::CallArgument::Spread {
478
+ span: spread.span.into(),
479
+ value: self.lower_expr(&spread.argument)?,
480
+ });
481
+ }
482
+ expression => lowered.push(crate::ir::CallArgument::Value(
483
+ self.lower_expr(expression.to_expression())?,
484
+ )),
485
+ }
486
+ }
487
+ Some(lowered)
488
+ }
489
+
490
+ pub(super) fn lower_assignment_target(
491
+ &mut self,
492
+ target: &AssignmentTarget<'a>,
493
+ ) -> Option<AssignTarget> {
494
+ match target {
495
+ AssignmentTarget::AssignmentTargetIdentifier(identifier) => {
496
+ Some(AssignTarget::Identifier {
497
+ span: identifier.span.into(),
498
+ name: identifier.name.as_str().to_string(),
499
+ })
500
+ }
501
+ AssignmentTarget::ComputedMemberExpression(member) => Some(AssignTarget::Member {
502
+ span: member.span.into(),
503
+ object: Box::new(self.lower_expr(&member.object)?),
504
+ property: MemberProperty::Computed(Box::new(self.lower_expr(&member.expression)?)),
505
+ optional: member.optional,
506
+ }),
507
+ AssignmentTarget::StaticMemberExpression(member) => Some(AssignTarget::Member {
508
+ span: member.span.into(),
509
+ object: Box::new(self.lower_expr(&member.object)?),
510
+ property: MemberProperty::Static(PropertyName::Identifier(
511
+ member.property.name.as_str().to_string(),
512
+ )),
513
+ optional: member.optional,
514
+ }),
515
+ AssignmentTarget::PrivateFieldExpression(expression) => {
516
+ self.unsupported(
517
+ "private fields are not supported in v1",
518
+ Some(expression.span.into()),
519
+ );
520
+ None
521
+ }
522
+ AssignmentTarget::ArrayAssignmentTarget(target) => {
523
+ self.lower_array_assignment_target(target)
524
+ }
525
+ AssignmentTarget::ObjectAssignmentTarget(target) => {
526
+ self.lower_object_assignment_target(target)
527
+ }
528
+ _ => {
529
+ self.unsupported(
530
+ "unsupported assignment target in v1",
531
+ Some(target.span().into()),
532
+ );
533
+ None
534
+ }
535
+ }
536
+ }
537
+
538
+ pub(super) fn lower_for_of_assignment_target(
539
+ &mut self,
540
+ target: &ForStatementLeft<'a>,
541
+ ) -> Option<AssignTarget> {
542
+ match target {
543
+ ForStatementLeft::AssignmentTargetIdentifier(identifier) => {
544
+ Some(AssignTarget::Identifier {
545
+ span: identifier.span.into(),
546
+ name: identifier.name.as_str().to_string(),
547
+ })
548
+ }
549
+ ForStatementLeft::ComputedMemberExpression(member) => Some(AssignTarget::Member {
550
+ span: member.span.into(),
551
+ object: Box::new(self.lower_expr(&member.object)?),
552
+ property: MemberProperty::Computed(Box::new(self.lower_expr(&member.expression)?)),
553
+ optional: member.optional,
554
+ }),
555
+ ForStatementLeft::StaticMemberExpression(member) => Some(AssignTarget::Member {
556
+ span: member.span.into(),
557
+ object: Box::new(self.lower_expr(&member.object)?),
558
+ property: MemberProperty::Static(PropertyName::Identifier(
559
+ member.property.name.as_str().to_string(),
560
+ )),
561
+ optional: member.optional,
562
+ }),
563
+ ForStatementLeft::PrivateFieldExpression(expression) => {
564
+ self.unsupported(
565
+ "private fields are not supported in v1",
566
+ Some(expression.span.into()),
567
+ );
568
+ None
569
+ }
570
+ ForStatementLeft::ArrayAssignmentTarget(target) => {
571
+ self.lower_array_assignment_target(target)
572
+ }
573
+ ForStatementLeft::ObjectAssignmentTarget(target) => {
574
+ self.lower_object_assignment_target(target)
575
+ }
576
+ _ => {
577
+ self.unsupported(
578
+ "unsupported assignment target in v1",
579
+ Some(target.span().into()),
580
+ );
581
+ None
582
+ }
583
+ }
584
+ }
585
+
586
+ fn lower_simple_assignment_target(
587
+ &mut self,
588
+ target: &SimpleAssignmentTarget<'a>,
589
+ ) -> Option<AssignTarget> {
590
+ match target {
591
+ SimpleAssignmentTarget::AssignmentTargetIdentifier(identifier) => {
592
+ Some(AssignTarget::Identifier {
593
+ span: identifier.span.into(),
594
+ name: identifier.name.as_str().to_string(),
595
+ })
596
+ }
597
+ SimpleAssignmentTarget::ComputedMemberExpression(member) => {
598
+ Some(AssignTarget::Member {
599
+ span: member.span.into(),
600
+ object: Box::new(self.lower_expr(&member.object)?),
601
+ property: MemberProperty::Computed(Box::new(
602
+ self.lower_expr(&member.expression)?,
603
+ )),
604
+ optional: member.optional,
605
+ })
606
+ }
607
+ SimpleAssignmentTarget::StaticMemberExpression(member) => Some(AssignTarget::Member {
608
+ span: member.span.into(),
609
+ object: Box::new(self.lower_expr(&member.object)?),
610
+ property: MemberProperty::Static(PropertyName::Identifier(
611
+ member.property.name.as_str().to_string(),
612
+ )),
613
+ optional: member.optional,
614
+ }),
615
+ SimpleAssignmentTarget::PrivateFieldExpression(expression) => {
616
+ self.unsupported(
617
+ "private fields are not supported in v1",
618
+ Some(expression.span.into()),
619
+ );
620
+ None
621
+ }
622
+ _ => {
623
+ self.unsupported(
624
+ "unsupported assignment target in v1",
625
+ Some(target.span().into()),
626
+ );
627
+ None
628
+ }
629
+ }
630
+ }
631
+
632
+ fn lower_assignment_target_maybe_default(
633
+ &mut self,
634
+ target: &AssignmentTargetMaybeDefault<'a>,
635
+ ) -> Option<AssignTarget> {
636
+ match target {
637
+ AssignmentTargetMaybeDefault::AssignmentTargetWithDefault(target) => {
638
+ Some(AssignTarget::Default {
639
+ span: target.span.into(),
640
+ target: Box::new(self.lower_assignment_target(&target.binding)?),
641
+ default_value: Box::new(self.lower_expr(&target.init)?),
642
+ })
643
+ }
644
+ _ => self.lower_assignment_target(target.to_assignment_target()),
645
+ }
646
+ }
647
+
648
+ fn lower_array_assignment_target(
649
+ &mut self,
650
+ target: &ArrayAssignmentTarget<'a>,
651
+ ) -> Option<AssignTarget> {
652
+ Some(AssignTarget::Array {
653
+ span: target.span.into(),
654
+ elements: target
655
+ .elements
656
+ .iter()
657
+ .map(|element| {
658
+ element
659
+ .as_ref()
660
+ .and_then(|element| self.lower_assignment_target_maybe_default(element))
661
+ })
662
+ .collect(),
663
+ rest: target
664
+ .rest
665
+ .as_ref()
666
+ .and_then(|rest| self.lower_assignment_target(&rest.target))
667
+ .map(Box::new),
668
+ })
669
+ }
670
+
671
+ fn lower_object_assignment_target(
672
+ &mut self,
673
+ target: &ObjectAssignmentTarget<'a>,
674
+ ) -> Option<AssignTarget> {
675
+ Some(AssignTarget::Object {
676
+ span: target.span.into(),
677
+ properties: target
678
+ .properties
679
+ .iter()
680
+ .filter_map(|property| {
681
+ Some(match property {
682
+ AssignmentTargetProperty::AssignmentTargetPropertyIdentifier(property) => {
683
+ crate::ir::AssignTargetProperty {
684
+ span: property.span.into(),
685
+ key: PropertyName::Identifier(
686
+ property.binding.name.as_str().to_string(),
687
+ ),
688
+ value: if let Some(init) = &property.init {
689
+ AssignTarget::Default {
690
+ span: property.span.into(),
691
+ target: Box::new(AssignTarget::Identifier {
692
+ span: property.span.into(),
693
+ name: property.binding.name.as_str().to_string(),
694
+ }),
695
+ default_value: Box::new(self.lower_expr(init)?),
696
+ }
697
+ } else {
698
+ AssignTarget::Identifier {
699
+ span: property.span.into(),
700
+ name: property.binding.name.as_str().to_string(),
701
+ }
702
+ },
703
+ }
704
+ }
705
+ AssignmentTargetProperty::AssignmentTargetPropertyProperty(property) => {
706
+ crate::ir::AssignTargetProperty {
707
+ span: property.span.into(),
708
+ key: self.lower_property_name(&property.name)?,
709
+ value: self
710
+ .lower_assignment_target_maybe_default(&property.binding)?,
711
+ }
712
+ }
713
+ })
714
+ })
715
+ .collect(),
716
+ rest: target
717
+ .rest
718
+ .as_ref()
719
+ .and_then(|rest| self.lower_assignment_target(&rest.target))
720
+ .map(Box::new),
721
+ })
722
+ }
723
+ }