@tishlang/tish 1.6.0 → 1.7.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 (79) hide show
  1. package/Cargo.toml +1 -0
  2. package/bin/tish +0 -0
  3. package/crates/js_to_tish/src/error.rs +2 -8
  4. package/crates/js_to_tish/src/transform/expr.rs +101 -130
  5. package/crates/js_to_tish/src/transform/stmt.rs +25 -22
  6. package/crates/tish/Cargo.toml +1 -1
  7. package/crates/tish/src/cli_help.rs +76 -29
  8. package/crates/tish/src/main.rs +85 -54
  9. package/crates/tish/tests/cargo_example_compile.rs +3 -1
  10. package/crates/tish/tests/integration_test.rs +197 -47
  11. package/crates/tish/tests/run_optimize_stdout_parity.rs +3 -7
  12. package/crates/tish/tests/shortcircuit.rs +19 -4
  13. package/crates/tish_ast/src/ast.rs +12 -14
  14. package/crates/tish_build_utils/src/lib.rs +31 -6
  15. package/crates/tish_builtins/src/array.rs +52 -21
  16. package/crates/tish_builtins/src/construct.rs +2 -8
  17. package/crates/tish_builtins/src/globals.rs +30 -15
  18. package/crates/tish_builtins/src/lib.rs +5 -5
  19. package/crates/tish_builtins/src/math.rs +5 -3
  20. package/crates/tish_builtins/src/string.rs +71 -19
  21. package/crates/tish_bytecode/src/chunk.rs +0 -1
  22. package/crates/tish_bytecode/src/compiler.rs +164 -60
  23. package/crates/tish_bytecode/src/opcode.rs +13 -4
  24. package/crates/tish_bytecode/src/peephole.rs +2 -2
  25. package/crates/tish_compile/src/codegen.rs +921 -299
  26. package/crates/tish_compile/src/infer.rs +69 -19
  27. package/crates/tish_compile/src/lib.rs +15 -5
  28. package/crates/tish_compile/src/resolve.rs +112 -69
  29. package/crates/tish_compile/src/types.rs +10 -14
  30. package/crates/tish_compile_js/src/codegen.rs +34 -13
  31. package/crates/tish_compile_js/src/tests_jsx.rs +30 -6
  32. package/crates/tish_compiler_wasm/src/lib.rs +16 -13
  33. package/crates/tish_compiler_wasm/src/resolve_virtual.rs +39 -48
  34. package/crates/tish_core/src/json.rs +5 -3
  35. package/crates/tish_core/src/lib.rs +1 -1
  36. package/crates/tish_core/src/uri.rs +9 -6
  37. package/crates/tish_core/src/value.rs +92 -28
  38. package/crates/tish_cranelift/src/link.rs +6 -9
  39. package/crates/tish_cranelift/src/lower.rs +14 -8
  40. package/crates/tish_eval/src/eval.rs +389 -142
  41. package/crates/tish_eval/src/lib.rs +10 -6
  42. package/crates/tish_eval/src/natives.rs +95 -38
  43. package/crates/tish_eval/src/promise.rs +14 -8
  44. package/crates/tish_eval/src/timers.rs +28 -19
  45. package/crates/tish_eval/src/value.rs +10 -3
  46. package/crates/tish_fmt/src/lib.rs +29 -13
  47. package/crates/tish_lexer/src/lib.rs +217 -63
  48. package/crates/tish_lexer/src/token.rs +6 -6
  49. package/crates/tish_llvm/src/lib.rs +15 -8
  50. package/crates/tish_lsp/src/main.rs +41 -43
  51. package/crates/tish_native/src/build.rs +1 -6
  52. package/crates/tish_native/src/lib.rs +48 -19
  53. package/crates/tish_opt/src/lib.rs +67 -50
  54. package/crates/tish_parser/src/lib.rs +36 -11
  55. package/crates/tish_parser/src/parser.rs +172 -87
  56. package/crates/tish_runtime/src/http.rs +15 -6
  57. package/crates/tish_runtime/src/http_fetch.rs +24 -14
  58. package/crates/tish_runtime/src/lib.rs +224 -168
  59. package/crates/tish_runtime/src/promise.rs +1 -5
  60. package/crates/tish_runtime/src/ws.rs +45 -20
  61. package/crates/tish_runtime/tests/fetch_readable_stream.rs +5 -4
  62. package/crates/tish_ui/src/jsx.rs +41 -22
  63. package/crates/tish_ui/src/lib.rs +2 -2
  64. package/crates/tish_vm/src/vm.rs +309 -112
  65. package/crates/tish_vm/tests/peephole_jump_chain_logical_or.rs +8 -3
  66. package/crates/tish_wasm/src/lib.rs +38 -28
  67. package/crates/tishlang_cargo_bindgen/Cargo.toml +25 -0
  68. package/crates/tishlang_cargo_bindgen/src/classify.rs +265 -0
  69. package/crates/tishlang_cargo_bindgen/src/discover.rs +52 -0
  70. package/crates/tishlang_cargo_bindgen/src/infer.rs +372 -0
  71. package/crates/tishlang_cargo_bindgen/src/lib.rs +349 -0
  72. package/crates/tishlang_cargo_bindgen/src/main.rs +164 -0
  73. package/crates/tishlang_cargo_bindgen/src/metadata.rs +114 -0
  74. package/package.json +1 -1
  75. package/platform/darwin-arm64/tish +0 -0
  76. package/platform/darwin-x64/tish +0 -0
  77. package/platform/linux-arm64/tish +0 -0
  78. package/platform/linux-x64/tish +0 -0
  79. package/platform/win32-x64/tish.exe +0 -0
