@tishlang/tish 1.6.0 → 1.8.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 (113) hide show
  1. package/Cargo.toml +2 -0
  2. package/README.md +2 -0
  3. package/bin/tish +0 -0
  4. package/crates/js_to_tish/src/error.rs +2 -8
  5. package/crates/js_to_tish/src/transform/expr.rs +128 -137
  6. package/crates/js_to_tish/src/transform/stmt.rs +62 -32
  7. package/crates/tish/Cargo.toml +15 -5
  8. package/crates/tish/src/cargo_native_registry.rs +29 -0
  9. package/crates/tish/src/cli_help.rs +92 -39
  10. package/crates/tish/src/main.rs +172 -86
  11. package/crates/tish/src/repl_completion.rs +3 -3
  12. package/crates/tish/tests/cargo_example_compile.rs +4 -2
  13. package/crates/tish/tests/integration_test.rs +216 -54
  14. package/crates/tish/tests/run_optimize_stdout_parity.rs +3 -7
  15. package/crates/tish/tests/shortcircuit.rs +20 -5
  16. package/crates/tish_ast/src/ast.rs +92 -23
  17. package/crates/tish_build_utils/Cargo.toml +4 -0
  18. package/crates/tish_build_utils/src/lib.rs +136 -8
  19. package/crates/tish_builtins/Cargo.toml +5 -1
  20. package/crates/tish_builtins/src/array.rs +65 -33
  21. package/crates/tish_builtins/src/construct.rs +34 -39
  22. package/crates/tish_builtins/src/globals.rs +42 -26
  23. package/crates/tish_builtins/src/helpers.rs +2 -1
  24. package/crates/tish_builtins/src/lib.rs +5 -5
  25. package/crates/tish_builtins/src/math.rs +5 -3
  26. package/crates/tish_builtins/src/object.rs +3 -2
  27. package/crates/tish_builtins/src/string.rs +144 -22
  28. package/crates/tish_bytecode/src/chunk.rs +0 -1
  29. package/crates/tish_bytecode/src/compiler.rs +173 -71
  30. package/crates/tish_bytecode/src/opcode.rs +24 -6
  31. package/crates/tish_bytecode/src/peephole.rs +2 -2
  32. package/crates/tish_compile/Cargo.toml +1 -0
  33. package/crates/tish_compile/src/codegen.rs +1621 -453
  34. package/crates/tish_compile/src/infer.rs +75 -19
  35. package/crates/tish_compile/src/lib.rs +19 -8
  36. package/crates/tish_compile/src/resolve.rs +278 -137
  37. package/crates/tish_compile/src/types.rs +184 -24
  38. package/crates/tish_compile_js/Cargo.toml +1 -0
  39. package/crates/tish_compile_js/src/codegen.rs +181 -37
  40. package/crates/tish_compile_js/src/lib.rs +3 -1
  41. package/crates/tish_compile_js/src/tests_jsx.rs +30 -6
  42. package/crates/tish_compiler_wasm/src/lib.rs +16 -13
  43. package/crates/tish_compiler_wasm/src/resolve_virtual.rs +69 -59
  44. package/crates/tish_core/Cargo.toml +8 -0
  45. package/crates/tish_core/src/json.rs +107 -56
  46. package/crates/tish_core/src/lib.rs +4 -2
  47. package/crates/tish_core/src/macros.rs +5 -5
  48. package/crates/tish_core/src/uri.rs +9 -6
  49. package/crates/tish_core/src/value.rs +145 -43
  50. package/crates/tish_core/src/vmref.rs +178 -0
  51. package/crates/tish_cranelift/src/link.rs +6 -9
  52. package/crates/tish_cranelift/src/lower.rs +14 -8
  53. package/crates/tish_eval/Cargo.toml +17 -2
  54. package/crates/tish_eval/src/eval.rs +474 -165
  55. package/crates/tish_eval/src/http.rs +61 -0
  56. package/crates/tish_eval/src/lib.rs +12 -8
  57. package/crates/tish_eval/src/natives.rs +136 -38
  58. package/crates/tish_eval/src/promise.rs +14 -8
  59. package/crates/tish_eval/src/timers.rs +28 -19
  60. package/crates/tish_eval/src/value.rs +17 -6
  61. package/crates/tish_eval/src/value_convert.rs +13 -5
  62. package/crates/tish_fmt/src/lib.rs +149 -43
  63. package/crates/tish_lexer/src/lib.rs +232 -63
  64. package/crates/tish_lexer/src/token.rs +10 -6
  65. package/crates/tish_llvm/src/lib.rs +17 -8
  66. package/crates/tish_lsp/Cargo.toml +4 -1
  67. package/crates/tish_lsp/README.md +1 -1
  68. package/crates/tish_lsp/src/builtin_goto.rs +261 -0
  69. package/crates/tish_lsp/src/import_goto.rs +549 -0
  70. package/crates/tish_lsp/src/main.rs +504 -106
  71. package/crates/tish_native/src/build.rs +4 -8
  72. package/crates/tish_native/src/lib.rs +54 -21
  73. package/crates/tish_opt/src/lib.rs +84 -52
  74. package/crates/tish_parser/src/lib.rs +45 -13
  75. package/crates/tish_parser/src/parser.rs +505 -130
  76. package/crates/tish_resolve/Cargo.toml +13 -0
  77. package/crates/tish_resolve/src/lib.rs +3436 -0
  78. package/crates/tish_resolve/src/pos.rs +133 -0
  79. package/crates/tish_runtime/Cargo.toml +68 -3
  80. package/crates/tish_runtime/src/http.rs +1136 -145
  81. package/crates/tish_runtime/src/http_fetch.rs +38 -27
  82. package/crates/tish_runtime/src/http_hyper.rs +418 -0
  83. package/crates/tish_runtime/src/http_prefork.rs +189 -0
  84. package/crates/tish_runtime/src/lib.rs +375 -189
  85. package/crates/tish_runtime/src/promise.rs +199 -40
  86. package/crates/tish_runtime/src/promise_io.rs +2 -1
  87. package/crates/tish_runtime/src/timers.rs +37 -1
  88. package/crates/tish_runtime/src/ws.rs +65 -42
  89. package/crates/tish_runtime/tests/fetch_readable_stream.rs +5 -4
  90. package/crates/tish_ui/src/jsx.rs +317 -27
  91. package/crates/tish_ui/src/lib.rs +5 -2
  92. package/crates/tish_ui/src/runtime/hooks.rs +406 -45
  93. package/crates/tish_ui/src/runtime/mod.rs +36 -9
  94. package/crates/tish_vm/Cargo.toml +15 -5
  95. package/crates/tish_vm/src/vm.rs +725 -281
  96. package/crates/tish_vm/tests/peephole_jump_chain_logical_or.rs +11 -4
  97. package/crates/tish_wasm/src/lib.rs +55 -42
  98. package/crates/tish_wasm_runtime/Cargo.toml +2 -1
  99. package/crates/tish_wasm_runtime/src/lib.rs +1 -1
  100. package/crates/tishlang_cargo_bindgen/Cargo.toml +26 -0
  101. package/crates/tishlang_cargo_bindgen/src/classify.rs +265 -0
  102. package/crates/tishlang_cargo_bindgen/src/discover.rs +120 -0
  103. package/crates/tishlang_cargo_bindgen/src/infer.rs +372 -0
  104. package/crates/tishlang_cargo_bindgen/src/lib.rs +350 -0
  105. package/crates/tishlang_cargo_bindgen/src/main.rs +164 -0
  106. package/crates/tishlang_cargo_bindgen/src/metadata.rs +114 -0
  107. package/justfile +8 -0
  108. package/package.json +1 -1
  109. package/platform/darwin-arm64/tish +0 -0
  110. package/platform/darwin-x64/tish +0 -0
  111. package/platform/linux-arm64/tish +0 -0
  112. package/platform/linux-x64/tish +0 -0
  113. package/platform/win32-x64/tish.exe +0 -0
