@tishlang/tish-format 1.0.12 → 2.0.1

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 (189) hide show
  1. package/Cargo.toml +51 -0
  2. package/LICENSE +13 -0
  3. package/bin/tish-format +0 -0
  4. package/crates/js_to_tish/Cargo.toml +11 -0
  5. package/crates/js_to_tish/README.md +18 -0
  6. package/crates/js_to_tish/src/error.rs +55 -0
  7. package/crates/js_to_tish/src/lib.rs +11 -0
  8. package/crates/js_to_tish/src/span_util.rs +35 -0
  9. package/crates/js_to_tish/src/transform/expr.rs +611 -0
  10. package/crates/js_to_tish/src/transform/stmt.rs +503 -0
  11. package/crates/js_to_tish/src/transform.rs +60 -0
  12. package/crates/tish/Cargo.toml +62 -0
  13. package/crates/tish/build.rs +21 -0
  14. package/crates/tish/src/cargo_native_registry.rs +32 -0
  15. package/crates/tish/src/cli_help.rs +576 -0
  16. package/crates/tish/src/main.rs +853 -0
  17. package/crates/tish/src/repl_completion.rs +199 -0
  18. package/crates/tish/tests/cargo_example_compile.rs +67 -0
  19. package/crates/tish/tests/error_source_location.rs +36 -0
  20. package/crates/tish/tests/fixtures/cargo_example_project/Cargo.toml +3 -0
  21. package/crates/tish/tests/fixtures/cargo_example_project/crates/demo-shim/Cargo.toml +11 -0
  22. package/crates/tish/tests/fixtures/cargo_example_project/crates/demo-shim/src/lib.rs +12 -0
  23. package/crates/tish/tests/fixtures/cargo_example_project/package.json +10 -0
  24. package/crates/tish/tests/fixtures/cargo_example_project/src/main.tish +3 -0
  25. package/crates/tish/tests/fixtures/runtime_error_location.tish +5 -0
  26. package/crates/tish/tests/fixtures/trycatch_runtime_errors.tish +15 -0
  27. package/crates/tish/tests/fixtures/tty_capability.tish +9 -0
  28. package/crates/tish/tests/integration_test.rs +1406 -0
  29. package/crates/tish/tests/run_optimize_stdout_parity.rs +50 -0
  30. package/crates/tish/tests/shortcircuit.rs +65 -0
  31. package/crates/tish/tests/trycatch_runtime_errors.rs +45 -0
  32. package/crates/tish/tests/tty_capability.rs +43 -0
  33. package/crates/tish_ast/Cargo.toml +9 -0
  34. package/crates/tish_ast/src/ast.rs +649 -0
  35. package/crates/tish_ast/src/lib.rs +5 -0
  36. package/crates/tish_build_utils/Cargo.toml +11 -0
  37. package/crates/tish_build_utils/src/lib.rs +577 -0
  38. package/crates/tish_builtins/Cargo.toml +22 -0
  39. package/crates/tish_builtins/src/array.rs +803 -0
  40. package/crates/tish_builtins/src/collections.rs +481 -0
  41. package/crates/tish_builtins/src/construct.rs +199 -0
  42. package/crates/tish_builtins/src/date.rs +538 -0
  43. package/crates/tish_builtins/src/globals.rs +293 -0
  44. package/crates/tish_builtins/src/helpers.rs +35 -0
  45. package/crates/tish_builtins/src/iterator.rs +129 -0
  46. package/crates/tish_builtins/src/lib.rs +21 -0
  47. package/crates/tish_builtins/src/math.rs +89 -0
  48. package/crates/tish_builtins/src/number.rs +96 -0
  49. package/crates/tish_builtins/src/object.rs +36 -0
  50. package/crates/tish_builtins/src/string.rs +646 -0
  51. package/crates/tish_builtins/src/symbol.rs +83 -0
  52. package/crates/tish_builtins/src/typedarrays.rs +298 -0
  53. package/crates/tish_bytecode/Cargo.toml +17 -0
  54. package/crates/tish_bytecode/src/chunk.rs +164 -0
  55. package/crates/tish_bytecode/src/compiler.rs +2604 -0
  56. package/crates/tish_bytecode/src/encoding.rs +102 -0
  57. package/crates/tish_bytecode/src/lib.rs +20 -0
  58. package/crates/tish_bytecode/src/opcode.rs +185 -0
  59. package/crates/tish_bytecode/src/peephole.rs +189 -0
  60. package/crates/tish_bytecode/src/serialize.rs +193 -0
  61. package/crates/tish_bytecode/tests/break_continue_bytecode.rs +44 -0
  62. package/crates/tish_bytecode/tests/constant_folding.rs +84 -0
  63. package/crates/tish_bytecode/tests/sort_optimization.rs +31 -0
  64. package/crates/tish_compile/Cargo.toml +27 -0
  65. package/crates/tish_compile/src/check.rs +774 -0
  66. package/crates/tish_compile/src/codegen.rs +7317 -0
  67. package/crates/tish_compile/src/infer.rs +1681 -0
  68. package/crates/tish_compile/src/lib.rs +206 -0
  69. package/crates/tish_compile/src/resolve.rs +1951 -0
  70. package/crates/tish_compile/src/types.rs +605 -0
  71. package/crates/tish_compile_js/Cargo.toml +18 -0
  72. package/crates/tish_compile_js/examples/jsx_vdom_smoke.tish +8 -0
  73. package/crates/tish_compile_js/src/codegen.rs +938 -0
  74. package/crates/tish_compile_js/src/error.rs +20 -0
  75. package/crates/tish_compile_js/src/lib.rs +26 -0
  76. package/crates/tish_compile_js/src/tests_jsx.rs +414 -0
  77. package/crates/tish_compiler_wasm/Cargo.toml +21 -0
  78. package/crates/tish_compiler_wasm/src/lib.rs +57 -0
  79. package/crates/tish_compiler_wasm/src/resolve_virtual.rs +473 -0
  80. package/crates/tish_core/Cargo.toml +32 -0
  81. package/crates/tish_core/src/console_style.rs +170 -0
  82. package/crates/tish_core/src/json.rs +430 -0
  83. package/crates/tish_core/src/lib.rs +20 -0
  84. package/crates/tish_core/src/macros.rs +36 -0
  85. package/crates/tish_core/src/shape.rs +85 -0
  86. package/crates/tish_core/src/uri.rs +118 -0
  87. package/crates/tish_core/src/value.rs +1350 -0
  88. package/crates/tish_core/src/vmref.rs +183 -0
  89. package/crates/tish_cranelift/Cargo.toml +19 -0
  90. package/crates/tish_cranelift/src/lib.rs +43 -0
  91. package/crates/tish_cranelift/src/link.rs +130 -0
  92. package/crates/tish_cranelift/src/lower.rs +85 -0
  93. package/crates/tish_cranelift_runtime/Cargo.toml +26 -0
  94. package/crates/tish_cranelift_runtime/src/lib.rs +45 -0
  95. package/crates/tish_eval/Cargo.toml +51 -0
  96. package/crates/tish_eval/src/eval.rs +4265 -0
  97. package/crates/tish_eval/src/http.rs +191 -0
  98. package/crates/tish_eval/src/lib.rs +99 -0
  99. package/crates/tish_eval/src/natives.rs +551 -0
  100. package/crates/tish_eval/src/promise.rs +179 -0
  101. package/crates/tish_eval/src/regex.rs +299 -0
  102. package/crates/tish_eval/src/timers.rs +120 -0
  103. package/crates/tish_eval/src/value.rs +336 -0
  104. package/crates/tish_eval/src/value_convert.rs +117 -0
  105. package/crates/tish_ffi/Cargo.toml +26 -0
  106. package/crates/tish_ffi/src/lib.rs +518 -0
  107. package/crates/tish_ffi/tests/fixtures/testmod/Cargo.toml +18 -0
  108. package/crates/tish_ffi/tests/fixtures/testmod/src/lib.rs +46 -0
  109. package/crates/tish_ffi/tests/loader.rs +65 -0
  110. package/crates/tish_fmt/Cargo.toml +16 -0
  111. package/crates/tish_fmt/src/bin/tish-fmt.rs +41 -0
  112. package/crates/tish_fmt/src/lib.rs +2157 -0
  113. package/crates/tish_jsx_web/Cargo.toml +9 -0
  114. package/crates/tish_jsx_web/README.md +5 -0
  115. package/crates/tish_jsx_web/src/lib.rs +2 -0
  116. package/crates/tish_lexer/Cargo.toml +9 -0
  117. package/crates/tish_lexer/src/lib.rs +1104 -0
  118. package/crates/tish_lexer/src/token.rs +170 -0
  119. package/crates/tish_lint/Cargo.toml +18 -0
  120. package/crates/tish_lint/src/bin/tish-lint.rs +195 -0
  121. package/crates/tish_lint/src/lib.rs +281 -0
  122. package/crates/tish_llvm/Cargo.toml +13 -0
  123. package/crates/tish_llvm/src/lib.rs +115 -0
  124. package/crates/tish_lsp/Cargo.toml +25 -0
  125. package/crates/tish_lsp/README.md +26 -0
  126. package/crates/tish_lsp/src/builtin_goto.rs +362 -0
  127. package/crates/tish_lsp/src/import_goto.rs +564 -0
  128. package/crates/tish_lsp/src/main.rs +1459 -0
  129. package/crates/tish_native/Cargo.toml +16 -0
  130. package/crates/tish_native/src/build.rs +481 -0
  131. package/crates/tish_native/src/config.rs +48 -0
  132. package/crates/tish_native/src/lib.rs +416 -0
  133. package/crates/tish_opt/Cargo.toml +13 -0
  134. package/crates/tish_opt/src/lib.rs +1046 -0
  135. package/crates/tish_parser/Cargo.toml +11 -0
  136. package/crates/tish_parser/src/lib.rs +386 -0
  137. package/crates/tish_parser/src/parser.rs +2726 -0
  138. package/crates/tish_pg/Cargo.toml +34 -0
  139. package/crates/tish_pg/README.md +38 -0
  140. package/crates/tish_pg/src/error.rs +52 -0
  141. package/crates/tish_pg/src/lib.rs +955 -0
  142. package/crates/tish_resolve/Cargo.toml +13 -0
  143. package/crates/tish_resolve/src/lib.rs +3601 -0
  144. package/crates/tish_resolve/src/pos.rs +141 -0
  145. package/crates/tish_runtime/Cargo.toml +100 -0
  146. package/crates/tish_runtime/src/http.rs +1347 -0
  147. package/crates/tish_runtime/src/http_fetch.rs +492 -0
  148. package/crates/tish_runtime/src/http_hyper.rs +441 -0
  149. package/crates/tish_runtime/src/http_prefork.rs +189 -0
  150. package/crates/tish_runtime/src/lib.rs +1447 -0
  151. package/crates/tish_runtime/src/native_promise.rs +15 -0
  152. package/crates/tish_runtime/src/promise.rs +558 -0
  153. package/crates/tish_runtime/src/promise_io.rs +38 -0
  154. package/crates/tish_runtime/src/timers.rs +172 -0
  155. package/crates/tish_runtime/src/tty.rs +226 -0
  156. package/crates/tish_runtime/src/ws.rs +778 -0
  157. package/crates/tish_runtime/tests/fetch_readable_stream.rs +102 -0
  158. package/crates/tish_ui/Cargo.toml +17 -0
  159. package/crates/tish_ui/src/jsx.rs +692 -0
  160. package/crates/tish_ui/src/lib.rs +20 -0
  161. package/crates/tish_ui/src/runtime/hooks.rs +573 -0
  162. package/crates/tish_ui/src/runtime/mod.rs +183 -0
  163. package/crates/tish_vm/Cargo.toml +60 -0
  164. package/crates/tish_vm/src/jit.rs +1050 -0
  165. package/crates/tish_vm/src/lib.rs +41 -0
  166. package/crates/tish_vm/src/vm.rs +3536 -0
  167. package/crates/tish_vm/tests/concurrent_shared_state.rs +140 -0
  168. package/crates/tish_vm/tests/fixtures/or_string_cmd.tish +2 -0
  169. package/crates/tish_vm/tests/lexical_scope_declare.rs +34 -0
  170. package/crates/tish_vm/tests/peephole_jump_chain_logical_or.rs +150 -0
  171. package/crates/tish_wasm/Cargo.toml +15 -0
  172. package/crates/tish_wasm/src/lib.rs +428 -0
  173. package/crates/tish_wasm_runtime/Cargo.toml +37 -0
  174. package/crates/tish_wasm_runtime/src/gpu.rs +429 -0
  175. package/crates/tish_wasm_runtime/src/lib.rs +42 -0
  176. package/crates/tishlang_cargo_bindgen/Cargo.toml +26 -0
  177. package/crates/tishlang_cargo_bindgen/src/classify.rs +261 -0
  178. package/crates/tishlang_cargo_bindgen/src/discover.rs +125 -0
  179. package/crates/tishlang_cargo_bindgen/src/infer.rs +382 -0
  180. package/crates/tishlang_cargo_bindgen/src/lib.rs +349 -0
  181. package/crates/tishlang_cargo_bindgen/src/main.rs +167 -0
  182. package/crates/tishlang_cargo_bindgen/src/metadata.rs +117 -0
  183. package/justfile +276 -0
  184. package/package.json +2 -2
  185. package/platform/darwin-arm64/tish-fmt +0 -0
  186. package/platform/darwin-x64/tish-fmt +0 -0
  187. package/platform/linux-arm64/tish-fmt +0 -0
  188. package/platform/linux-x64/tish-fmt +0 -0
  189. package/platform/win32-x64/tish-fmt.exe +0 -0