@@ -80,9 +80,11 @@ pub fn compile_to_native(
80
80
  .map_err(|e| NativeError { message: e })
81
81
  }
82
82
  Backend::Cranelift => {
83
- let modules = tishlang_compile::resolve_project(entry_path, project_root)
84
- .map_err(|e| NativeError {
85
- message: e.to_string(),
83
+ let modules =
84
+ tishlang_compile::resolve_project(entry_path, project_root).map_err(|e| {
85
+ NativeError {
86
+ message: e.to_string(),
87
+ }
86
88
  })?;
87
89
  tishlang_compile::detect_cycles(&modules).map_err(|e| NativeError {
88
90
  message: e.to_string(),
@@ -121,9 +123,15 @@ pub fn compile_to_native(
121
123
  })
122
124
  }
123
125
  Backend::Llvm => {
124
- let modules = tishlang_compile::resolve_project(entry_path, project_root)
125
- .map_err(|e| NativeError { message: e.to_string() })?;
126
- tishlang_compile::detect_cycles(&modules).map_err(|e| NativeError { message: e.to_string() })?;
126
+ let modules =
127
+ tishlang_compile::resolve_project(entry_path, project_root).map_err(|e| {
128
+ NativeError {
129
+ message: e.to_string(),
130
+ }
131
+ })?;
132
+ tishlang_compile::detect_cycles(&modules).map_err(|e| NativeError {
133
+ message: e.to_string(),
134
+ })?;
127
135
  let program = {
128
136
  let prog = tishlang_compile::merge_modules(modules).map_err(|e| NativeError {
129
137
  message: e.to_string(),
@@ -180,12 +188,17 @@ pub fn compile_program_to_native(
180
188
 
181
189
  match backend {
182
190
  Backend::Rust => {
183
- let program = if optimize { tishlang_opt::optimize(program) } else { program.clone() };
191
+ let program = if optimize {
192
+ tishlang_opt::optimize(program)
193
+ } else {
194
+ program.clone()
195
+ };
184
196
  let root = project_root.unwrap_or_else(|| Path::new("."));
185
197
  let native_modules = tishlang_compile::resolve_native_modules(&program, root)
186
198
  .map_err(|e| NativeError { message: e })?;
187
- let native_build = tishlang_compile::compute_native_build_artifacts(&program, root, &native_modules)
188
- .map_err(|e| NativeError { message: e })?;
199
+ let native_build =
200
+ tishlang_compile::compute_native_build_artifacts(&program, root, &native_modules)
201
+ .map_err(|e| NativeError { message: e })?;
189
202
  let mut all_features = features.to_vec();
190
203
  for f in tishlang_compile::extract_native_import_features(&program) {
191
204
  if !all_features.contains(&f) {
@@ -200,9 +213,7 @@ pub fn compile_program_to_native(
200
213
  &native_build.native_init,
201
214
  optimize,
202
215
  )
203
- .map_err(|e| NativeError {
204
- message: e.message,
205
- })?;
216
+ .map_err(|e| NativeError { message: e.message })?;
206
217
  crate::build::build_via_cargo(
207
218
  &rust_code,
208
219
  native_modules,
@@ -220,15 +231,25 @@ pub fn compile_program_to_native(
220
231
  message: "Cranelift backend does not support external native imports (tish:…, cargo:…, @scope/pkg). Built-in tish:fs, tish:http, tish:process are supported.".to_string(),
221
232
  });
222
233
  }
223
- let program = if optimize { tishlang_opt::optimize(program) } else { program.clone() };
234
+ let program = if optimize {
235
+ tishlang_opt::optimize(program)
236
+ } else {
237
+ program.clone()
238
+ };
224
239
  let chunk = if optimize {
225
- tishlang_bytecode::compile(&program).map_err(|e| NativeError { message: e.to_string() })?
240
+ tishlang_bytecode::compile(&program).map_err(|e| NativeError {
241
+ message: e.to_string(),
242
+ })?
226
243
  } else {
227
- tishlang_bytecode::compile_unoptimized(&program).map_err(|e| NativeError { message: e.to_string() })?
244
+ tishlang_bytecode::compile_unoptimized(&program).map_err(|e| NativeError {
245
+ message: e.to_string(),
246
+ })?
228
247
  };
229
248
  let cranelift_features = tishlang_compile::extract_native_import_features(&program);
230
249
  tishlang_cranelift::compile_chunk_to_native(&chunk, output_path, &cranelift_features)
231
- .map_err(|e| NativeError { message: e.to_string() })
250
+ .map_err(|e| NativeError {
251
+ message: e.to_string(),
252
+ })
232
253
  }
233
254
  Backend::Llvm => {
234
255
  if tishlang_compile::has_external_native_imports(program) {
@@ -236,11 +257,19 @@ pub fn compile_program_to_native(
236
257
  message: "LLVM backend does not support external native imports (tish:…, cargo:…, @scope/pkg).".to_string(),
237
258
  });
238
259
  }
239
- let program = if optimize { tishlang_opt::optimize(program) } else { program.clone() };
260
+ let program = if optimize {
261
+ tishlang_opt::optimize(program)
262
+ } else {
263
+ program.clone()
264
+ };
240
265
  let chunk = if optimize {
241
- tishlang_bytecode::compile(&program).map_err(|e| NativeError { message: e.to_string() })?
266
+ tishlang_bytecode::compile(&program).map_err(|e| NativeError {
267
+ message: e.to_string(),
268
+ })?
242
269
  } else {
243
- tishlang_bytecode::compile_unoptimized(&program).map_err(|e| NativeError { message: e.to_string() })?
270
+ tishlang_bytecode::compile_unoptimized(&program).map_err(|e| NativeError {
271
+ message: e.to_string(),
272
+ })?
244
273
  };
245
274
  let llvm_features = tishlang_compile::extract_native_import_features(&program);
246
275
  tishlang_llvm::compile_chunk_to_native(&chunk, output_path, &llvm_features)
@@ -10,11 +10,7 @@ use tishlang_ast::{ArrowBody, BinOp, Expr, Literal, Program, Statement, UnaryOp}
10
10
  /// Optimize a Tish program. Returns a new program with transformations applied.
11
11
  pub fn optimize(program: &Program) -> Program {
12
12
  Program {
13
- statements: program
14
- .statements
15
- .iter()
16
- .map(optimize_statement)
17
- .collect(),
13
+ statements: program.statements.iter().map(optimize_statement).collect(),
18
14
  }
19
15
  }
20
16
 
@@ -79,7 +75,9 @@ fn optimize_statement(stmt: &Statement) -> Statement {
79
75
  Statement::If {
80
76
  cond: opt_cond,
81
77
  then_branch: Box::new(optimize_statement(then_branch)),
82
- else_branch: else_branch.as_ref().map(|b| Box::new(optimize_statement(b))),
78
+ else_branch: else_branch
79
+ .as_ref()
80
+ .map(|b| Box::new(optimize_statement(b))),
83
81
  span: *span,
84
82
  }
85
83
  }
@@ -144,21 +142,12 @@ fn optimize_statement(stmt: &Statement) -> Statement {
144
142
  expr: optimize_expr(expr),
145
143
  cases: cases
146
144
  .iter()
147
- .map(|(ce, stmts)| {
148
- (
149
- ce.as_ref().map(optimize_expr),
150
- optimize_block(stmts),
151
- )
152
- })
145
+ .map(|(ce, stmts)| (ce.as_ref().map(optimize_expr), optimize_block(stmts)))
153
146
  .collect(),
154
147
  default_body: default_body.as_ref().map(|stmts| optimize_block(stmts)),
155
148
  span: *span,
156
149
  },
157
- Statement::DoWhile {
158
- body,
159
- cond,
160
- span,
161
- } => Statement::DoWhile {
150
+ Statement::DoWhile { body, cond, span } => Statement::DoWhile {
162
151
  body: Box::new(optimize_statement(body)),
163
152
  cond: optimize_expr(cond),
164
153
  span: *span,
@@ -177,7 +166,9 @@ fn optimize_statement(stmt: &Statement) -> Statement {
177
166
  body: Box::new(optimize_statement(body)),
178
167
  catch_param: catch_param.clone(),
179
168
  catch_body: catch_body.as_ref().map(|b| Box::new(optimize_statement(b))),
180
- finally_body: finally_body.as_ref().map(|b| Box::new(optimize_statement(b))),
169
+ finally_body: finally_body
170
+ .as_ref()
171
+ .map(|b| Box::new(optimize_statement(b))),
181
172
  span: *span,
182
173
  },
183
174
  Statement::Import { .. } | Statement::Export { .. } => stmt.clone(),
@@ -232,7 +223,12 @@ fn optimize_expr(expr: &Expr) -> Expr {
232
223
  name: Arc::clone(name),
233
224
  span: *span,
234
225
  },
235
- Expr::Binary { left, op, right, span } => {
226
+ Expr::Binary {
227
+ left,
228
+ op,
229
+ right,
230
+ span,
231
+ } => {
236
232
  let opt_left = optimize_expr(left);
237
233
  let opt_right = optimize_expr(right);
238
234
 
@@ -324,32 +320,28 @@ fn optimize_expr(expr: &Expr) -> Expr {
324
320
  span: *span,
325
321
  }
326
322
  }
327
- Expr::Call {
328
- callee,
329
- args,
330
- span,
331
- } => Expr::Call {
323
+ Expr::Call { callee, args, span } => Expr::Call {
332
324
  callee: Box::new(optimize_expr(callee)),
333
325
  args: args
334
326
  .iter()
335
327
  .map(|a| match a {
336
328
  tishlang_ast::CallArg::Expr(e) => tishlang_ast::CallArg::Expr(optimize_expr(e)),
337
- tishlang_ast::CallArg::Spread(e) => tishlang_ast::CallArg::Spread(optimize_expr(e)),
329
+ tishlang_ast::CallArg::Spread(e) => {
330
+ tishlang_ast::CallArg::Spread(optimize_expr(e))
331
+ }
338
332
  })
339
333
  .collect(),
340
334
  span: *span,
341
335
  },
342
- Expr::New {
343
- callee,
344
- args,
345
- span,
346
- } => Expr::New {
336
+ Expr::New { callee, args, span } => Expr::New {
347
337
  callee: Box::new(optimize_expr(callee)),
348
338
  args: args
349
339
  .iter()
350
340
  .map(|a| match a {
351
341
  tishlang_ast::CallArg::Expr(e) => tishlang_ast::CallArg::Expr(optimize_expr(e)),
352
- tishlang_ast::CallArg::Spread(e) => tishlang_ast::CallArg::Spread(optimize_expr(e)),
342
+ tishlang_ast::CallArg::Spread(e) => {
343
+ tishlang_ast::CallArg::Spread(optimize_expr(e))
344
+ }
353
345
  })
354
346
  .collect(),
355
347
  span: *span,
@@ -385,14 +377,11 @@ fn optimize_expr(expr: &Expr) -> Expr {
385
377
  optional: *optional,
386
378
  span: *span,
387
379
  },
388
- Expr::NullishCoalesce {
389
- left,
390
- right,
391
- span,
392
- } => {
380
+ Expr::NullishCoalesce { left, right, span } => {
393
381
  let opt_left = optimize_expr(left);
394
382
  if let Expr::Literal {
395
- value: Literal::Null, ..
383
+ value: Literal::Null,
384
+ ..
396
385
  } = &opt_left
397
386
  {
398
387
  return optimize_expr(right);
@@ -444,13 +433,23 @@ fn optimize_expr(expr: &Expr) -> Expr {
444
433
  | Expr::PostfixDec { .. }
445
434
  | Expr::PrefixInc { .. }
446
435
  | Expr::PrefixDec { .. } => expr.clone(),
447
- Expr::CompoundAssign { name, op, value, span } => Expr::CompoundAssign {
436
+ Expr::CompoundAssign {
437
+ name,
438
+ op,
439
+ value,
440
+ span,
441
+ } => Expr::CompoundAssign {
448
442
  name: Arc::clone(name),
449
443
  op: *op,
450
444
  value: Box::new(optimize_expr(value)),
451
445
  span: *span,
452
446
  },
453
- Expr::LogicalAssign { name, op, value, span } => Expr::LogicalAssign {
447
+ Expr::LogicalAssign {
448
+ name,
449
+ op,
450
+ value,
451
+ span,
452
+ } => Expr::LogicalAssign {
454
453
  name: Arc::clone(name),
455
454
  op: *op,
456
455
  value: Box::new(optimize_expr(value)),
@@ -478,11 +477,7 @@ fn optimize_expr(expr: &Expr) -> Expr {
478
477
  value: Box::new(optimize_expr(value)),
479
478
  span: *span,
480
479
  },
481
- Expr::ArrowFunction {
482
- params,
483
- body,
484
- span,
485
- } => {
480
+ Expr::ArrowFunction { params, body, span } => {
486
481
  let opt_body = match body {
487
482
  ArrowBody::Expr(e) => ArrowBody::Expr(Box::new(optimize_expr(e))),
488
483
  ArrowBody::Block(s) => ArrowBody::Block(Box::new(optimize_statement(s))),
@@ -493,7 +488,11 @@ fn optimize_expr(expr: &Expr) -> Expr {
493
488
  span: *span,
494
489
  }
495
490
  }
496
- Expr::TemplateLiteral { quasis, exprs, span } => Expr::TemplateLiteral {
491
+ Expr::TemplateLiteral {
492
+ quasis,
493
+ exprs,
494
+ span,
495
+ } => Expr::TemplateLiteral {
497
496
  quasis: quasis.iter().map(Arc::clone).collect(),
498
497
  exprs: exprs.iter().map(optimize_expr).collect(),
499
498
  span: *span,
@@ -503,7 +502,11 @@ fn optimize_expr(expr: &Expr) -> Expr {
503
502
  span: *span,
504
503
  },
505
504
  Expr::JsxElement { .. } | Expr::JsxFragment { .. } => expr.clone(),
506
- Expr::NativeModuleLoad { spec, export_name, span } => Expr::NativeModuleLoad {
505
+ Expr::NativeModuleLoad {
506
+ spec,
507
+ export_name,
508
+ span,
509
+ } => Expr::NativeModuleLoad {
507
510
  spec: Arc::clone(spec),
508
511
  export_name: Arc::clone(export_name),
509
512
  span: *span,
@@ -699,8 +702,12 @@ fn try_fold_binop(left: &Literal, op: BinOp, right: &Literal) -> Option<Literal>
699
702
  Add => {
700
703
  if matches!(left, Literal::String(_)) || matches!(right, Literal::String(_)) {
701
704
  return Some(Literal::String(
702
- format!("{}{}", literal_to_display_string(left), literal_to_display_string(right))
703
- .into(),
705
+ format!(
706
+ "{}{}",
707
+ literal_to_display_string(left),
708
+ literal_to_display_string(right)
709
+ )
710
+ .into(),
704
711
  ));
705
712
  }
706
713
  Literal::Number(ln + rn)
@@ -769,7 +776,11 @@ mod tests {
769
776
  [tishlang_ast::Statement::ExprStmt { expr, .. }] => expr,
770
777
  _ => panic!("expected single expr stmt"),
771
778
  };
772
- assert!(has_literal_number(expr, -42.0), "expected -42, got {:?}", expr);
779
+ assert!(
780
+ has_literal_number(expr, -42.0),
781
+ "expected -42, got {:?}",
782
+ expr
783
+ );
773
784
  }
774
785
 
775
786
  #[test]
@@ -781,7 +792,13 @@ mod tests {
781
792
  _ => panic!("expected single expr stmt"),
782
793
  };
783
794
  assert!(
784
- matches!(expr, Expr::Literal { value: Literal::Bool(false), .. }),
795
+ matches!(
796
+ expr,
797
+ Expr::Literal {
798
+ value: Literal::Bool(false),
799
+ ..
800
+ }
801
+ ),
785
802
  "expected false, got {:?}",
786
803
  expr
787
804
  );
@@ -38,7 +38,9 @@ mod tests {
38
38
  assert_eq!(program.statements.len(), 1);
39
39
  let stmt = &program.statements[0];
40
40
  let init = match stmt {
41
- Statement::VarDecl { init: Some(ref i), .. } => i,
41
+ Statement::VarDecl {
42
+ init: Some(ref i), ..
43
+ } => i,
42
44
  _ => panic!("expected VarDecl with init"),
43
45
  };
44
46
  let props = match init {
@@ -61,11 +63,14 @@ mod tests {
61
63
 
62
64
  #[test]
63
65
  fn test_object_literal_string_key() {
64
- let program = parse(r#"const o = { "ai-a": 0, human: 1 }"#).expect("parse object with string key");
66
+ let program =
67
+ parse(r#"const o = { "ai-a": 0, human: 1 }"#).expect("parse object with string key");
65
68
  assert_eq!(program.statements.len(), 1);
66
69
  let stmt = &program.statements[0];
67
70
  let init = match stmt {
68
- Statement::VarDecl { init: Some(ref i), .. } => i,
71
+ Statement::VarDecl {
72
+ init: Some(ref i), ..
73
+ } => i,
69
74
  _ => panic!("expected VarDecl with init"),
70
75
  };
71
76
  let props = match init {
@@ -89,7 +94,9 @@ mod tests {
89
94
  assert_eq!(program.statements.len(), 1);
90
95
  let stmt = &program.statements[0];
91
96
  let init = match stmt {
92
- Statement::VarDecl { init: Some(ref i), .. } => i,
97
+ Statement::VarDecl {
98
+ init: Some(ref i), ..
99
+ } => i,
93
100
  _ => panic!("expected VarDecl with init"),
94
101
  };
95
102
  let props = match init {
@@ -134,7 +141,9 @@ mod tests {
134
141
  let e = unwrap_expr_stmt(&program);
135
142
  match e {
136
143
  Expr::New { callee, args, .. } => {
137
- assert!(matches!(callee.as_ref(), Expr::Ident { name, .. } if name.as_ref() == "Foo"));
144
+ assert!(
145
+ matches!(callee.as_ref(), Expr::Ident { name, .. } if name.as_ref() == "Foo")
146
+ );
138
147
  assert!(args.is_empty());
139
148
  }
140
149
  _ => panic!("expected New, got {:?}", e),
@@ -147,7 +156,9 @@ mod tests {
147
156
  let e = unwrap_expr_stmt(&program);
148
157
  match e {
149
158
  Expr::New { callee, args, .. } => {
150
- assert!(matches!(callee.as_ref(), Expr::Ident { name, .. } if name.as_ref() == "Uint8Array"));
159
+ assert!(
160
+ matches!(callee.as_ref(), Expr::Ident { name, .. } if name.as_ref() == "Uint8Array")
161
+ );
151
162
  assert_eq!(args.len(), 1);
152
163
  assert!(matches!(&args[0], CallArg::Expr(Expr::Literal { .. })));
153
164
  }
@@ -179,8 +190,14 @@ mod tests {
179
190
  Expr::New { callee, args, .. } => {
180
191
  assert!(args.is_empty());
181
192
  match callee.as_ref() {
182
- Expr::New { callee: inner, args: inner_args, .. } => {
183
- assert!(matches!(inner.as_ref(), Expr::Ident { name, .. } if name.as_ref() == "Date"));
193
+ Expr::New {
194
+ callee: inner,
195
+ args: inner_args,
196
+ ..
197
+ } => {
198
+ assert!(
199
+ matches!(inner.as_ref(), Expr::Ident { name, .. } if name.as_ref() == "Date")
200
+ );
184
201
  assert!(inner_args.is_empty());
185
202
  }
186
203
  _ => panic!("expected nested New"),
@@ -195,11 +212,17 @@ mod tests {
195
212
  let program = parse("new Foo().bar").expect("parse");
196
213
  let e = unwrap_expr_stmt(&program);
197
214
  match e {
198
- Expr::Member { object, prop: tishlang_ast::MemberProp::Name(p), .. } => {
215
+ Expr::Member {
216
+ object,
217
+ prop: tishlang_ast::MemberProp::Name(p),
218
+ ..
219
+ } => {
199
220
  assert_eq!(p.as_ref(), "bar");
200
221
  match object.as_ref() {
201
222
  Expr::New { callee, args, .. } => {
202
- assert!(matches!(callee.as_ref(), Expr::Ident { name, .. } if name.as_ref() == "Foo"));
223
+ assert!(
224
+ matches!(callee.as_ref(), Expr::Ident { name, .. } if name.as_ref() == "Foo")
225
+ );
203
226
  assert!(args.is_empty());
204
227
  }
205
228
  _ => panic!("expected New object"),
@@ -215,7 +238,9 @@ mod tests {
215
238
  let e = unwrap_expr_stmt(&program);
216
239
  match e {
217
240
  Expr::New { args, .. } => {
218
- assert!(matches!(&args[0], CallArg::Spread(Expr::Ident { name, .. }) if name.as_ref() == "xs"));
241
+ assert!(
242
+ matches!(&args[0], CallArg::Spread(Expr::Ident { name, .. }) if name.as_ref() == "xs")
243
+ );
219
244
  }
220
245
  _ => panic!("expected New"),
221
246
  }