@@ -1,7 +1,10 @@
1
1
  //! Shared JSX lowering: emit `h(tag, props, children)` as JavaScript or Rust (`Value`) source.
2
2
 
3
+ use std::collections::HashSet;
4
+
3
5
  use tishlang_ast::{
4
- ArrayElement, Expr, JsxAttrValue, JsxChild, JsxProp, Literal, ObjectProp,
6
+ ArrayElement, ArrowBody, CallArg, ExportDeclaration, Expr, JsxAttrValue, JsxChild, JsxProp,
7
+ Literal, MemberProp, ObjectProp, Program, Statement,
5
8
  };
6
9
 
7
10
  /// Escape a Tish identifier for Rust output (matches `tishlang_compile` conventions).
@@ -26,20 +29,29 @@ where
26
29
  children,
27
30
  ..
28
31
  } => {
29
- let tag_str = if tag.chars().next().map(|c| c.is_uppercase()).unwrap_or(false) {
32
+ let tag_str = if tag
33
+ .chars()
34
+ .next()
35
+ .map(|c| c.is_uppercase())
36
+ .unwrap_or(false)
37
+ {
30
38
  tag.as_ref().to_string()
31
39
  } else {
32
40
  format!("{:?}", tag.as_ref())
33
41
  };
34
42
  let props_str = emit_jsx_props_js(props, emit_expr)?;
35
- let children_strs: Result<Vec<_>, _> =
36
- children.iter().map(|c| emit_jsx_child_js(c, emit_expr)).collect();
43
+ let children_strs: Result<Vec<_>, _> = children
44
+ .iter()
45
+ .map(|c| emit_jsx_child_js(c, emit_expr))
46
+ .collect();
37
47
  let children_str = children_strs?.join(", ");
38
48
  Ok(format!("h({}, {}, [{}])", tag_str, props_str, children_str))
39
49
  }
40
50
  Expr::JsxFragment { children, .. } => {
41
- let children_strs: Result<Vec<_>, _> =
42
- children.iter().map(|c| emit_jsx_child_js(c, emit_expr)).collect();
51
+ let children_strs: Result<Vec<_>, _> = children
52
+ .iter()
53
+ .map(|c| emit_jsx_child_js(c, emit_expr))
54
+ .collect();
43
55
  let children_str = children_strs?.join(", ");
44
56
  Ok(format!("h(Fragment, null, [{}])", children_str))
45
57
  }
@@ -107,8 +119,265 @@ where
107
119
  }