@@ -0,0 +1,611 @@
1
+ //! Convert OXC expressions to Tish expressions.
2
+
3
+ use std::sync::Arc;
4
+
5
+ use oxc::ast::ast::Expression as OxcExpr;
6
+ use oxc::semantic::Semantic;
7
+ use tishlang_ast::{
8
+ ArrayElement, ArrowBody, BinOp, CompoundOp, DestructPattern, Expr, FunParam, Literal,
9
+ LogicalAssignOp, MemberProp, ObjectProp, TypedParam,
10
+ };
11
+
12
+ use crate::error::{ConvertError, ConvertErrorKind};
13
+ use crate::span_util;
14
+
15
+ type Ctx<'a> = (&'a Semantic<'a>, &'a str);
16
+
17
+ /// Convert OXC expression to Tish expression.
18
+ pub fn convert_expr(expr: &OxcExpr<'_>, ctx: &Ctx<'_>) -> Result<Expr, ConvertError> {
19
+ let span = span_util::oxc_span_to_tish(ctx.1, expr);
20
+ match expr {
21
+ OxcExpr::BooleanLiteral(b) => Ok(Expr::Literal {
22
+ value: Literal::Bool(b.value),
23
+ span,
24
+ }),
25
+ OxcExpr::NullLiteral(_) => Ok(Expr::Literal {
26
+ value: Literal::Null,
27
+ span,
28
+ }),
29
+ OxcExpr::NumericLiteral(n) => Ok(Expr::Literal {
30
+ value: Literal::Number(n.value),
31
+ span,
32
+ }),
33
+ OxcExpr::StringLiteral(s) => Ok(Expr::Literal {
34
+ value: Literal::String(Arc::from(s.value.as_str())),
35
+ span,
36
+ }),
37
+ OxcExpr::Identifier(id) => {
38
+ let name = id.name.as_str();
39
+ if name == "this" {
40
+ return Err(ConvertError::new(ConvertErrorKind::Incompatible {
41
+ what: "this".into(),
42
+ reason: "Tish does not support this".into(),
43
+ }));
44
+ }
45
+ if name == "arguments" {
46
+ return Err(ConvertError::new(ConvertErrorKind::Incompatible {
47
+ what: "arguments".into(),
48
+ reason: "Tish does not support arguments object".into(),
49
+ }));
50
+ }
51
+ Ok(Expr::Ident {
52
+ name: Arc::from(name),
53
+ span,
54
+ })
55
+ }
56
+ OxcExpr::BinaryExpression(b) => {
57
+ let left = Box::new(convert_expr(&b.left, ctx)?);
58
+ let right = Box::new(convert_expr(&b.right, ctx)?);
59
+ let op = convert_bin_op(&b.operator)?;
60
+ Ok(Expr::Binary {
61
+ left,
62
+ op,
63
+ right,
64
+ span,
65
+ })
66
+ }
67
+ OxcExpr::UnaryExpression(u) => {
68
+ let operand = Box::new(convert_expr(&u.argument, ctx)?);
69
+ let op = convert_unary_op(&u.operator)?;
70
+ Ok(Expr::Unary { op, operand, span })
71
+ }
72
+ OxcExpr::CallExpression(c) => {
73
+ let callee = Box::new(convert_expr(&c.callee, ctx)?);
74
+ let args = c
75
+ .arguments
76
+ .iter()
77
+ .map(|a| convert_call_arg(a, ctx))
78
+ .collect::<Result<Vec<_>, _>>()?;
79
+ Ok(Expr::Call { callee, args, span })
80
+ }
81
+ OxcExpr::NewExpression(n) => {
82
+ let callee = Box::new(convert_expr(&n.callee, ctx)?);
83
+ let args = n
84
+ .arguments
85
+ .iter()
86
+ .map(|a| convert_call_arg(a, ctx))
87
+ .collect::<Result<Vec<_>, _>>()?;
88
+ Ok(Expr::New { callee, args, span })
89
+ }
90
+ OxcExpr::StaticMemberExpression(s) => {
91
+ let object = Box::new(convert_expr(&s.object, ctx)?);
92
+ let name = Arc::from(s.property.name.as_str());
93
+ let name_span = span_util::oxc_span_to_tish(ctx.1, &s.property);
94
+ Ok(Expr::Member {
95
+ object,
96
+ prop: MemberProp::Name {
97
+ name,
98
+ span: name_span,
99
+ },
100
+ optional: s.optional,
101
+ span,
102
+ })
103
+ }
104
+ OxcExpr::ComputedMemberExpression(c) => {
105
+ let object = Box::new(convert_expr(&c.object, ctx)?);
106
+ Ok(Expr::Member {
107
+ object,
108
+ prop: MemberProp::Expr(Box::new(convert_expr(&c.expression, ctx)?)),
109
+ optional: c.optional,
110
+ span,
111
+ })
112
+ }
113
+ OxcExpr::ConditionalExpression(c) => {
114
+ let cond = Box::new(convert_expr(&c.test, ctx)?);
115
+ let then_branch = Box::new(convert_expr(&c.consequent, ctx)?);
116
+ let else_branch = Box::new(convert_expr(&c.alternate, ctx)?);
117
+ Ok(Expr::Conditional {
118
+ cond,
119
+ then_branch,
120
+ else_branch,
121
+ span,
122
+ })
123
+ }
124
+ OxcExpr::LogicalExpression(l) => {
125
+ if matches!(l.operator, oxc::ast::ast::LogicalOperator::Coalesce) {
126
+ Ok(Expr::NullishCoalesce {
127
+ left: Box::new(convert_expr(&l.left, ctx)?),
128
+ right: Box::new(convert_expr(&l.right, ctx)?),
129
+ span,
130
+ })
131
+ } else {
132
+ let op = match l.operator {
133
+ oxc::ast::ast::LogicalOperator::And => BinOp::And,
134
+ oxc::ast::ast::LogicalOperator::Or => BinOp::Or,
135
+ _ => BinOp::Or,
136
+ };
137
+ Ok(Expr::Binary {
138
+ left: Box::new(convert_expr(&l.left, ctx)?),
139
+ op,
140
+ right: Box::new(convert_expr(&l.right, ctx)?),
141
+ span,
142
+ })
143
+ }
144
+ }
145
+ OxcExpr::AssignmentExpression(a) => convert_assignment(a, ctx, span),
146
+ OxcExpr::ArrayExpression(arr) => {
147
+ let elements = arr
148
+ .elements
149
+ .iter()
150
+ .map(|e| convert_array_element(e, ctx))
151
+ .collect::<Result<Vec<_>, _>>()?;
152
+ Ok(Expr::Array { elements, span })
153
+ }
154
+ OxcExpr::ObjectExpression(obj) => {
155
+ let props = obj
156
+ .properties
157
+ .iter()
158
+ .map(|p| convert_object_prop(p, ctx))
159
+ .collect::<Result<Vec<_>, _>>()?;
160
+ Ok(Expr::Object { props, span })
161
+ }
162
+ OxcExpr::ArrowFunctionExpression(arrow) => {
163
+ let params = convert_arrow_params(&arrow.params, ctx)?;
164
+ let body = if arrow.expression {
165
+ let e = arrow.get_expression().ok_or_else(|| {
166
+ ConvertError::new(ConvertErrorKind::Incompatible {
167
+ what: "arrow expression body".into(),
168
+ reason: "expected expression".into(),
169
+ })
170
+ })?;
171
+ ArrowBody::Expr(Box::new(convert_expr(e, ctx)?))
172
+ } else {
173
+ let stmts = super::stmt::convert_statements(&arrow.body.statements, ctx.0, ctx.1)?;
174
+ ArrowBody::Block(Box::new(tishlang_ast::Statement::Block {
175
+ statements: stmts,
176
+ span: span_util::oxc_span_to_tish(ctx.1, &*arrow.body),
177
+ }))
178
+ };
179
+ Ok(Expr::ArrowFunction { params, body, span })
180
+ }
181
+ OxcExpr::AwaitExpression(a) => Ok(Expr::Await {
182
+ operand: Box::new(convert_expr(&a.argument, ctx)?),
183
+ span,
184
+ }),
185
+ OxcExpr::TemplateLiteral(t) => {
186
+ let mut quasis = Vec::new();
187
+ let mut exprs = Vec::new();
188
+ for q in &t.quasis {
189
+ quasis.push(Arc::from(q.value.raw.as_str()));
190
+ }
191
+ for e in &t.expressions {
192
+ exprs.push(convert_expr(e, ctx)?);
193
+ }
194
+ Ok(Expr::TemplateLiteral {
195
+ quasis,
196
+ exprs,
197
+ span,
198
+ })
199
+ }
200
+ OxcExpr::ChainExpression(c) => convert_chain_element(&c.expression, ctx, span),
201
+ OxcExpr::UpdateExpression(u) => convert_update_expr(u, ctx, span),
202
+ OxcExpr::SequenceExpression(s) => {
203
+ // (a, b, c) -> convert last expr
204
+ if let Some(last) = s.expressions.iter().last() {
205
+ convert_expr(last, ctx)
206
+ } else {
207
+ Err(ConvertError::new(ConvertErrorKind::Incompatible {
208
+ what: "empty sequence".into(),
209
+ reason: "invalid".into(),
210
+ }))
211
+ }
212
+ }
213
+ OxcExpr::FunctionExpression(f) => {
214
+ // Convert to ArrowFunction-like; Tish doesn't have function expressions per se
215
+ // Use ArrowFunction with block body. FunctionBody is a struct with .statements.
216
+ let params = convert_params(&f.params, ctx)?.0;
217
+ let body = match &f.body {
218
+ Some(fb) => {
219
+ let stmts = super::stmt::convert_statements(&fb.statements, ctx.0, ctx.1)?;
220
+ ArrowBody::Block(Box::new(tishlang_ast::Statement::Block {
221
+ statements: stmts,
222
+ span: span_util::oxc_span_to_tish(ctx.1, fb.as_ref()),
223
+ }))
224
+ }
225
+ None => {
226
+ return Err(ConvertError::new(ConvertErrorKind::Incompatible {
227
+ what: "function expression body".into(),
228
+ reason: "expected block".into(),
229
+ }))
230
+ }
231
+ };
232
+ Ok(Expr::ArrowFunction { params, body, span })
233
+ }
234
+ _ => Err(ConvertError::new(ConvertErrorKind::Unsupported {
235
+ what: format!("expression: {:?}", std::mem::discriminant(expr)),
236
+ hint: None,
237
+ })),
238
+ }
239
+ }
240
+
241
+ fn convert_chain_element(
242
+ ce: &oxc::ast::ast::ChainElement<'_>,
243
+ ctx: &Ctx<'_>,
244
+ span: tishlang_ast::Span,
245
+ ) -> Result<Expr, ConvertError> {
246
+ match ce {
247
+ oxc::ast::ast::ChainElement::StaticMemberExpression(m) => {
248
+ let object = Box::new(convert_expr(&m.object, ctx)?);
249
+ let name = Arc::from(m.property.name.as_str());
250
+ let name_span = span_util::oxc_span_to_tish(ctx.1, &m.property);
251
+ Ok(Expr::Member {
252
+ object,
253
+ prop: MemberProp::Name {
254
+ name,
255
+ span: name_span,
256
+ },
257
+ optional: m.optional,
258
+ span,
259
+ })
260
+ }
261
+ oxc::ast::ast::ChainElement::ComputedMemberExpression(m) => {
262
+ let object = Box::new(convert_expr(&m.object, ctx)?);
263
+ Ok(Expr::Member {
264
+ object,
265
+ prop: MemberProp::Expr(Box::new(convert_expr(&m.expression, ctx)?)),
266
+ optional: m.optional,
267
+ span,
268
+ })
269
+ }
270
+ oxc::ast::ast::ChainElement::CallExpression(call) => {
271
+ let callee = Box::new(convert_expr(&call.callee, ctx)?);
272
+ let args = call
273
+ .arguments
274
+ .iter()
275
+ .map(|a| convert_call_arg(a, ctx))
276
+ .collect::<Result<Vec<_>, _>>()?;
277
+ Ok(Expr::Call { callee, args, span })
278
+ }
279
+ _ => Err(ConvertError::new(ConvertErrorKind::Unsupported {
280
+ what: "chain expression element (e.g. TSNonNull, PrivateField)".into(),
281
+ hint: None,
282
+ })),
283
+ }
284
+ }
285
+
286
+ fn convert_call_arg(
287
+ arg: &oxc::ast::ast::Argument<'_>,
288
+ ctx: &Ctx<'_>,
289
+ ) -> Result<tishlang_ast::CallArg, ConvertError> {
290
+ if arg.is_spread() {
291
+ if let oxc::ast::ast::Argument::SpreadElement(s) = arg {
292
+ Ok(tishlang_ast::CallArg::Spread(convert_expr(
293
+ &s.argument,
294
+ ctx,
295
+ )?))
296
+ } else {
297
+ unreachable!()
298
+ }
299
+ } else if let Some(e) = arg.as_expression() {
300
+ Ok(tishlang_ast::CallArg::Expr(convert_expr(e, ctx)?))
301
+ } else {
302
+ Err(ConvertError::new(ConvertErrorKind::Unsupported {
303
+ what: "call argument".into(),
304
+ hint: None,
305
+ }))
306
+ }
307
+ }
308
+
309
+ fn convert_array_element(
310
+ el: &oxc::ast::ast::ArrayExpressionElement<'_>,
311
+ ctx: &Ctx<'_>,
312
+ ) -> Result<ArrayElement, ConvertError> {
313
+ match el {
314
+ oxc::ast::ast::ArrayExpressionElement::SpreadElement(s) => {
315
+ Ok(ArrayElement::Spread(convert_expr(&s.argument, ctx)?))
316
+ }
317
+ oxc::ast::ast::ArrayExpressionElement::Elision(_) => {
318
+ Ok(ArrayElement::Expr(Expr::Literal {
319
+ value: Literal::Null,
320
+ span: span_util::stub_span(),
321
+ }))
322
+ }
323
+ _ => {
324
+ if let Some(e) = el.as_expression() {
325
+ Ok(ArrayElement::Expr(convert_expr(e, ctx)?))
326
+ } else {
327
+ Err(ConvertError::new(ConvertErrorKind::Unsupported {
328
+ what: "array element".into(),
329
+ hint: None,
330
+ }))
331
+ }
332
+ }
333
+ }
334
+ }
335
+
336
+ fn convert_object_prop(
337
+ p: &oxc::ast::ast::ObjectPropertyKind<'_>,
338
+ ctx: &Ctx<'_>,
339
+ ) -> Result<ObjectProp, ConvertError> {
340
+ match p {
341
+ oxc::ast::ast::ObjectPropertyKind::SpreadProperty(s) => {
342
+ Ok(ObjectProp::Spread(convert_expr(&s.argument, ctx)?))
343
+ }
344
+ oxc::ast::ast::ObjectPropertyKind::ObjectProperty(prop) => {
345
+ let key = prop.key.name().map(|n| n.to_string()).unwrap_or_else(|| {
346
+ if let oxc::ast::ast::PropertyKey::Identifier(id) = &prop.key {
347
+ id.name.to_string()
348
+ } else {
349
+ "key".to_string()
350
+ }
351
+ });
352
+ let value = convert_expr(&prop.value, ctx)?;
353
+ Ok(ObjectProp::KeyValue(Arc::from(key.as_str()), value))
354
+ }
355
+ }
356
+ }
357
+
358
+ fn convert_assignment(
359
+ a: &oxc::ast::ast::AssignmentExpression<'_>,
360
+ ctx: &Ctx<'_>,
361
+ span: tishlang_ast::Span,
362
+ ) -> Result<Expr, ConvertError> {
363
+ let (left, right) = (&a.left, &a.right);
364
+ if let Some(oxc::ast::ast::SimpleAssignmentTarget::AssignmentTargetIdentifier(id)) =
365
+ left.as_simple_assignment_target()
366
+ {
367
+ let name = id.name.as_str();
368
+ let value = Box::new(convert_expr(right, ctx)?);
369
+ return match &a.operator {
370
+ oxc::ast::ast::AssignmentOperator::Assign => Ok(Expr::Assign {
371
+ name: Arc::from(name),
372
+ value,
373
+ span,
374
+ }),
375
+ oxc::ast::ast::AssignmentOperator::Addition => Ok(Expr::CompoundAssign {
376
+ name: Arc::from(name),
377
+ op: CompoundOp::Add,
378
+ value,
379
+ span,
380
+ }),
381
+ oxc::ast::ast::AssignmentOperator::Subtraction => Ok(Expr::CompoundAssign {
382
+ name: Arc::from(name),
383
+ op: CompoundOp::Sub,
384
+ value,
385
+ span,
386
+ }),
387
+ oxc::ast::ast::AssignmentOperator::Multiplication => Ok(Expr::CompoundAssign {
388
+ name: Arc::from(name),
389
+ op: CompoundOp::Mul,
390
+ value,
391
+ span,
392
+ }),
393
+ oxc::ast::ast::AssignmentOperator::Division => Ok(Expr::CompoundAssign {
394
+ name: Arc::from(name),
395
+ op: CompoundOp::Div,
396
+ value,
397
+ span,
398
+ }),
399
+ oxc::ast::ast::AssignmentOperator::Remainder => Ok(Expr::CompoundAssign {
400
+ name: Arc::from(name),
401
+ op: CompoundOp::Mod,
402
+ value,
403
+ span,
404
+ }),
405
+ oxc::ast::ast::AssignmentOperator::LogicalAnd => Ok(Expr::LogicalAssign {
406
+ name: Arc::from(name),
407
+ op: LogicalAssignOp::AndAnd,
408
+ value,
409
+ span,
410
+ }),
411
+ oxc::ast::ast::AssignmentOperator::LogicalOr => Ok(Expr::LogicalAssign {
412
+ name: Arc::from(name),
413
+ op: LogicalAssignOp::OrOr,
414
+ value,
415
+ span,
416
+ }),
417
+ oxc::ast::ast::AssignmentOperator::LogicalNullish => Ok(Expr::LogicalAssign {
418
+ name: Arc::from(name),
419
+ op: LogicalAssignOp::Nullish,
420
+ value,
421
+ span,
422
+ }),
423
+ _ => Err(ConvertError::new(ConvertErrorKind::Unsupported {
424
+ what: "assignment operator".into(),
425
+ hint: None,
426
+ })),
427
+ };
428
+ }
429
+ Err(ConvertError::new(ConvertErrorKind::Unsupported {
430
+ what: "complex assignment target".into(),
431
+ hint: None,
432
+ }))
433
+ }
434
+
435
+ fn convert_update_expr(
436
+ u: &oxc::ast::ast::UpdateExpression<'_>,
437
+ _ctx: &Ctx<'_>,
438
+ span: tishlang_ast::Span,
439
+ ) -> Result<Expr, ConvertError> {
440
+ let name: Arc<str> = match &u.argument {
441
+ oxc::ast::ast::SimpleAssignmentTarget::AssignmentTargetIdentifier(id) => {
442
+ Arc::from(id.name.as_str())
443
+ }
444
+ _ => {
445
+ return Err(ConvertError::new(ConvertErrorKind::Unsupported {
446
+ what: "update expression on non-identifier".into(),
447
+ hint: None,
448
+ }))
449
+ }
450
+ };
451
+ Ok(match (u.operator, u.prefix) {
452
+ (oxc::ast::ast::UpdateOperator::Increment, true) => Expr::PrefixInc { name, span },
453
+ (oxc::ast::ast::UpdateOperator::Increment, false) => Expr::PostfixInc { name, span },
454
+ (oxc::ast::ast::UpdateOperator::Decrement, true) => Expr::PrefixDec { name, span },
455
+ (oxc::ast::ast::UpdateOperator::Decrement, false) => Expr::PostfixDec { name, span },
456
+ })
457
+ }
458
+
459
+ fn convert_bin_op(op: &oxc::ast::ast::BinaryOperator) -> Result<BinOp, ConvertError> {
460
+ Ok(match op {
461
+ oxc::ast::ast::BinaryOperator::Equality => BinOp::Eq,
462
+ oxc::ast::ast::BinaryOperator::Inequality => BinOp::Ne,
463
+ oxc::ast::ast::BinaryOperator::StrictEquality => BinOp::StrictEq,
464
+ oxc::ast::ast::BinaryOperator::StrictInequality => BinOp::StrictNe,
465
+ oxc::ast::ast::BinaryOperator::LessThan => BinOp::Lt,
466
+ oxc::ast::ast::BinaryOperator::LessEqualThan => BinOp::Le,
467
+ oxc::ast::ast::BinaryOperator::GreaterThan => BinOp::Gt,
468
+ oxc::ast::ast::BinaryOperator::GreaterEqualThan => BinOp::Ge,
469
+ oxc::ast::ast::BinaryOperator::Addition => BinOp::Add,
470
+ oxc::ast::ast::BinaryOperator::Subtraction => BinOp::Sub,
471
+ oxc::ast::ast::BinaryOperator::Multiplication => BinOp::Mul,
472
+ oxc::ast::ast::BinaryOperator::Division => BinOp::Div,
473
+ oxc::ast::ast::BinaryOperator::Remainder => BinOp::Mod,
474
+ oxc::ast::ast::BinaryOperator::Exponential => BinOp::Pow,
475
+ oxc::ast::ast::BinaryOperator::BitwiseAnd => BinOp::BitAnd,
476
+ oxc::ast::ast::BinaryOperator::BitwiseOR => BinOp::BitOr,
477
+ oxc::ast::ast::BinaryOperator::BitwiseXOR => BinOp::BitXor,
478
+ oxc::ast::ast::BinaryOperator::ShiftLeft => BinOp::Shl,
479
+ oxc::ast::ast::BinaryOperator::ShiftRight => BinOp::Shr,
480
+ oxc::ast::ast::BinaryOperator::ShiftRightZeroFill => BinOp::UShr,
481
+ _ => {
482
+ return Err(ConvertError::new(ConvertErrorKind::Unsupported {
483
+ what: format!("binary operator: {op:?}"),
484
+ hint: None,
485
+ }))
486
+ }
487
+ })
488
+ }
489
+
490
+ fn convert_unary_op(
491
+ op: &oxc::ast::ast::UnaryOperator,
492
+ ) -> Result<tishlang_ast::UnaryOp, ConvertError> {
493
+ Ok(match op {
494
+ oxc::ast::ast::UnaryOperator::LogicalNot => tishlang_ast::UnaryOp::Not,
495
+ oxc::ast::ast::UnaryOperator::UnaryNegation => tishlang_ast::UnaryOp::Neg,
496
+ oxc::ast::ast::UnaryOperator::UnaryPlus => tishlang_ast::UnaryOp::Pos,
497
+ oxc::ast::ast::UnaryOperator::BitwiseNot => tishlang_ast::UnaryOp::BitNot,
498
+ oxc::ast::ast::UnaryOperator::Void => tishlang_ast::UnaryOp::Void,
499
+ _ => {
500
+ return Err(ConvertError::new(ConvertErrorKind::Unsupported {
501
+ what: format!("unary operator: {op:?}"),
502
+ hint: None,
503
+ }))
504
+ }
505
+ })
506
+ }
507
+
508
+ /// Convert function/arrow params to TypedParam list.
509
+ pub fn convert_params(
510
+ params: &oxc::ast::ast::FormalParameters<'_>,
511
+ ctx: &Ctx<'_>,
512
+ ) -> Result<(Vec<FunParam>, Option<TypedParam>), ConvertError> {
513
+ let mut typed_params = Vec::new();
514
+ let mut rest_param = None;
515
+ for (i, p) in params.items.iter().enumerate() {
516
+ if params.rest.is_some() && i == params.items.len() - 1 {
517
+ if let Some(rest) = &params.rest {
518
+ let (rest_name, rest_name_span) = match &rest.rest.argument {
519
+ oxc::ast::ast::BindingPattern::BindingIdentifier(b) => (
520
+ b.name.as_str(),
521
+ crate::span_util::oxc_span_to_tish(ctx.1, b.as_ref()),
522
+ ),
523
+ _ => {
524
+ return Err(ConvertError::new(ConvertErrorKind::Unsupported {
525
+ what: "rest param with non-identifier".into(),
526
+ hint: None,
527
+ }))
528
+ }
529
+ };
530
+ rest_param = Some(TypedParam {
531
+ name: Arc::from(rest_name),
532
+ name_span: rest_name_span,
533
+ type_ann: None,
534
+ default: None,
535
+ });
536
+ }
537
+ break;
538
+ }
539
+ // params.items contains FormalParameter structs (not enum)
540
+ let fp = p;
541
+ {
542
+ let (name, name_span) = match &fp.pattern {
543
+ oxc::ast::ast::BindingPattern::BindingIdentifier(b) => (
544
+ b.name.as_str(),
545
+ crate::span_util::oxc_span_to_tish(ctx.1, b.as_ref()),
546
+ ),
547
+ _ => {
548
+ return Err(ConvertError::new(ConvertErrorKind::Unsupported {
549
+ what: "destructuring in params".into(),
550
+ hint: None,
551
+ }))
552
+ }
553
+ };
554
+ let default = fp
555
+ .initializer
556
+ .as_ref()
557
+ .map(|e| convert_expr(e, ctx))
558
+ .transpose()?;
559
+ typed_params.push(FunParam::Simple(TypedParam {
560
+ name: Arc::from(name),
561
+ name_span,
562
+ type_ann: None,
563
+ default,
564
+ }));
565
+ }
566
+ }
567
+ if rest_param.is_none() {
568
+ if let Some(rest) = &params.rest {
569
+ let (rest_name, rest_name_span) = match &rest.rest.argument {
570
+ oxc::ast::ast::BindingPattern::BindingIdentifier(b) => (
571
+ b.name.as_str(),
572
+ crate::span_util::oxc_span_to_tish(ctx.1, b.as_ref()),
573
+ ),
574
+ _ => {
575
+ return Err(ConvertError::new(ConvertErrorKind::Unsupported {
576
+ what: "rest param with non-identifier".into(),
577
+ hint: None,
578
+ }));
579
+ }
580
+ };
581
+ rest_param = Some(TypedParam {
582
+ name: Arc::from(rest_name),
583
+ name_span: rest_name_span,
584
+ type_ann: None,
585
+ default: None,
586
+ });
587
+ }
588
+ }
589
+ Ok((typed_params, rest_param))
590
+ }
591
+
592
+ fn convert_arrow_params(
593
+ params: &oxc::ast::ast::FormalParameters<'_>,
594
+ ctx: &Ctx<'_>,
595
+ ) -> Result<Vec<FunParam>, ConvertError> {
596
+ let (mut ps, rest) = convert_params(params, ctx)?;
597
+ if let Some(r) = rest {
598
+ ps.push(FunParam::Simple(r));
599
+ }
600
+ Ok(ps)
601
+ }
602
+
603
+ /// Convert binding pattern to Tish DestructPattern.
604
+ pub fn convert_destruct_pattern(
605
+ _pattern: &oxc::ast::ast::BindingPattern<'_>,
606
+ ) -> Result<DestructPattern, ConvertError> {
607
+ Err(ConvertError::new(ConvertErrorKind::Unsupported {
608
+ what: "destructuring in variable declaration".into(),
609
+ hint: Some("use simple identifier for now".into()),
610
+ }))
611
+ }