108
120
  }
109
121
 
122
+ /// Every `fn Foo` name in the program (including nested bodies), for Rust JSX tag lowering.
123
+ ///
124
+ /// PascalCase JSX tags that match a name here are emitted as a Rust identifier (component
125
+ /// `Value::Function`). Other PascalCase tags become `Value::String("Tag")` (native intrinsics).
126
+ pub fn collect_fun_decl_names(program: &Program) -> HashSet<String> {
127
+ let mut names = HashSet::new();
128
+ for s in &program.statements {
129
+ collect_fun_decl_names_stmt(s, &mut names);
130
+ }
131
+ names
132
+ }
133
+
134
+ fn collect_fun_decl_names_stmt(stmt: &Statement, names: &mut HashSet<String>) {
135
+ match stmt {
136
+ Statement::FunDecl { name, body, .. } => {
137
+ names.insert(name.to_string());
138
+ collect_fun_decl_names_stmt(body, names);
139
+ }
140
+ Statement::Block { statements, .. } => {
141
+ for s in statements {
142
+ collect_fun_decl_names_stmt(s, names);
143
+ }
144
+ }
145
+ Statement::VarDecl { init, .. } => {
146
+ if let Some(e) = init {
147
+ collect_fun_decl_names_expr(e, names);
148
+ }
149
+ }
150
+ Statement::VarDeclDestructure { init, .. } => collect_fun_decl_names_expr(init, names),
151
+ Statement::ExprStmt { expr, .. } => collect_fun_decl_names_expr(expr, names),
152
+ Statement::If {
153
+ cond,
154
+ then_branch,
155
+ else_branch,
156
+ ..
157
+ } => {
158
+ collect_fun_decl_names_expr(cond, names);
159
+ collect_fun_decl_names_stmt(then_branch, names);
160
+ if let Some(e) = else_branch {
161
+ collect_fun_decl_names_stmt(e, names);
162
+ }
163
+ }
164
+ Statement::While { cond, body, .. } => {
165
+ collect_fun_decl_names_expr(cond, names);
166
+ collect_fun_decl_names_stmt(body, names);
167
+ }
168
+ Statement::For {
169
+ init,
170
+ cond,
171
+ update,
172
+ body,
173
+ ..
174
+ } => {
175
+ if let Some(i) = init {
176
+ collect_fun_decl_names_stmt(i, names);
177
+ }
178
+ if let Some(c) = cond {
179
+ collect_fun_decl_names_expr(c, names);
180
+ }
181
+ if let Some(u) = update {
182
+ collect_fun_decl_names_expr(u, names);
183
+ }
184
+ collect_fun_decl_names_stmt(body, names);
185
+ }
186
+ Statement::ForOf { iterable, body, .. } => {
187
+ collect_fun_decl_names_expr(iterable, names);
188
+ collect_fun_decl_names_stmt(body, names);
189
+ }
190
+ Statement::Return { value, .. } => {
191
+ if let Some(e) = value {
192
+ collect_fun_decl_names_expr(e, names);
193
+ }
194
+ }
195
+ Statement::Switch {
196
+ expr,
197
+ cases,
198
+ default_body,
199
+ ..
200
+ } => {
201
+ collect_fun_decl_names_expr(expr, names);
202
+ for (ce, ss) in cases {
203
+ if let Some(e) = ce {
204
+ collect_fun_decl_names_expr(e, names);
205
+ }
206
+ for s in ss {
207
+ collect_fun_decl_names_stmt(s, names);
208
+ }
209
+ }
210
+ if let Some(ss) = default_body {
211
+ for s in ss {
212
+ collect_fun_decl_names_stmt(s, names);
213
+ }
214
+ }
215
+ }
216
+ Statement::DoWhile { body, cond, .. } => {
217
+ collect_fun_decl_names_stmt(body, names);
218
+ collect_fun_decl_names_expr(cond, names);
219
+ }
220
+ Statement::Throw { value, .. } => collect_fun_decl_names_expr(value, names),
221
+ Statement::Try {
222
+ body,
223
+ catch_body,
224
+ finally_body,
225
+ ..
226
+ } => {
227
+ collect_fun_decl_names_stmt(body, names);
228
+ if let Some(c) = catch_body {
229
+ collect_fun_decl_names_stmt(c, names);
230
+ }
231
+ if let Some(f) = finally_body {
232
+ collect_fun_decl_names_stmt(f, names);
233
+ }
234
+ }
235
+ Statement::Export { declaration, .. } => match declaration.as_ref() {
236
+ ExportDeclaration::Named(inner) => collect_fun_decl_names_stmt(inner, names),
237
+ ExportDeclaration::Default(e) => collect_fun_decl_names_expr(e, names),
238
+ },
239
+ Statement::Import { .. }
240
+ | Statement::Break { .. }
241
+ | Statement::Continue { .. }
242
+ | Statement::TypeAlias { .. }
243
+ | Statement::DeclareVar { .. }
244
+ | Statement::DeclareFun { .. } => {}
245
+ }
246
+ }
247
+
248
+ fn collect_fun_decl_names_expr(expr: &Expr, names: &mut HashSet<String>) {
249
+ match expr {
250
+ Expr::ArrowFunction { body, .. } => match body {
251
+ ArrowBody::Expr(e) => collect_fun_decl_names_expr(e, names),
252
+ ArrowBody::Block(s) => collect_fun_decl_names_stmt(s, names),
253
+ },
254
+ Expr::Binary { left, right, .. } => {
255
+ collect_fun_decl_names_expr(left, names);
256
+ collect_fun_decl_names_expr(right, names);
257
+ }
258
+ Expr::Unary { operand, .. } => collect_fun_decl_names_expr(operand, names),
259
+ Expr::Assign { value, .. } => collect_fun_decl_names_expr(value, names),
260
+ Expr::Call { callee, args, .. } => {
261
+ collect_fun_decl_names_expr(callee, names);
262
+ for a in args {
263
+ match a {
264
+ CallArg::Expr(e) | CallArg::Spread(e) => collect_fun_decl_names_expr(e, names),
265
+ }
266
+ }
267
+ }
268
+ Expr::Member { object, prop, .. } => {
269
+ collect_fun_decl_names_expr(object, names);
270
+ if let MemberProp::Expr(e) = prop {
271
+ collect_fun_decl_names_expr(e, names);
272
+ }
273
+ }
274
+ Expr::Index { object, index, .. } => {
275
+ collect_fun_decl_names_expr(object, names);
276
+ collect_fun_decl_names_expr(index, names);
277
+ }
278
+ Expr::Conditional {
279
+ cond,
280
+ then_branch,
281
+ else_branch,
282
+ ..
283
+ } => {
284
+ collect_fun_decl_names_expr(cond, names);
285
+ collect_fun_decl_names_expr(then_branch, names);
286
+ collect_fun_decl_names_expr(else_branch, names);
287
+ }
288
+ Expr::Array { elements, .. } => {
289
+ for el in elements {
290
+ match el {
291
+ ArrayElement::Expr(e) | ArrayElement::Spread(e) => {
292
+ collect_fun_decl_names_expr(e, names);
293
+ }
294
+ }
295
+ }
296
+ }
297
+ Expr::Object { props, .. } => {
298
+ for p in props {
299
+ match p {
300
+ ObjectProp::KeyValue(_, e) | ObjectProp::Spread(e) => {
301
+ collect_fun_decl_names_expr(e, names);
302
+ }
303
+ }
304
+ }
305
+ }
306
+ Expr::NullishCoalesce { left, right, .. } => {
307
+ collect_fun_decl_names_expr(left, names);
308
+ collect_fun_decl_names_expr(right, names);
309
+ }
310
+ Expr::TemplateLiteral { exprs, .. } => {
311
+ for e in exprs {
312
+ collect_fun_decl_names_expr(e, names);
313
+ }
314
+ }
315
+ Expr::Await { operand, .. } | Expr::TypeOf { operand, .. } => {
316
+ collect_fun_decl_names_expr(operand, names);
317
+ }
318
+ Expr::CompoundAssign { value, .. } | Expr::LogicalAssign { value, .. } => {
319
+ collect_fun_decl_names_expr(value, names);
320
+ }
321
+ Expr::MemberAssign { object, value, .. } => {
322
+ collect_fun_decl_names_expr(object, names);
323
+ collect_fun_decl_names_expr(value, names);
324
+ }
325
+ Expr::IndexAssign {
326
+ object,
327
+ index,
328
+ value,
329
+ ..
330
+ } => {
331
+ collect_fun_decl_names_expr(object, names);
332
+ collect_fun_decl_names_expr(index, names);
333
+ collect_fun_decl_names_expr(value, names);
334
+ }
335
+ Expr::New { callee, args, .. } => {
336
+ collect_fun_decl_names_expr(callee, names);
337
+ for a in args {
338
+ match a {
339
+ CallArg::Expr(e) | CallArg::Spread(e) => collect_fun_decl_names_expr(e, names),
340
+ }
341
+ }
342
+ }
343
+ Expr::PostfixInc { .. }
344
+ | Expr::PrefixInc { .. }
345
+ | Expr::PostfixDec { .. }
346
+ | Expr::PrefixDec { .. } => {}
347
+ Expr::JsxElement { props, children, .. } => {
348
+ for p in props {
349
+ match p {
350
+ JsxProp::Attr { value, .. } => {
351
+ if let JsxAttrValue::Expr(e) = value {
352
+ collect_fun_decl_names_expr(e, names);
353
+ }
354
+ }
355
+ JsxProp::Spread(e) => collect_fun_decl_names_expr(e, names),
356
+ }
357
+ }
358
+ for c in children {
359
+ if let JsxChild::Expr(e) = c {
360
+ collect_fun_decl_names_expr(e, names);
361
+ }
362
+ }
363
+ }
364
+ Expr::JsxFragment { children, .. } => {
365
+ for c in children {
366
+ if let JsxChild::Expr(e) = c {
367
+ collect_fun_decl_names_expr(e, names);
368
+ }
369
+ }
370
+ }
371
+ Expr::Literal { .. } | Expr::Ident { .. } | Expr::NativeModuleLoad { .. } => {}
372
+ }
373
+ }
374
+
110
375
  /// Emit JSX as Rust `Value` by calling `tishlang_ui::ui_h` directly (no closure capture of a local `h` binding).
111
- pub fn emit_jsx_rust<F, E>(expr: &Expr, emit_expr: &mut F) -> Result<String, E>
376
+ pub fn emit_jsx_rust<F, E>(
377
+ expr: &Expr,
378
+ emit_expr: &mut F,
379
+ fun_decls: &HashSet<String>,
380
+ ) -> Result<String, E>
112
381
  where
113
382
  F: FnMut(&Expr) -> Result<String, E>,
114
383
  E: From<String>,
@@ -120,9 +389,17 @@ where
120
389
  children,
121
390
  ..
122
391
  } => {
123
- let is_component = tag.chars().next().map(|c| c.is_uppercase()).unwrap_or(false);
392
+ let is_component = tag
393
+ .chars()
394
+ .next()
395
+ .map(|c| c.is_uppercase())
396
+ .unwrap_or(false);
124
397
  let tag_rust = if is_component {
125
- escape_ident_rust(tag.as_ref())
398
+ if fun_decls.contains(tag.as_ref()) {
399
+ escape_ident_rust(tag.as_ref())
400
+ } else {
401
+ format!("Value::String({:?}.into())", tag.as_ref())
402
+ }
126
403
  } else {
127
404
  format!("Value::String({:?}.into())", tag.as_ref())
128
405
  };
@@ -132,7 +409,7 @@ where
132
409
  .map(|c| emit_jsx_child_rust(c, emit_expr))
133
410
  .collect();
134
411
  let children_rust = format!(
135
- "Value::Array(Rc::new(RefCell::new(vec![{}])))",
412
+ "Value::Array(VmRef::new(vec![{}]))",
136
413
  child_parts?.join(", ")
137
414
  );
138
415
  Ok(wrap_h_call_rust(&tag_rust, &props_rust, &children_rust))
@@ -143,14 +420,10 @@ where
143
420
  .map(|c| emit_jsx_child_rust(c, emit_expr))
144
421
  .collect();
145
422
  let children_rust = format!(
146
- "Value::Array(Rc::new(RefCell::new(vec![{}])))",
423
+ "Value::Array(VmRef::new(vec![{}]))",
147
424
  child_parts?.join(", ")
148
425
  );
149
- Ok(wrap_h_call_rust(
150
- "Fragment",
151
- "Value::Null",
152
- &children_rust,
153
- ))
426
+ Ok(wrap_h_call_rust("Fragment", "Value::Null", &children_rust))
154
427
  }
155
428
  _ => Err(E::from("emit_jsx_rust: not a JSX expression".to_string())),
156
429
  }
@@ -200,7 +473,7 @@ where
200
473
  }
201
474
  }
202
475
  Ok(format!(
203
- "{{ let mut _obj: ObjectMap = ObjectMap::default(); {} Value::Object(Rc::new(RefCell::new(_obj))) }}",
476
+ "{{ let mut _obj: ObjectMap = ObjectMap::default(); {} Value::Object(VmRef::new(_obj)) }}",
204
477
  parts.join(" ")
205
478
  ))
206
479
  } else {
@@ -222,7 +495,7 @@ where
222
495
  }
223
496
  }
224
497
  Ok(format!(
225
- "Value::Object(Rc::new(RefCell::new(ObjectMap::from([{}]))))",
498
+ "Value::Object(VmRef::new(ObjectMap::from([{}])))",
226
499
  kv.join(", ")
227
500
  ))
228
501
  }
@@ -279,7 +552,13 @@ fn stmt_contains_jsx(stmt: &tishlang_ast::Statement) -> bool {
279
552
  Statement::While { cond, body, .. } | Statement::DoWhile { body, cond, .. } => {
280
553
  expr_contains_jsx(cond) || stmt_contains_jsx(body)
281
554
  }
282
- Statement::For { init, cond, update, body, .. } => {
555
+ Statement::For {
556
+ init,
557
+ cond,
558
+ update,
559
+ body,
560
+ ..
561
+ } => {
283
562
  init.as_ref().is_some_and(|s| stmt_contains_jsx(s))
284
563
  || cond.as_ref().is_some_and(expr_contains_jsx)
285
564
  || update.as_ref().is_some_and(expr_contains_jsx)
@@ -288,7 +567,12 @@ fn stmt_contains_jsx(stmt: &tishlang_ast::Statement) -> bool {
288
567
  Statement::ForOf { iterable, body, .. } => {
289
568
  expr_contains_jsx(iterable) || stmt_contains_jsx(body)
290
569
  }
291
- Statement::Switch { expr, cases, default_body, .. } => {
570
+ Statement::Switch {
571
+ expr,
572
+ cases,
573
+ default_body,
574
+ ..
575
+ } => {
292
576
  expr_contains_jsx(expr)
293
577
  || cases.iter().any(|(e, ss)| {
294
578
  e.as_ref().is_some_and(expr_contains_jsx) || ss.iter().any(stmt_contains_jsx)
@@ -313,7 +597,12 @@ fn stmt_contains_jsx(stmt: &tishlang_ast::Statement) -> bool {
313
597
  ExportDeclaration::Named(inner) => stmt_contains_jsx(inner),
314
598
  ExportDeclaration::Default(e) => expr_contains_jsx(e),
315
599
  },
316
- Statement::Import { .. } | Statement::Break { .. } | Statement::Continue { .. } => false,
600
+ Statement::Import { .. }
601
+ | Statement::Break { .. }
602
+ | Statement::Continue { .. }
603
+ | Statement::TypeAlias { .. }
604
+ | Statement::DeclareVar { .. }
605
+ | Statement::DeclareFun { .. } => false,
317
606
  }
318
607
  }
319
608
 
@@ -372,9 +661,12 @@ fn expr_contains_jsx(expr: &Expr) -> bool {
372
661
  Expr::MemberAssign { object, value, .. } => {
373
662
  expr_contains_jsx(object) || expr_contains_jsx(value)
374
663
  }
375
- Expr::IndexAssign { object, index, value, .. } => {
376
- expr_contains_jsx(object) || expr_contains_jsx(index) || expr_contains_jsx(value)
377
- }
664
+ Expr::IndexAssign {
665
+ object,
666
+ index,
667
+ value,
668
+ ..
669
+ } => expr_contains_jsx(object) || expr_contains_jsx(index) || expr_contains_jsx(value),
378
670
  Expr::New { callee, args, .. } => {
379
671
  expr_contains_jsx(callee)
380
672
  || args.iter().any(|a| match a {
@@ -383,8 +675,6 @@ fn expr_contains_jsx(expr: &Expr) -> bool {
383
675
  }
384
676
  })
385
677
  }
386
- Expr::Literal { .. }
387
- | Expr::Ident { .. }
388
- | Expr::NativeModuleLoad { .. } => false,
678
+ Expr::Literal { .. } | Expr::Ident { .. } | Expr::NativeModuleLoad { .. } => false,
389
679
  }
390
680
  }
@@ -11,6 +11,9 @@ pub mod runtime;
11
11
 
12
12
  #[cfg(feature = "runtime")]
13
13
  pub use runtime::{
14
- fragment_value, install_thread_local_host, native_create_root, native_use_state, ui_h,
15
- ui_text, with_thread_local_host, Host, HeadlessHost, FRAGMENT_SENTINEL,
14
+ alloc_root_id, current_root_id, drop_host_for_root, fragment_value, install_host_for_root,
15
+ install_thread_local_host, native_create_root, native_use_effect, native_use_memo,
16
+ native_use_state, run_with_current_root, ui_h, ui_text, unregister_root,
17
+ unregister_root_hooks_and_effects, with_host_for_root, with_thread_local_host, HeadlessHost, Host,
18
+ FRAGMENT_SENTINEL, LEGACY_ROOT_ID, RootId,
16
19
  };