@tsonic/emitter 0.0.61 → 0.0.63

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 (531) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/adapter-generator.d.ts +5 -15
  3. package/dist/adapter-generator.d.ts.map +1 -1
  4. package/dist/adapter-generator.js +60 -53
  5. package/dist/adapter-generator.js.map +1 -1
  6. package/dist/contracts/backend-adapter.d.ts +36 -0
  7. package/dist/contracts/backend-adapter.d.ts.map +1 -0
  8. package/dist/contracts/backend-adapter.js +9 -0
  9. package/dist/contracts/backend-adapter.js.map +1 -0
  10. package/dist/contracts/emitter-contract.d.ts +54 -0
  11. package/dist/contracts/emitter-contract.d.ts.map +1 -0
  12. package/dist/contracts/emitter-contract.js +8 -0
  13. package/dist/contracts/emitter-contract.js.map +1 -0
  14. package/dist/contracts/import-classifier.d.ts +36 -0
  15. package/dist/contracts/import-classifier.d.ts.map +1 -0
  16. package/dist/contracts/import-classifier.js +9 -0
  17. package/dist/contracts/import-classifier.js.map +1 -0
  18. package/dist/core/{attributes.d.ts → format/attributes.d.ts} +9 -14
  19. package/dist/core/format/attributes.d.ts.map +1 -0
  20. package/dist/core/format/attributes.js +190 -0
  21. package/dist/core/format/attributes.js.map +1 -0
  22. package/dist/core/format/attributes.test.d.ts.map +1 -0
  23. package/dist/core/{attributes.test.js → format/attributes.test.js} +70 -32
  24. package/dist/core/format/attributes.test.js.map +1 -0
  25. package/dist/core/format/backend-ast/index.d.ts +7 -0
  26. package/dist/core/format/backend-ast/index.d.ts.map +1 -0
  27. package/dist/core/format/backend-ast/index.js +6 -0
  28. package/dist/core/format/backend-ast/index.js.map +1 -0
  29. package/dist/core/format/backend-ast/printer.d.ts +33 -0
  30. package/dist/core/format/backend-ast/printer.d.ts.map +1 -0
  31. package/dist/core/format/backend-ast/printer.js +1151 -0
  32. package/dist/core/format/backend-ast/printer.js.map +1 -0
  33. package/dist/core/format/backend-ast/types.d.ts +504 -0
  34. package/dist/core/format/backend-ast/types.d.ts.map +1 -0
  35. package/dist/core/format/backend-ast/types.js +13 -0
  36. package/dist/core/format/backend-ast/types.js.map +1 -0
  37. package/dist/core/format/backend-ast/utils.d.ts +26 -0
  38. package/dist/core/format/backend-ast/utils.d.ts.map +1 -0
  39. package/dist/core/format/backend-ast/utils.js +65 -0
  40. package/dist/core/format/backend-ast/utils.js.map +1 -0
  41. package/dist/core/{exports.d.ts → format/exports.d.ts} +2 -2
  42. package/dist/core/format/exports.d.ts.map +1 -0
  43. package/dist/core/format/exports.js +22 -0
  44. package/dist/core/format/exports.js.map +1 -0
  45. package/dist/core/format/index.d.ts +9 -0
  46. package/dist/core/format/index.d.ts.map +1 -0
  47. package/dist/core/format/index.js +9 -0
  48. package/dist/core/format/index.js.map +1 -0
  49. package/dist/core/{local-names.d.ts → format/local-names.d.ts} +1 -1
  50. package/dist/core/format/local-names.d.ts.map +1 -0
  51. package/dist/core/{local-names.js → format/local-names.js} +3 -2
  52. package/dist/core/format/local-names.js.map +1 -0
  53. package/dist/core/format/module-emitter/assembly.d.ts +27 -0
  54. package/dist/core/format/module-emitter/assembly.d.ts.map +1 -0
  55. package/dist/core/format/module-emitter/assembly.js +44 -0
  56. package/dist/core/format/module-emitter/assembly.js.map +1 -0
  57. package/dist/core/{module-emitter → format/module-emitter}/header.d.ts +1 -1
  58. package/dist/core/format/module-emitter/header.d.ts.map +1 -0
  59. package/dist/core/{module-emitter → format/module-emitter}/header.js +1 -1
  60. package/dist/core/format/module-emitter/header.js.map +1 -0
  61. package/dist/core/format/module-emitter/index.d.ts.map +1 -0
  62. package/dist/core/format/module-emitter/index.js.map +1 -0
  63. package/dist/core/format/module-emitter/namespace.d.ts +21 -0
  64. package/dist/core/format/module-emitter/namespace.d.ts.map +1 -0
  65. package/dist/core/format/module-emitter/namespace.js +58 -0
  66. package/dist/core/format/module-emitter/namespace.js.map +1 -0
  67. package/dist/core/{module-emitter → format/module-emitter}/orchestrator.d.ts +1 -1
  68. package/dist/core/format/module-emitter/orchestrator.d.ts.map +1 -0
  69. package/dist/core/format/module-emitter/orchestrator.js +254 -0
  70. package/dist/core/format/module-emitter/orchestrator.js.map +1 -0
  71. package/dist/core/format/module-emitter/separation.d.ts.map +1 -0
  72. package/dist/core/format/module-emitter/separation.js.map +1 -0
  73. package/dist/core/{module-emitter → format/module-emitter}/static-container.d.ts +8 -3
  74. package/dist/core/format/module-emitter/static-container.d.ts.map +1 -0
  75. package/dist/core/format/module-emitter/static-container.js +202 -0
  76. package/dist/core/format/module-emitter/static-container.js.map +1 -0
  77. package/dist/core/format/module-emitter.d.ts.map +1 -0
  78. package/dist/core/format/module-emitter.js.map +1 -0
  79. package/dist/core/{options.d.ts → format/options.d.ts} +1 -1
  80. package/dist/core/format/options.d.ts.map +1 -0
  81. package/dist/core/format/options.js.map +1 -0
  82. package/dist/core/index.d.ts +2 -7
  83. package/dist/core/index.d.ts.map +1 -1
  84. package/dist/core/index.js +2 -7
  85. package/dist/core/index.js.map +1 -1
  86. package/dist/core/module-emitter.test.js.map +1 -1
  87. package/dist/core/semantic/boolean-context.d.ts +44 -0
  88. package/dist/core/semantic/boolean-context.d.ts.map +1 -0
  89. package/dist/core/semantic/boolean-context.js +655 -0
  90. package/dist/core/semantic/boolean-context.js.map +1 -0
  91. package/dist/core/semantic/boolean-context.test.d.ts.map +1 -0
  92. package/dist/core/{boolean-context.test.js → semantic/boolean-context.test.js} +56 -103
  93. package/dist/core/semantic/boolean-context.test.js.map +1 -0
  94. package/dist/core/{imports.d.ts → semantic/imports.d.ts} +1 -5
  95. package/dist/core/semantic/imports.d.ts.map +1 -0
  96. package/dist/core/{imports.js → semantic/imports.js} +9 -78
  97. package/dist/core/semantic/imports.js.map +1 -0
  98. package/dist/core/semantic/imports.test.d.ts.map +1 -0
  99. package/dist/core/{imports.test.js → semantic/imports.test.js} +1 -1
  100. package/dist/core/semantic/imports.test.js.map +1 -0
  101. package/dist/core/semantic/index.d.ts +15 -0
  102. package/dist/core/semantic/index.d.ts.map +1 -0
  103. package/dist/core/semantic/index.js +15 -0
  104. package/dist/core/semantic/index.js.map +1 -0
  105. package/dist/core/{local-types.d.ts → semantic/local-types.d.ts} +1 -1
  106. package/dist/core/semantic/local-types.d.ts.map +1 -0
  107. package/dist/core/semantic/local-types.js.map +1 -0
  108. package/dist/core/{module-map.d.ts → semantic/module-map.d.ts} +1 -1
  109. package/dist/core/semantic/module-map.d.ts.map +1 -0
  110. package/dist/core/semantic/module-map.js.map +1 -0
  111. package/dist/core/semantic/module-map.test.d.ts.map +1 -0
  112. package/dist/core/semantic/module-map.test.js.map +1 -0
  113. package/dist/core/semantic/naming-collisions.d.ts.map +1 -0
  114. package/dist/core/{naming-collisions.js → semantic/naming-collisions.js} +3 -2
  115. package/dist/core/semantic/naming-collisions.js.map +1 -0
  116. package/dist/core/{type-alias-index.d.ts → semantic/type-alias-index.d.ts} +1 -1
  117. package/dist/core/semantic/type-alias-index.d.ts.map +1 -0
  118. package/dist/core/semantic/type-alias-index.js.map +1 -0
  119. package/dist/core/semantic/type-compatibility.d.ts.map +1 -0
  120. package/dist/core/semantic/type-compatibility.js.map +1 -0
  121. package/dist/core/{type-member-index.d.ts → semantic/type-member-index.d.ts} +1 -1
  122. package/dist/core/semantic/type-member-index.d.ts.map +1 -0
  123. package/dist/core/semantic/type-member-index.js.map +1 -0
  124. package/dist/core/semantic/type-params.d.ts.map +1 -0
  125. package/dist/core/semantic/type-params.js.map +1 -0
  126. package/dist/core/{type-resolution.d.ts → semantic/type-resolution.d.ts} +3 -6
  127. package/dist/core/semantic/type-resolution.d.ts.map +1 -0
  128. package/dist/core/{type-resolution.js → semantic/type-resolution.js} +78 -47
  129. package/dist/core/semantic/type-resolution.js.map +1 -0
  130. package/dist/core/semantic/type-resolution.test.d.ts.map +1 -0
  131. package/dist/core/{type-resolution.test.js → semantic/type-resolution.test.js} +155 -20
  132. package/dist/core/semantic/type-resolution.test.js.map +1 -0
  133. package/dist/core/semantic/unsafe.d.ts.map +1 -0
  134. package/dist/core/{unsafe.js → semantic/unsafe.js} +8 -6
  135. package/dist/core/semantic/unsafe.js.map +1 -0
  136. package/dist/emitter-types/core.d.ts +50 -12
  137. package/dist/emitter-types/core.d.ts.map +1 -1
  138. package/dist/emitter-types/index.d.ts +1 -1
  139. package/dist/emitter-types/index.d.ts.map +1 -1
  140. package/dist/emitter-types/index.js.map +1 -1
  141. package/dist/emitter.d.ts +1 -1
  142. package/dist/emitter.d.ts.map +1 -1
  143. package/dist/emitter.js +216 -16
  144. package/dist/emitter.js.map +1 -1
  145. package/dist/expression-emitter.d.ts +10 -5
  146. package/dist/expression-emitter.d.ts.map +1 -1
  147. package/dist/expression-emitter.js +135 -121
  148. package/dist/expression-emitter.js.map +1 -1
  149. package/dist/expressions/access.d.ts +4 -3
  150. package/dist/expressions/access.d.ts.map +1 -1
  151. package/dist/expressions/access.js +299 -109
  152. package/dist/expressions/access.js.map +1 -1
  153. package/dist/expressions/calls/call-analysis.d.ts +86 -0
  154. package/dist/expressions/calls/call-analysis.d.ts.map +1 -0
  155. package/dist/expressions/calls/call-analysis.js +284 -0
  156. package/dist/expressions/calls/call-analysis.js.map +1 -0
  157. package/dist/expressions/calls/call-emitter.d.ts +13 -0
  158. package/dist/expressions/calls/call-emitter.d.ts.map +1 -0
  159. package/dist/expressions/calls/call-emitter.js +876 -0
  160. package/dist/expressions/calls/call-emitter.js.map +1 -0
  161. package/dist/expressions/calls/new-emitter.d.ts +13 -0
  162. package/dist/expressions/calls/new-emitter.d.ts.map +1 -0
  163. package/dist/expressions/calls/new-emitter.js +641 -0
  164. package/dist/expressions/calls/new-emitter.js.map +1 -0
  165. package/dist/expressions/calls.d.ts +2 -14
  166. package/dist/expressions/calls.d.ts.map +1 -1
  167. package/dist/expressions/calls.js +2 -744
  168. package/dist/expressions/calls.js.map +1 -1
  169. package/dist/expressions/collections.d.ts +6 -16
  170. package/dist/expressions/collections.d.ts.map +1 -1
  171. package/dist/expressions/collections.js +303 -218
  172. package/dist/expressions/collections.js.map +1 -1
  173. package/dist/expressions/functions.d.ts +6 -5
  174. package/dist/expressions/functions.d.ts.map +1 -1
  175. package/dist/expressions/functions.js +57 -62
  176. package/dist/expressions/functions.js.map +1 -1
  177. package/dist/expressions/identifiers.d.ts +11 -6
  178. package/dist/expressions/identifiers.d.ts.map +1 -1
  179. package/dist/expressions/identifiers.js +81 -25
  180. package/dist/expressions/identifiers.js.map +1 -1
  181. package/dist/expressions/index.d.ts +1 -1
  182. package/dist/expressions/index.d.ts.map +1 -1
  183. package/dist/expressions/index.js +1 -1
  184. package/dist/expressions/index.js.map +1 -1
  185. package/dist/expressions/index.test.js +522 -3
  186. package/dist/expressions/index.test.js.map +1 -1
  187. package/dist/expressions/literals.d.ts +4 -3
  188. package/dist/expressions/literals.d.ts.map +1 -1
  189. package/dist/expressions/literals.js +25 -17
  190. package/dist/expressions/literals.js.map +1 -1
  191. package/dist/expressions/literals.test.js +18 -18
  192. package/dist/expressions/literals.test.js.map +1 -1
  193. package/dist/expressions/operators/assignment-emitter.d.ts +16 -0
  194. package/dist/expressions/operators/assignment-emitter.d.ts.map +1 -0
  195. package/dist/expressions/operators/assignment-emitter.js +118 -0
  196. package/dist/expressions/operators/assignment-emitter.js.map +1 -0
  197. package/dist/expressions/operators/binary-emitter.d.ts +33 -0
  198. package/dist/expressions/operators/binary-emitter.d.ts.map +1 -0
  199. package/dist/expressions/operators/binary-emitter.js +398 -0
  200. package/dist/expressions/operators/binary-emitter.js.map +1 -0
  201. package/dist/expressions/operators/conditional-emitter.d.ts +17 -0
  202. package/dist/expressions/operators/conditional-emitter.d.ts.map +1 -0
  203. package/dist/expressions/operators/conditional-emitter.js +306 -0
  204. package/dist/expressions/operators/conditional-emitter.js.map +1 -0
  205. package/dist/expressions/operators/helpers.d.ts +37 -0
  206. package/dist/expressions/operators/helpers.d.ts.map +1 -0
  207. package/dist/expressions/operators/helpers.js +136 -0
  208. package/dist/expressions/operators/helpers.js.map +1 -0
  209. package/dist/expressions/operators/logical-emitter.d.ts +23 -0
  210. package/dist/expressions/operators/logical-emitter.d.ts.map +1 -0
  211. package/dist/expressions/operators/logical-emitter.js +73 -0
  212. package/dist/expressions/operators/logical-emitter.js.map +1 -0
  213. package/dist/expressions/operators/unary-emitter.d.ts +30 -0
  214. package/dist/expressions/operators/unary-emitter.d.ts.map +1 -0
  215. package/dist/expressions/operators/unary-emitter.js +244 -0
  216. package/dist/expressions/operators/unary-emitter.js.map +1 -0
  217. package/dist/expressions/operators.d.ts +5 -81
  218. package/dist/expressions/operators.d.ts.map +1 -1
  219. package/dist/expressions/operators.js +5 -868
  220. package/dist/expressions/operators.js.map +1 -1
  221. package/dist/expressions/other.d.ts +15 -11
  222. package/dist/expressions/other.d.ts.map +1 -1
  223. package/dist/expressions/other.js +55 -38
  224. package/dist/expressions/other.js.map +1 -1
  225. package/dist/expressions/parentheses.d.ts.map +1 -1
  226. package/dist/expressions/parentheses.js +2 -1
  227. package/dist/expressions/parentheses.js.map +1 -1
  228. package/dist/expressions/precedence.test.js +6 -2
  229. package/dist/expressions/precedence.test.js.map +1 -1
  230. package/dist/generator-exchange.d.ts +10 -3
  231. package/dist/generator-exchange.d.ts.map +1 -1
  232. package/dist/generator-exchange.js +57 -54
  233. package/dist/generator-exchange.js.map +1 -1
  234. package/dist/generator-wrapper.d.ts +17 -65
  235. package/dist/generator-wrapper.d.ts.map +1 -1
  236. package/dist/generator-wrapper.js +396 -220
  237. package/dist/generator-wrapper.js.map +1 -1
  238. package/dist/generator-wrapper.test.js +22 -14
  239. package/dist/generator-wrapper.test.js.map +1 -1
  240. package/dist/golden-shards.d.ts.map +1 -1
  241. package/dist/golden-shards.js.map +1 -1
  242. package/dist/golden-tests/runner.d.ts.map +1 -1
  243. package/dist/golden-tests/runner.js +3 -1
  244. package/dist/golden-tests/runner.js.map +1 -1
  245. package/dist/integration.test.js +166 -1
  246. package/dist/integration.test.js.map +1 -1
  247. package/dist/json-aot-generic.test.js +8 -2
  248. package/dist/json-aot-generic.test.js.map +1 -1
  249. package/dist/patterns.d.ts +18 -88
  250. package/dist/patterns.d.ts.map +1 -1
  251. package/dist/patterns.js +540 -304
  252. package/dist/patterns.js.map +1 -1
  253. package/dist/patterns.test.js +5 -4
  254. package/dist/patterns.test.js.map +1 -1
  255. package/dist/specialization/generation.d.ts +7 -3
  256. package/dist/specialization/generation.d.ts.map +1 -1
  257. package/dist/specialization/generation.js +32 -16
  258. package/dist/specialization/generation.js.map +1 -1
  259. package/dist/specialization/type-aliases.test.js +3 -2
  260. package/dist/specialization/type-aliases.test.js.map +1 -1
  261. package/dist/statement-emitter.d.ts +15 -4
  262. package/dist/statement-emitter.d.ts.map +1 -1
  263. package/dist/statement-emitter.js +54 -47
  264. package/dist/statement-emitter.js.map +1 -1
  265. package/dist/statements/blocks.d.ts +24 -16
  266. package/dist/statements/blocks.d.ts.map +1 -1
  267. package/dist/statements/blocks.js +193 -66
  268. package/dist/statements/blocks.js.map +1 -1
  269. package/dist/statements/classes/index.d.ts +1 -1
  270. package/dist/statements/classes/index.d.ts.map +1 -1
  271. package/dist/statements/classes/index.js +1 -1
  272. package/dist/statements/classes/index.js.map +1 -1
  273. package/dist/statements/classes/inline-types.d.ts +4 -3
  274. package/dist/statements/classes/inline-types.d.ts.map +1 -1
  275. package/dist/statements/classes/inline-types.js +21 -21
  276. package/dist/statements/classes/inline-types.js.map +1 -1
  277. package/dist/statements/classes/members/constructors.d.ts +4 -3
  278. package/dist/statements/classes/members/constructors.d.ts.map +1 -1
  279. package/dist/statements/classes/members/constructors.js +57 -58
  280. package/dist/statements/classes/members/constructors.js.map +1 -1
  281. package/dist/statements/classes/members/methods.d.ts +4 -3
  282. package/dist/statements/classes/members/methods.d.ts.map +1 -1
  283. package/dist/statements/classes/members/methods.js +98 -98
  284. package/dist/statements/classes/members/methods.js.map +1 -1
  285. package/dist/statements/classes/members/orchestrator.d.ts +4 -3
  286. package/dist/statements/classes/members/orchestrator.d.ts.map +1 -1
  287. package/dist/statements/classes/members/orchestrator.js +2 -2
  288. package/dist/statements/classes/members/orchestrator.js.map +1 -1
  289. package/dist/statements/classes/members/properties.d.ts +4 -3
  290. package/dist/statements/classes/members/properties.d.ts.map +1 -1
  291. package/dist/statements/classes/members/properties.js +109 -89
  292. package/dist/statements/classes/members/properties.js.map +1 -1
  293. package/dist/statements/classes/members/shadowing.test.js +7 -2
  294. package/dist/statements/classes/members/shadowing.test.js.map +1 -1
  295. package/dist/statements/classes/members/static-readonly-properties.test.js +10 -2
  296. package/dist/statements/classes/members/static-readonly-properties.test.js.map +1 -1
  297. package/dist/statements/classes/parameters.d.ts +8 -10
  298. package/dist/statements/classes/parameters.d.ts.map +1 -1
  299. package/dist/statements/classes/parameters.js +30 -26
  300. package/dist/statements/classes/parameters.js.map +1 -1
  301. package/dist/statements/classes/properties.d.ts +4 -3
  302. package/dist/statements/classes/properties.d.ts.map +1 -1
  303. package/dist/statements/classes/properties.js +76 -50
  304. package/dist/statements/classes/properties.js.map +1 -1
  305. package/dist/statements/classes.d.ts +1 -1
  306. package/dist/statements/classes.d.ts.map +1 -1
  307. package/dist/statements/classes.js +1 -1
  308. package/dist/statements/classes.js.map +1 -1
  309. package/dist/statements/control/conditionals/guard-analysis.d.ts +169 -0
  310. package/dist/statements/control/conditionals/guard-analysis.d.ts.map +1 -0
  311. package/dist/statements/control/conditionals/guard-analysis.js +591 -0
  312. package/dist/statements/control/conditionals/guard-analysis.js.map +1 -0
  313. package/dist/statements/control/conditionals/if-emitter.d.ts +14 -0
  314. package/dist/statements/control/conditionals/if-emitter.d.ts.map +1 -0
  315. package/dist/statements/control/conditionals/if-emitter.js +725 -0
  316. package/dist/statements/control/conditionals/if-emitter.js.map +1 -0
  317. package/dist/statements/control/conditionals/switch-emitter.d.ts +13 -0
  318. package/dist/statements/control/conditionals/switch-emitter.d.ts.map +1 -0
  319. package/dist/statements/control/conditionals/switch-emitter.js +60 -0
  320. package/dist/statements/control/conditionals/switch-emitter.js.map +1 -0
  321. package/dist/statements/control/conditionals.d.ts +3 -15
  322. package/dist/statements/control/conditionals.d.ts.map +1 -1
  323. package/dist/statements/control/conditionals.js +3 -1065
  324. package/dist/statements/control/conditionals.js.map +1 -1
  325. package/dist/statements/control/exceptions.d.ts +8 -6
  326. package/dist/statements/control/exceptions.d.ts.map +1 -1
  327. package/dist/statements/control/exceptions.js +35 -23
  328. package/dist/statements/control/exceptions.js.map +1 -1
  329. package/dist/statements/control/index.d.ts +3 -3
  330. package/dist/statements/control/index.d.ts.map +1 -1
  331. package/dist/statements/control/index.js +3 -3
  332. package/dist/statements/control/index.js.map +1 -1
  333. package/dist/statements/control/loops.d.ts +14 -12
  334. package/dist/statements/control/loops.d.ts.map +1 -1
  335. package/dist/statements/control/loops.js +147 -82
  336. package/dist/statements/control/loops.js.map +1 -1
  337. package/dist/statements/control.d.ts +1 -1
  338. package/dist/statements/control.d.ts.map +1 -1
  339. package/dist/statements/control.js +1 -1
  340. package/dist/statements/control.js.map +1 -1
  341. package/dist/statements/declarations/classes.d.ts +7 -3
  342. package/dist/statements/declarations/classes.d.ts.map +1 -1
  343. package/dist/statements/declarations/classes.js +72 -86
  344. package/dist/statements/declarations/classes.js.map +1 -1
  345. package/dist/statements/declarations/enums.d.ts +4 -3
  346. package/dist/statements/declarations/enums.d.ts.map +1 -1
  347. package/dist/statements/declarations/enums.js +18 -16
  348. package/dist/statements/declarations/enums.js.map +1 -1
  349. package/dist/statements/declarations/functions.d.ts +18 -2
  350. package/dist/statements/declarations/functions.d.ts.map +1 -1
  351. package/dist/statements/declarations/functions.js +625 -159
  352. package/dist/statements/declarations/functions.js.map +1 -1
  353. package/dist/statements/declarations/index.d.ts +2 -2
  354. package/dist/statements/declarations/index.d.ts.map +1 -1
  355. package/dist/statements/declarations/index.js +2 -2
  356. package/dist/statements/declarations/index.js.map +1 -1
  357. package/dist/statements/declarations/interfaces.d.ts +7 -3
  358. package/dist/statements/declarations/interfaces.d.ts.map +1 -1
  359. package/dist/statements/declarations/interfaces.js +121 -107
  360. package/dist/statements/declarations/interfaces.js.map +1 -1
  361. package/dist/statements/declarations/type-aliases.d.ts +7 -3
  362. package/dist/statements/declarations/type-aliases.d.ts.map +1 -1
  363. package/dist/statements/declarations/type-aliases.js +95 -79
  364. package/dist/statements/declarations/type-aliases.js.map +1 -1
  365. package/dist/statements/declarations/variables.d.ts +12 -2
  366. package/dist/statements/declarations/variables.d.ts.map +1 -1
  367. package/dist/statements/declarations/variables.js +535 -424
  368. package/dist/statements/declarations/variables.js.map +1 -1
  369. package/dist/statements/declarations.d.ts +1 -1
  370. package/dist/statements/declarations.d.ts.map +1 -1
  371. package/dist/statements/declarations.js +1 -1
  372. package/dist/statements/declarations.js.map +1 -1
  373. package/dist/statements/index.d.ts +3 -3
  374. package/dist/statements/index.d.ts.map +1 -1
  375. package/dist/statements/index.js +5 -5
  376. package/dist/statements/index.js.map +1 -1
  377. package/dist/type-emitter.d.ts +1 -1
  378. package/dist/type-emitter.d.ts.map +1 -1
  379. package/dist/type-emitter.js +1 -1
  380. package/dist/type-emitter.js.map +1 -1
  381. package/dist/types/arrays.d.ts +3 -2
  382. package/dist/types/arrays.d.ts.map +1 -1
  383. package/dist/types/arrays.js +7 -5
  384. package/dist/types/arrays.js.map +1 -1
  385. package/dist/types/dictionaries.d.ts +6 -3
  386. package/dist/types/dictionaries.d.ts.map +1 -1
  387. package/dist/types/dictionaries.js +22 -10
  388. package/dist/types/dictionaries.js.map +1 -1
  389. package/dist/types/emitter.d.ts +8 -2
  390. package/dist/types/emitter.d.ts.map +1 -1
  391. package/dist/types/emitter.js +23 -6
  392. package/dist/types/emitter.js.map +1 -1
  393. package/dist/types/functions.d.ts +3 -2
  394. package/dist/types/functions.d.ts.map +1 -1
  395. package/dist/types/functions.js +36 -13
  396. package/dist/types/functions.js.map +1 -1
  397. package/dist/types/index.d.ts +2 -2
  398. package/dist/types/index.d.ts.map +1 -1
  399. package/dist/types/index.js +2 -2
  400. package/dist/types/index.js.map +1 -1
  401. package/dist/types/index.test.js +137 -0
  402. package/dist/types/index.test.js.map +1 -1
  403. package/dist/types/intersections.d.ts +3 -2
  404. package/dist/types/intersections.d.ts.map +1 -1
  405. package/dist/types/intersections.js +2 -2
  406. package/dist/types/intersections.js.map +1 -1
  407. package/dist/types/literals.d.ts +9 -2
  408. package/dist/types/literals.d.ts.map +1 -1
  409. package/dist/types/literals.js +11 -5
  410. package/dist/types/literals.js.map +1 -1
  411. package/dist/types/objects.d.ts +3 -2
  412. package/dist/types/objects.d.ts.map +1 -1
  413. package/dist/types/objects.js +1 -1
  414. package/dist/types/objects.js.map +1 -1
  415. package/dist/types/parameters.d.ts +6 -5
  416. package/dist/types/parameters.d.ts.map +1 -1
  417. package/dist/types/parameters.js +92 -31
  418. package/dist/types/parameters.js.map +1 -1
  419. package/dist/types/parameters.test.js +9 -4
  420. package/dist/types/parameters.test.js.map +1 -1
  421. package/dist/types/primitives.d.ts +5 -4
  422. package/dist/types/primitives.d.ts.map +1 -1
  423. package/dist/types/primitives.js +14 -13
  424. package/dist/types/primitives.js.map +1 -1
  425. package/dist/types/references.d.ts +3 -2
  426. package/dist/types/references.d.ts.map +1 -1
  427. package/dist/types/references.js +187 -104
  428. package/dist/types/references.js.map +1 -1
  429. package/dist/types/references.test.js +138 -0
  430. package/dist/types/references.test.js.map +1 -1
  431. package/dist/types/tuples.d.ts +3 -2
  432. package/dist/types/tuples.d.ts.map +1 -1
  433. package/dist/types/tuples.js +25 -11
  434. package/dist/types/tuples.js.map +1 -1
  435. package/dist/types/unions.d.ts +3 -2
  436. package/dist/types/unions.d.ts.map +1 -1
  437. package/dist/types/unions.js +36 -21
  438. package/dist/types/unions.js.map +1 -1
  439. package/dist/types.d.ts +1 -1
  440. package/dist/types.d.ts.map +1 -1
  441. package/dist/types.js.map +1 -1
  442. package/package.json +2 -2
  443. package/dist/core/attributes.d.ts.map +0 -1
  444. package/dist/core/attributes.js +0 -141
  445. package/dist/core/attributes.js.map +0 -1
  446. package/dist/core/attributes.test.d.ts.map +0 -1
  447. package/dist/core/attributes.test.js.map +0 -1
  448. package/dist/core/boolean-context.d.ts +0 -42
  449. package/dist/core/boolean-context.d.ts.map +0 -1
  450. package/dist/core/boolean-context.js +0 -402
  451. package/dist/core/boolean-context.js.map +0 -1
  452. package/dist/core/boolean-context.test.d.ts.map +0 -1
  453. package/dist/core/boolean-context.test.js.map +0 -1
  454. package/dist/core/exports.d.ts.map +0 -1
  455. package/dist/core/exports.js +0 -28
  456. package/dist/core/exports.js.map +0 -1
  457. package/dist/core/imports.d.ts.map +0 -1
  458. package/dist/core/imports.js.map +0 -1
  459. package/dist/core/imports.test.d.ts.map +0 -1
  460. package/dist/core/imports.test.js.map +0 -1
  461. package/dist/core/local-names.d.ts.map +0 -1
  462. package/dist/core/local-names.js.map +0 -1
  463. package/dist/core/local-types.d.ts.map +0 -1
  464. package/dist/core/local-types.js.map +0 -1
  465. package/dist/core/module-emitter/assembly.d.ts +0 -24
  466. package/dist/core/module-emitter/assembly.d.ts.map +0 -1
  467. package/dist/core/module-emitter/assembly.js +0 -69
  468. package/dist/core/module-emitter/assembly.js.map +0 -1
  469. package/dist/core/module-emitter/header.d.ts.map +0 -1
  470. package/dist/core/module-emitter/header.js.map +0 -1
  471. package/dist/core/module-emitter/index.d.ts.map +0 -1
  472. package/dist/core/module-emitter/index.js.map +0 -1
  473. package/dist/core/module-emitter/namespace.d.ts +0 -14
  474. package/dist/core/module-emitter/namespace.d.ts.map +0 -1
  475. package/dist/core/module-emitter/namespace.js +0 -26
  476. package/dist/core/module-emitter/namespace.js.map +0 -1
  477. package/dist/core/module-emitter/orchestrator.d.ts.map +0 -1
  478. package/dist/core/module-emitter/orchestrator.js +0 -82
  479. package/dist/core/module-emitter/orchestrator.js.map +0 -1
  480. package/dist/core/module-emitter/separation.d.ts.map +0 -1
  481. package/dist/core/module-emitter/separation.js.map +0 -1
  482. package/dist/core/module-emitter/static-container.d.ts.map +0 -1
  483. package/dist/core/module-emitter/static-container.js +0 -139
  484. package/dist/core/module-emitter/static-container.js.map +0 -1
  485. package/dist/core/module-emitter.d.ts.map +0 -1
  486. package/dist/core/module-emitter.js.map +0 -1
  487. package/dist/core/module-map.d.ts.map +0 -1
  488. package/dist/core/module-map.js.map +0 -1
  489. package/dist/core/module-map.test.d.ts.map +0 -1
  490. package/dist/core/module-map.test.js.map +0 -1
  491. package/dist/core/naming-collisions.d.ts.map +0 -1
  492. package/dist/core/naming-collisions.js.map +0 -1
  493. package/dist/core/options.d.ts.map +0 -1
  494. package/dist/core/options.js.map +0 -1
  495. package/dist/core/type-alias-index.d.ts.map +0 -1
  496. package/dist/core/type-alias-index.js.map +0 -1
  497. package/dist/core/type-compatibility.d.ts.map +0 -1
  498. package/dist/core/type-compatibility.js.map +0 -1
  499. package/dist/core/type-member-index.d.ts.map +0 -1
  500. package/dist/core/type-member-index.js.map +0 -1
  501. package/dist/core/type-params.d.ts.map +0 -1
  502. package/dist/core/type-params.js.map +0 -1
  503. package/dist/core/type-resolution.d.ts.map +0 -1
  504. package/dist/core/type-resolution.js.map +0 -1
  505. package/dist/core/type-resolution.test.d.ts.map +0 -1
  506. package/dist/core/type-resolution.test.js.map +0 -1
  507. package/dist/core/unsafe.d.ts.map +0 -1
  508. package/dist/core/unsafe.js.map +0 -1
  509. /package/dist/core/{attributes.test.d.ts → format/attributes.test.d.ts} +0 -0
  510. /package/dist/core/{module-emitter → format/module-emitter}/index.d.ts +0 -0
  511. /package/dist/core/{module-emitter → format/module-emitter}/index.js +0 -0
  512. /package/dist/core/{module-emitter → format/module-emitter}/separation.d.ts +0 -0
  513. /package/dist/core/{module-emitter → format/module-emitter}/separation.js +0 -0
  514. /package/dist/core/{module-emitter.d.ts → format/module-emitter.d.ts} +0 -0
  515. /package/dist/core/{module-emitter.js → format/module-emitter.js} +0 -0
  516. /package/dist/core/{options.js → format/options.js} +0 -0
  517. /package/dist/core/{boolean-context.test.d.ts → semantic/boolean-context.test.d.ts} +0 -0
  518. /package/dist/core/{imports.test.d.ts → semantic/imports.test.d.ts} +0 -0
  519. /package/dist/core/{local-types.js → semantic/local-types.js} +0 -0
  520. /package/dist/core/{module-map.js → semantic/module-map.js} +0 -0
  521. /package/dist/core/{module-map.test.d.ts → semantic/module-map.test.d.ts} +0 -0
  522. /package/dist/core/{module-map.test.js → semantic/module-map.test.js} +0 -0
  523. /package/dist/core/{naming-collisions.d.ts → semantic/naming-collisions.d.ts} +0 -0
  524. /package/dist/core/{type-alias-index.js → semantic/type-alias-index.js} +0 -0
  525. /package/dist/core/{type-compatibility.d.ts → semantic/type-compatibility.d.ts} +0 -0
  526. /package/dist/core/{type-compatibility.js → semantic/type-compatibility.js} +0 -0
  527. /package/dist/core/{type-member-index.js → semantic/type-member-index.js} +0 -0
  528. /package/dist/core/{type-params.d.ts → semantic/type-params.d.ts} +0 -0
  529. /package/dist/core/{type-params.js → semantic/type-params.js} +0 -0
  530. /package/dist/core/{type-resolution.test.d.ts → semantic/type-resolution.test.d.ts} +0 -0
  531. /package/dist/core/{unsafe.d.ts → semantic/unsafe.d.ts} +0 -0
@@ -6,872 +6,9 @@
6
6
  * - Integer casts only from IrCastExpression (not inferred from expectedType)
7
7
  * - Binary ops: int op int = int, double op anything = double (C# semantics)
8
8
  */
9
- import { emitExpression } from "../expression-emitter.js";
10
- import { emitType } from "../type-emitter.js";
11
- import { resolveTypeAlias, stripNullish, findUnionMemberIndex, getPropertyType, getAllPropertySignatures, isDefinitelyValueType, } from "../core/type-resolution.js";
12
- import { emitBooleanCondition } from "../core/boolean-context.js";
13
- import { emitRemappedLocalName } from "../core/local-names.js";
14
- import { lowerAssignmentPattern } from "../patterns.js";
15
- /**
16
- * Check if an expression has proven Int32 type from the numeric proof pass.
17
- * Mirrors the same check in access.ts for consistency.
18
- */
19
- const hasInt32Proof = (expr) => {
20
- if (expr.inferredType?.kind === "primitiveType" &&
21
- expr.inferredType.name === "int") {
22
- return true;
23
- }
24
- if (expr.inferredType?.kind === "referenceType" &&
25
- expr.inferredType.name === "int") {
26
- return true;
27
- }
28
- return false;
29
- };
30
- /**
31
- * Get operator precedence for proper parenthesization
32
- */
33
- const getPrecedence = (operator) => {
34
- const precedences = {
35
- "||": 5,
36
- // C# precedence: `??` binds less tightly than `||` / `&&` but more tightly than `?:`.
37
- "??": 4,
38
- "&&": 6,
39
- "|": 7,
40
- "^": 8,
41
- "&": 9,
42
- "==": 10,
43
- "!=": 10,
44
- "===": 10,
45
- "!==": 10,
46
- "<": 11,
47
- ">": 11,
48
- "<=": 11,
49
- ">=": 11,
50
- instanceof: 11,
51
- in: 11,
52
- "<<": 12,
53
- ">>": 12,
54
- ">>>": 12,
55
- "+": 13,
56
- "-": 13,
57
- "*": 14,
58
- "/": 14,
59
- "%": 14,
60
- "**": 15,
61
- };
62
- return precedences[operator] ?? 16;
63
- };
64
- /**
65
- * Check if an expression has char type (either from string indexer or a variable typed as char).
66
- * In C#, string[int] returns char, not string like in TypeScript.
67
- * The IR now correctly sets inferredType to char for string indexer access.
68
- */
69
- const isCharTyped = (expr) => {
70
- return ((expr.inferredType?.kind === "primitiveType" &&
71
- expr.inferredType.name === "char") ||
72
- (expr.inferredType?.kind === "referenceType" && expr.inferredType.name === "char"));
73
- };
74
- /**
75
- * Check if an expression is a single-character string literal.
76
- * Returns the character if so, undefined otherwise.
77
- */
78
- const getSingleCharLiteral = (expr) => {
79
- if (expr.kind !== "literal")
80
- return undefined;
81
- if (typeof expr.value !== "string")
82
- return undefined;
83
- if (expr.value.length !== 1)
84
- return undefined;
85
- return expr.value;
86
- };
87
- /**
88
- * Escape a character for use in a C# char literal.
89
- * Handles special characters like quotes, backslash, newline, etc.
90
- */
91
- const escapeCharLiteral = (char) => {
92
- switch (char) {
93
- case "'":
94
- return "\\'";
95
- case "\\":
96
- return "\\\\";
97
- case "\n":
98
- return "\\n";
99
- case "\r":
100
- return "\\r";
101
- case "\t":
102
- return "\\t";
103
- case "\0":
104
- return "\\0";
105
- default:
106
- return char;
107
- }
108
- };
109
- /**
110
- * Emit a binary operator expression
111
- *
112
- * NEW NUMERIC SPEC: No contextual type propagation for numeric literals.
113
- * Literals use their raw lexeme - C# will naturally handle int + int = int,
114
- * int + double = double, etc.
115
- *
116
- * Explicit casts come from IrCastExpression nodes (generated by type-checker
117
- * when user intent allows int → double coercion).
118
- *
119
- * STRING INDEXER FIX: In C#, string[int] returns char, not string.
120
- * When comparing a string indexer result with a single-character string literal,
121
- * we emit the string as a char literal to avoid CS0019 (char == string).
122
- *
123
- * @param expr - The binary expression
124
- * @param context - Emitter context
125
- * @param _expectedType - Unused under new spec (kept for API compatibility)
126
- */
127
- export const emitBinary = (expr, context, _expectedType) => {
128
- // Map JavaScript operators to C# operators
129
- const operatorMap = {
130
- "===": "==",
131
- "!==": "!=",
132
- "==": "==", // Loose equality - needs special handling
133
- "!=": "!=", // Loose inequality - needs special handling
134
- instanceof: "is",
135
- in: "/* in */", // Needs special handling
136
- };
137
- const op = operatorMap[expr.operator] ?? expr.operator;
138
- const parentPrecedence = getPrecedence(expr.operator);
139
- // Handle `"prop" in x` (union narrowing / dictionary membership)
140
- if (expr.operator === "in") {
141
- // LHS must be a string literal for deterministic lowering.
142
- if (expr.left.kind !== "literal" || typeof expr.left.value !== "string") {
143
- throw new Error("ICE: Unsupported `in` operator form. Left-hand side must be a string literal.");
144
- }
145
- const rhsType = expr.right.inferredType;
146
- if (!rhsType) {
147
- throw new Error("ICE: `in` operator RHS missing inferredType.");
148
- }
149
- const [rhsFrag, rhsCtx] = emitExpression(expr.right, context);
150
- const rhsText = rhsFrag.text;
151
- const resolvedRhs = resolveTypeAlias(stripNullish(rhsType), rhsCtx);
152
- // Union<T1..Tn>: `"error" in auth` → auth.IsN() (where member N has the prop)
153
- if (resolvedRhs.kind === "unionType") {
154
- const propName = expr.left.value;
155
- const matchingMembers = [];
156
- for (let i = 0; i < resolvedRhs.types.length; i++) {
157
- const member = resolvedRhs.types[i];
158
- if (!member || member.kind !== "referenceType")
159
- continue;
160
- const localInfo = rhsCtx.localTypes?.get(member.name);
161
- if (localInfo?.kind === "interface") {
162
- const props = getAllPropertySignatures(member, rhsCtx);
163
- if (props?.some((p) => p.name === propName)) {
164
- matchingMembers.push(i + 1);
165
- }
166
- continue;
167
- }
168
- if (localInfo?.kind === "class") {
169
- if (localInfo.members.some((m) => (m.kind === "propertyDeclaration" || m.kind === "methodDeclaration") &&
170
- m.name === propName)) {
171
- matchingMembers.push(i + 1);
172
- }
173
- continue;
174
- }
175
- // Cross-module union members: consult the batch type-member index.
176
- // This enables `"prop" in x` narrowing even when the union member types
177
- // are declared in a different TS module.
178
- const candidates = [];
179
- const stripGlobalPrefix = (name) => name.startsWith("global::") ? name.slice("global::".length) : name;
180
- if (member.resolvedClrType) {
181
- candidates.push(stripGlobalPrefix(member.resolvedClrType));
182
- }
183
- if (member.name.includes(".")) {
184
- candidates.push(member.name);
185
- }
186
- if (!member.name.includes(".") && rhsCtx.options.typeMemberIndex) {
187
- const matches = [];
188
- for (const fqn of rhsCtx.options.typeMemberIndex.keys()) {
189
- if (fqn.endsWith(`.${member.name}`) || fqn.endsWith(`.${member.name}__Alias`)) {
190
- matches.push(fqn);
191
- }
192
- }
193
- if (matches.length === 1) {
194
- candidates.push(matches[0]);
195
- }
196
- else if (matches.length > 1) {
197
- const list = matches.sort().join(", ");
198
- throw new Error(`ICE: Ambiguous union member type '${member.name}' for \`in\` narrowing. Candidates: ${list}`);
199
- }
200
- }
201
- // Single-file fallback (no batch indexes): assume same namespace.
202
- if (rhsCtx.moduleNamespace) {
203
- candidates.push(`${rhsCtx.moduleNamespace}.${member.name}`);
204
- candidates.push(`${rhsCtx.moduleNamespace}.${member.name}__Alias`);
205
- }
206
- const hasMember = candidates.some((fqn) => {
207
- const perType = rhsCtx.options.typeMemberIndex?.get(fqn);
208
- return perType?.has(propName) ?? false;
209
- });
210
- if (hasMember) {
211
- matchingMembers.push(i + 1);
212
- }
213
- }
214
- if (matchingMembers.length === 0) {
215
- return [{ text: "false", precedence: parentPrecedence }, rhsCtx];
216
- }
217
- const checks = matchingMembers.map((n) => `${rhsText}.Is${n}()`).join(" || ");
218
- // Lowering emits an `||` chain; wrap to preserve grouping in any surrounding expression.
219
- return [{ text: `(${checks})`, precedence: 16 }, rhsCtx];
220
- }
221
- // Dictionary<K,V>: `"k" in dict` → dict.ContainsKey("k")
222
- if (resolvedRhs.kind === "dictionaryType") {
223
- const keyType = stripNullish(resolvedRhs.keyType);
224
- const isStringKey = (keyType.kind === "primitiveType" && keyType.name === "string") ||
225
- (keyType.kind === "referenceType" && keyType.name === "string");
226
- if (!isStringKey) {
227
- throw new Error("ICE: Unsupported `in` operator on dictionary with non-string keys.");
228
- }
229
- const [keyFrag, keyCtx] = emitExpression(expr.left, rhsCtx);
230
- const text = `${rhsText}.ContainsKey(${keyFrag.text})`;
231
- return [{ text, precedence: parentPrecedence }, keyCtx];
232
- }
233
- throw new Error("ICE: Unsupported `in` operator. Only union shape guards and Dictionary<string, T> membership are supported.");
234
- }
235
- // Handle instanceof operator specially
236
- if (expr.operator === "instanceof") {
237
- const [leftFrag, leftContext] = emitExpression(expr.left, context);
238
- const [rightFrag, rightContext] = emitExpression(expr.right, leftContext);
239
- const text = `${leftFrag.text} is ${rightFrag.text}`;
240
- return [{ text, precedence: parentPrecedence }, rightContext];
241
- }
242
- // CHAR VS STRING COMPARISON FIX:
243
- // In C#, string[int] returns char, but in TypeScript it returns string.
244
- // The IR now sets inferredType to char for string indexer access.
245
- // When comparing a char-typed expression with a single-character string literal,
246
- // emit the string as a char literal to avoid CS0019 (operator == cannot be applied to char and string).
247
- const isComparisonOp = op === "==" ||
248
- op === "!=" ||
249
- op === "<" ||
250
- op === ">" ||
251
- op === "<=" ||
252
- op === ">=";
253
- if (isComparisonOp) {
254
- const leftIsChar = isCharTyped(expr.left);
255
- const rightIsChar = isCharTyped(expr.right);
256
- const leftSingleChar = getSingleCharLiteral(expr.left);
257
- const rightSingleChar = getSingleCharLiteral(expr.right);
258
- // Case 1: left is char-typed, right is single-char literal → emit right as char
259
- if (leftIsChar && rightSingleChar !== undefined) {
260
- const [leftFrag, leftContext] = emitExpression(expr.left, context);
261
- // Emit as char literal instead of string literal
262
- const charLiteral = `'${escapeCharLiteral(rightSingleChar)}'`;
263
- const text = `${leftFrag.text} ${op} ${charLiteral}`;
264
- return [{ text, precedence: parentPrecedence }, leftContext];
265
- }
266
- // Case 2: right is char-typed, left is single-char literal → emit left as char
267
- if (rightIsChar && leftSingleChar !== undefined) {
268
- const [rightFrag, rightContext] = emitExpression(expr.right, context);
269
- // Emit as char literal instead of string literal
270
- const charLiteral = `'${escapeCharLiteral(leftSingleChar)}'`;
271
- const text = `${charLiteral} ${op} ${rightFrag.text}`;
272
- return [{ text, precedence: parentPrecedence }, rightContext];
273
- }
274
- }
275
- // NULLISH COMPARISONS:
276
- //
277
- // Prefer `== null` / `!= null` for normal reference/nullable types so the result
278
- // is expression-tree friendly (EF Core query providers do not support pattern matching).
279
- //
280
- // For unconstrained generics (T), `== null` is not always valid, so we instead cast
281
- // to `object` to force reference-equality semantics and avoid operator overloads:
282
- // ((object)x) == null
283
- // This also avoids emitting pattern matching (`is null`) which is rejected inside
284
- // expression trees (EF Core query providers).
285
- //
286
- // TypeScript: x === undefined → C#: x == null
287
- // TypeScript: x !== undefined → C#: x != null
288
- // TypeScript: x === null → C#: x == null
289
- // TypeScript: x !== null → C#: x != null
290
- const isNullishLiteral = (e) => (e.kind === "literal" && (e.value === undefined || e.value === null)) ||
291
- (e.kind === "identifier" && (e.name === "undefined" || e.name === "null"));
292
- const leftIsNullish = isNullishLiteral(expr.left);
293
- const rightIsNullish = isNullishLiteral(expr.right);
294
- const isNullishComparison = isComparisonOp &&
295
- (op === "==" || op === "!=") &&
296
- (leftIsNullish || rightIsNullish);
297
- if (isNullishComparison) {
298
- // One side is null/undefined literal, emit the other side as a C# null check.
299
- // Clear narrowedBindings so we emit the raw identifier (not .Value)
300
- const nonNullishExpr = leftIsNullish ? expr.right : expr.left;
301
- const nonNullishContext = { ...context, narrowedBindings: undefined };
302
- const [nonNullishFrag, resultContext] = emitExpression(nonNullishExpr, nonNullishContext);
303
- const inferred = nonNullishExpr.inferredType;
304
- const base = inferred ? stripNullish(inferred) : undefined;
305
- const bareTypeParamName = (() => {
306
- if (!base)
307
- return undefined;
308
- if (base.kind === "typeParameterType")
309
- return base.name;
310
- if (base.kind === "referenceType" &&
311
- (resultContext.typeParameters?.has(base.name) ?? false) &&
312
- (!base.typeArguments || base.typeArguments.length === 0)) {
313
- return base.name;
314
- }
315
- return undefined;
316
- })();
317
- // If the operand is definitely a non-nullable value type, fold comparison to a constant.
318
- if (inferred && inferred.kind !== "unionType" && isDefinitelyValueType(inferred)) {
319
- const folded = op === "==" ? "false" : "true";
320
- return [{ text: folded, precedence: getPrecedence(expr.operator) }, resultContext];
321
- }
322
- const typeParamConstraint = bareTypeParamName !== undefined
323
- ? (resultContext.typeParamConstraints?.get(bareTypeParamName) ??
324
- "unconstrained")
325
- : undefined;
326
- if (typeParamConstraint === "struct") {
327
- const folded = op === "==" ? "false" : "true";
328
- return [{ text: folded, precedence: getPrecedence(expr.operator) }, resultContext];
329
- }
330
- const needsObjectCast = bareTypeParamName !== undefined && typeParamConstraint === "unconstrained";
331
- const nullOp = op === "==" ? "== null" : "!= null";
332
- const nullOperandText = (() => {
333
- switch (nonNullishExpr.kind) {
334
- case "identifier":
335
- case "memberAccess":
336
- case "call":
337
- case "new":
338
- case "this":
339
- case "literal":
340
- return nonNullishFrag.text;
341
- default:
342
- return `(${nonNullishFrag.text})`;
343
- }
344
- })();
345
- const text = needsObjectCast
346
- ? `((global::System.Object)(${nonNullishFrag.text})) ${nullOp}`
347
- : `${nullOperandText} ${nullOp}`;
348
- return [{ text, precedence: getPrecedence(expr.operator) }, resultContext];
349
- }
350
- // Standard emission path
351
- // Emit operands without contextual type propagation
352
- // Literals will emit using their raw lexeme (42 vs 42.0)
353
- const [leftFrag, leftContext] = emitExpression(expr.left, context);
354
- const [rightFrag, rightContext] = emitExpression(expr.right, leftContext);
355
- // Wrap child expressions in parentheses if their precedence is lower than parent
356
- // This preserves grouping: (x + y) * z should not become x + y * z
357
- const leftText = leftFrag.precedence !== undefined && leftFrag.precedence < parentPrecedence
358
- ? `(${leftFrag.text})`
359
- : leftFrag.text;
360
- // For right operand, also wrap if precedence is equal (right-to-left associativity issue)
361
- // Example: a - (b - c) should not become a - b - c
362
- const rightText = rightFrag.precedence !== undefined &&
363
- rightFrag.precedence <= parentPrecedence
364
- ? `(${rightFrag.text})`
365
- : rightFrag.text;
366
- const text = `${leftText} ${op} ${rightText}`;
367
- return [{ text, precedence: getPrecedence(expr.operator) }, rightContext];
368
- };
369
- /**
370
- * Check if an IR type is boolean
371
- */
372
- const isBooleanType = (type) => {
373
- if (!type)
374
- return false;
375
- return type.kind === "primitiveType" && type.name === "boolean";
376
- };
377
- /**
378
- * Emit a logical operator expression (&&, ||, ??)
379
- *
380
- * In TypeScript, || is used both for:
381
- * 1. Boolean OR (when operands are booleans)
382
- * 2. Nullish coalescing fallback (when left operand is nullable)
383
- *
384
- * In C#:
385
- * - || only works with booleans
386
- * - ?? is used for nullish coalescing
387
- *
388
- * We check if || is used with non-boolean operands and emit ?? instead.
389
- */
390
- export const emitLogical = (expr, context) => {
391
- const [leftFrag, leftContext] = emitExpression(expr.left, context);
392
- // If || is used with non-boolean left operand, use ?? instead for nullish coalescing
393
- const operator = expr.operator === "||" && !isBooleanType(expr.left.inferredType)
394
- ? "??"
395
- : expr.operator;
396
- const parentPrecedence = getPrecedence(operator);
397
- // If the left operand is a non-nullable value type, `??` is invalid in C# and the
398
- // fallback is unreachable. Emit only the left operand.
399
- if (operator === "??" &&
400
- expr.left.inferredType &&
401
- expr.left.inferredType.kind !== "unionType" &&
402
- isDefinitelyValueType(expr.left.inferredType) &&
403
- // Conditional access (`?.` / `?[`) produces nullable value types in C# even when the
404
- // underlying member type is non-nullable (e.g., `string?.Length` → `int?`).
405
- // In that case the fallback is still meaningful and must be preserved.
406
- !leftFrag.text.includes("?.") &&
407
- !leftFrag.text.includes("?[")) {
408
- return [leftFrag, leftContext];
409
- }
410
- const [rightFrag, rightContext] = emitExpression(expr.right, leftContext);
411
- const leftText = leftFrag.precedence !== undefined && leftFrag.precedence < parentPrecedence
412
- ? `(${leftFrag.text})`
413
- : leftFrag.text;
414
- const rightText = rightFrag.precedence !== undefined &&
415
- rightFrag.precedence <= parentPrecedence
416
- ? `(${rightFrag.text})`
417
- : rightFrag.text;
418
- const text = `${leftText} ${operator} ${rightText}`;
419
- return [{ text, precedence: getPrecedence(operator) }, rightContext];
420
- };
421
- /**
422
- * Emit a unary operator expression (-, +, !, ~, typeof, void, delete)
423
- *
424
- * NEW NUMERIC SPEC: No contextual type propagation for numeric literals.
425
- * Explicit casts come from IrCastExpression nodes.
426
- *
427
- * @param expr - The unary expression
428
- * @param context - Emitter context
429
- * @param _expectedType - Unused under new spec (kept for API compatibility)
430
- */
431
- export const emitUnary = (expr, context, expectedType) => {
432
- // In TypeScript, `!x` applies JS ToBoolean semantics to *any* operand.
433
- // In C#, `!` only works on booleans, so we must coerce to a boolean condition.
434
- if (expr.operator === "!") {
435
- const [condText, condCtx] = emitBooleanCondition(expr.expression, (e, ctx) => emitExpression(e, ctx), context);
436
- const text = `!(${condText})`;
437
- return [{ text, precedence: 15 }, condCtx];
438
- }
439
- const [operandFrag, newContext] = emitExpression(expr.expression, context);
440
- if (expr.operator === "typeof") {
441
- // typeof becomes global::Tsonic.Runtime.Operators.typeof()
442
- const text = `global::Tsonic.Runtime.Operators.@typeof(${operandFrag.text})`;
443
- return [{ text }, newContext];
444
- }
445
- if (expr.operator === "void") {
446
- // `void expr` evaluates `expr` and yields `undefined`.
447
- //
448
- // In expression position we must produce a value, so use an IIFE:
449
- // (() => { <eval expr>; return default(<T>); })()
450
- //
451
- // In statement position, emitExpressionStatement handles this separately
452
- // (so we don't pay this cost for the common `void x;` marker).
453
- const operand = expr.expression;
454
- // If the operand is a literal null/undefined, evaluation is a no-op and can be skipped.
455
- // This avoids generating invalid discard assignments like `_ = default;`.
456
- const isNoopOperand = (operand.kind === "literal" &&
457
- (operand.value === undefined || operand.value === null)) ||
458
- (operand.kind === "identifier" &&
459
- (operand.name === "undefined" || operand.name === "null"));
460
- let currentContext = newContext;
461
- const effectiveExpectedType = expectedType && expectedType.kind !== "voidType" && expectedType.kind !== "neverType"
462
- ? expectedType
463
- : undefined;
464
- let returnTypeText = "object?";
465
- let defaultText = "default";
466
- if (effectiveExpectedType) {
467
- try {
468
- const [typeText, next] = emitType(effectiveExpectedType, currentContext);
469
- currentContext = next;
470
- returnTypeText = typeText;
471
- defaultText = `default(${typeText})`;
472
- }
473
- catch {
474
- // Fall back to object? + default literal.
475
- }
476
- }
477
- const operandStatement = (() => {
478
- if (isNoopOperand)
479
- return "";
480
- // If the operand is already a valid statement-expression (call/new/assignment/
481
- // update/await), emit it directly. Otherwise, use a discard assignment.
482
- if (operand.kind === "call" ||
483
- operand.kind === "new" ||
484
- operand.kind === "assignment" ||
485
- operand.kind === "update" ||
486
- operand.kind === "await") {
487
- return `${operandFrag.text}; `;
488
- }
489
- return `_ = ${operandFrag.text}; `;
490
- })();
491
- if (operand.kind === "await") {
492
- if (!currentContext.isAsync) {
493
- throw new Error("ICE: `void await <expr>` reached emitter in a non-async context.");
494
- }
495
- const taskReturnType = `global::System.Threading.Tasks.Task<${returnTypeText}>`;
496
- const text = `await ((global::System.Func<${taskReturnType}>)(async () => { ${operandStatement}return ${defaultText}; }))()`;
497
- return [{ text }, currentContext];
498
- }
499
- const text = `((global::System.Func<${returnTypeText}>)(() => { ${operandStatement}return ${defaultText}; }))()`;
500
- return [{ text }, currentContext];
501
- }
502
- if (expr.operator === "delete") {
503
- // delete needs special handling
504
- const text = `/* delete ${operandFrag.text} */`;
505
- return [{ text }, newContext];
506
- }
507
- const text = `${expr.operator}${operandFrag.text}`;
508
- return [{ text, precedence: 15 }, newContext];
509
- };
510
- /**
511
- * Emit an update operator expression (++, --)
512
- */
513
- export const emitUpdate = (expr, context) => {
514
- // Narrowing maps (instanceof / nullable / union) apply to *reads*, not writes.
515
- // For update operators, the operand is written, so we must not rewrite the target
516
- // identifier to a narrowed binding (e.g., C# pattern var).
517
- const operandCtx = expr.expression.kind === "identifier" &&
518
- context.narrowedBindings?.has(expr.expression.name)
519
- ? (() => {
520
- const next = new Map(context.narrowedBindings);
521
- next.delete(expr.expression.name);
522
- return { ...context, narrowedBindings: next };
523
- })()
524
- : context;
525
- const [operandFrag, ctx] = emitExpression(expr.expression, operandCtx);
526
- const newContext = operandCtx !== context
527
- ? { ...ctx, narrowedBindings: context.narrowedBindings }
528
- : ctx;
529
- const text = expr.prefix
530
- ? `${expr.operator}${operandFrag.text}`
531
- : `${operandFrag.text}${expr.operator}`;
532
- return [{ text, precedence: 15 }, newContext];
533
- };
534
- /**
535
- * Emit an assignment expression (=, +=, -=, etc.)
536
- *
537
- * Passes the LHS type as expected type to RHS, enabling proper integer
538
- * literal emission for cases like `this.value = this.value + 1`.
539
- */
540
- export const emitAssignment = (expr, context) => {
541
- // Array element assignment uses native CLR indexer
542
- // HARD GATE: Index must be proven Int32 (validated by proof pass)
543
- if (expr.operator === "=" &&
544
- "kind" in expr.left &&
545
- expr.left.kind === "memberAccess" &&
546
- expr.left.isComputed &&
547
- expr.left.object.inferredType?.kind === "arrayType") {
548
- const leftExpr = expr.left;
549
- const indexExpr = leftExpr.property;
550
- if (!hasInt32Proof(indexExpr)) {
551
- // ICE: Unproven index should have been caught by proof pass (TSN5107)
552
- throw new Error(`Internal Compiler Error: Array index must be proven Int32. ` +
553
- `This should have been caught by the numeric proof pass (TSN5107).`);
554
- }
555
- const [objectFrag, objectContext] = emitExpression(leftExpr.object, context);
556
- const [indexFrag, indexContext] = emitExpression(indexExpr, objectContext);
557
- const [rightFrag, rightContext] = emitExpression(expr.right, indexContext);
558
- // Use native CLR indexer
559
- const text = `${objectFrag.text}[${indexFrag.text}] = ${rightFrag.text}`;
560
- return [{ text, precedence: 2 }, rightContext];
561
- }
562
- // Left side can be an expression or a pattern (for destructuring)
563
- const isPattern = "kind" in expr.left &&
564
- (expr.left.kind === "identifierPattern" ||
565
- expr.left.kind === "arrayPattern" ||
566
- expr.left.kind === "objectPattern");
567
- // Handle destructuring assignment patterns
568
- if (isPattern && expr.operator === "=") {
569
- const pattern = expr.left;
570
- // Emit the RHS first
571
- const [rightFrag, rightContext] = emitExpression(expr.right, context);
572
- // Use lowerAssignmentPattern to generate the destructuring expression
573
- const result = lowerAssignmentPattern(pattern, rightFrag.text, expr.right.inferredType, rightContext);
574
- return [{ text: result.expression, precedence: 2 }, result.context];
575
- }
576
- // Standard assignment (expression on left side)
577
- let leftText;
578
- let leftContext;
579
- let leftType;
580
- if (isPattern) {
581
- // Identifier pattern with compound assignment (+=, etc.)
582
- const pattern = expr.left;
583
- if (pattern.kind === "identifierPattern") {
584
- leftText = emitRemappedLocalName(pattern.name, context);
585
- leftContext = context;
586
- leftType = pattern.type;
587
- }
588
- else {
589
- // Compound assignment to array/object pattern - not valid in JS
590
- leftText = "/* invalid compound destructuring */";
591
- leftContext = context;
592
- }
593
- }
594
- else {
595
- const leftExpr = expr.left;
596
- // Narrowing maps (instanceof / nullable / union) apply to *reads*, not writes.
597
- // For assignment, the LHS is written, so we must not rewrite identifier targets
598
- // to narrowed bindings (e.g., C# pattern vars).
599
- const leftCtx = leftExpr.kind === "identifier" &&
600
- context.narrowedBindings?.has(leftExpr.name)
601
- ? (() => {
602
- const next = new Map(context.narrowedBindings);
603
- next.delete(leftExpr.name);
604
- return { ...context, narrowedBindings: next };
605
- })()
606
- : context;
607
- const [leftFrag, ctx] = emitExpression(leftExpr, leftCtx);
608
- leftText = leftFrag.text;
609
- // Restore narrowing for RHS emission (reads) when we suppressed it for the LHS.
610
- leftContext =
611
- leftCtx !== context
612
- ? { ...ctx, narrowedBindings: context.narrowedBindings }
613
- : ctx;
614
- leftType = leftExpr.inferredType;
615
- }
616
- // Pass LHS type as expected type to RHS for proper integer handling
617
- const [rightFrag, rightContext] = emitExpression(expr.right, leftContext, leftType);
618
- const text = `${leftText} ${expr.operator} ${rightFrag.text}`;
619
- return [{ text, precedence: 2 }, rightContext];
620
- };
621
- const resolveLocalTypesForReference = (type, context) => {
622
- const lookupName = type.name.includes(".")
623
- ? type.name.split(".").pop() ?? type.name
624
- : type.name;
625
- if (context.localTypes?.has(lookupName)) {
626
- return context.localTypes;
627
- }
628
- const moduleMap = context.options.moduleMap;
629
- if (!moduleMap)
630
- return undefined;
631
- const matches = [];
632
- for (const m of moduleMap.values()) {
633
- if (!m.localTypes)
634
- continue;
635
- if (m.localTypes.has(lookupName)) {
636
- matches.push({ namespace: m.namespace, localTypes: m.localTypes });
637
- }
638
- }
639
- if (matches.length === 0)
640
- return undefined;
641
- if (matches.length === 1)
642
- return matches[0].localTypes;
643
- const fqn = type.resolvedClrType ?? (type.name.includes(".") ? type.name : undefined);
644
- if (fqn && fqn.includes(".")) {
645
- const ns = fqn.slice(0, fqn.lastIndexOf("."));
646
- const filtered = matches.filter((m) => m.namespace === ns);
647
- if (filtered.length === 1)
648
- return filtered[0].localTypes;
649
- }
650
- return undefined;
651
- };
652
- const tryGetLiteralSet = (type, context) => {
653
- const resolved = resolveTypeAlias(type, context);
654
- if (resolved.kind === "literalType") {
655
- return new Set([resolved.value]);
656
- }
657
- if (resolved.kind === "unionType") {
658
- const out = new Set();
659
- for (const t of resolved.types) {
660
- const r = resolveTypeAlias(t, context);
661
- if (r.kind !== "literalType")
662
- return undefined;
663
- out.add(r.value);
664
- }
665
- return out;
666
- }
667
- return undefined;
668
- };
669
- const tryResolveTernaryGuard = (condition, context) => {
670
- // Check for direct call: isUser(x)
671
- const resolveFromCall = (call) => {
672
- const narrowing = call.narrowing;
673
- if (!narrowing || narrowing.kind !== "typePredicate")
674
- return undefined;
675
- const arg = call.arguments[narrowing.argIndex];
676
- if (!arg ||
677
- ("kind" in arg && arg.kind === "spread") ||
678
- arg.kind !== "identifier") {
679
- return undefined;
680
- }
681
- const originalName = arg.name;
682
- const unionSourceType = arg.inferredType;
683
- if (!unionSourceType)
684
- return undefined;
685
- const resolved = resolveTypeAlias(stripNullish(unionSourceType), context);
686
- if (resolved.kind !== "unionType")
687
- return undefined;
688
- const idx = findUnionMemberIndex(resolved, narrowing.targetType, context);
689
- if (idx === undefined)
690
- return undefined;
691
- return {
692
- originalName,
693
- memberN: idx + 1,
694
- escapedOrig: emitRemappedLocalName(originalName, context),
695
- polarity: "positive",
696
- };
697
- };
698
- // Direct call: isUser(x) -> narrow whenTrue
699
- if (condition.kind === "call") {
700
- return resolveFromCall(condition);
701
- }
702
- // Discriminant literal equality: x.kind === "circle"
703
- const resolveFromDiscriminantEquality = (expr) => {
704
- // Normalize `!(x.prop === lit)` to `x.prop !== lit` (and vice versa) by flipping polarity.
705
- if (expr.kind === "unary" && expr.operator === "!") {
706
- const inner = resolveFromDiscriminantEquality(expr.expression);
707
- if (!inner)
708
- return undefined;
709
- return {
710
- ...inner,
711
- polarity: inner.polarity === "positive" ? "negative" : "positive",
712
- };
713
- }
714
- if (expr.kind !== "binary")
715
- return undefined;
716
- if (expr.operator !== "===" &&
717
- expr.operator !== "!==" &&
718
- expr.operator !== "==" &&
719
- expr.operator !== "!=") {
720
- return undefined;
721
- }
722
- const extract = (left, right) => {
723
- if (left.kind !== "memberAccess")
724
- return undefined;
725
- if (left.isOptional)
726
- return undefined;
727
- if (left.isComputed)
728
- return undefined;
729
- if (left.object.kind !== "identifier")
730
- return undefined;
731
- if (typeof left.property !== "string")
732
- return undefined;
733
- if (right.kind !== "literal")
734
- return undefined;
735
- if (typeof right.value !== "string" &&
736
- typeof right.value !== "number" &&
737
- typeof right.value !== "boolean") {
738
- return undefined;
739
- }
740
- return {
741
- receiver: left.object,
742
- propertyName: left.property,
743
- literal: right.value,
744
- };
745
- };
746
- const direct = extract(expr.left, expr.right);
747
- const swapped = direct ? undefined : extract(expr.right, expr.left);
748
- const match = direct ?? swapped;
749
- if (!match)
750
- return undefined;
751
- const { receiver, propertyName, literal } = match;
752
- const originalName = receiver.name;
753
- if (context.narrowedBindings?.has(originalName))
754
- return undefined;
755
- const unionSourceType = receiver.inferredType;
756
- if (!unionSourceType)
757
- return undefined;
758
- const resolved = resolveTypeAlias(stripNullish(unionSourceType), context);
759
- if (resolved.kind !== "unionType")
760
- return undefined;
761
- const unionArity = resolved.types.length;
762
- if (unionArity < 2 || unionArity > 8)
763
- return undefined;
764
- const matchingMembers = [];
765
- for (let i = 0; i < resolved.types.length; i++) {
766
- const member = resolved.types[i];
767
- if (!member)
768
- continue;
769
- let propType;
770
- if (member.kind === "objectType") {
771
- const prop = member.members.find((m) => m.kind === "propertySignature" && m.name === propertyName);
772
- propType = prop?.type;
773
- }
774
- else if (member.kind === "referenceType") {
775
- const localTypes = resolveLocalTypesForReference(member, context);
776
- if (!localTypes)
777
- continue;
778
- const lookupName = member.name.includes(".")
779
- ? member.name.split(".").pop() ?? member.name
780
- : member.name;
781
- propType = getPropertyType({ ...member, name: lookupName }, propertyName, { ...context, localTypes });
782
- }
783
- else {
784
- continue;
785
- }
786
- if (!propType)
787
- continue;
788
- const literals = tryGetLiteralSet(propType, context);
789
- if (!literals)
790
- continue;
791
- if (literals.has(literal)) {
792
- matchingMembers.push(i + 1);
793
- }
794
- }
795
- if (matchingMembers.length !== 1)
796
- return undefined;
797
- const memberN = matchingMembers[0];
798
- if (!memberN)
799
- return undefined;
800
- const isInequality = expr.operator === "!==" || expr.operator === "!=";
801
- return {
802
- originalName,
803
- memberN,
804
- escapedOrig: emitRemappedLocalName(originalName, context),
805
- polarity: isInequality ? "negative" : "positive",
806
- };
807
- };
808
- const discr = resolveFromDiscriminantEquality(condition);
809
- if (discr)
810
- return discr;
811
- // Negated call: !isUser(x) -> narrow whenFalse
812
- if (condition.kind === "unary" &&
813
- condition.operator === "!" &&
814
- condition.expression.kind === "call") {
815
- const guard = resolveFromCall(condition.expression);
816
- if (guard) {
817
- return { ...guard, polarity: "negative" };
818
- }
819
- }
820
- return undefined;
821
- };
822
- /**
823
- * Emit a conditional (ternary) expression
824
- *
825
- * Supports type predicate narrowing:
826
- * - `isUser(x) ? x.name : "anon"` → `x.Is1() ? (x.As1()).name : "anon"`
827
- * - `!isUser(x) ? "anon" : x.name` → `!x.Is1() ? "anon" : (x.As1()).name`
828
- *
829
- * @param expr - The conditional expression
830
- * @param context - Emitter context
831
- * @param expectedType - Optional expected type (for null → default in generic contexts)
832
- */
833
- export const emitConditional = (expr, context, expectedType) => {
834
- // When no contextual expectedType is provided (e.g., `var x = cond ? a : b`),
835
- // use the conditional expression's own inferred type to guide null/undefined → default
836
- // conversions and keep C# type inference consistent with TS.
837
- const branchExpectedType = expectedType ?? expr.inferredType;
838
- // Try to detect type predicate guard in condition
839
- const guard = tryResolveTernaryGuard(expr.condition, context);
840
- if (guard) {
841
- const { originalName, memberN, escapedOrig, polarity } = guard;
842
- // Build condition text
843
- const condText = polarity === "positive"
844
- ? `${escapedOrig}.Is${memberN}()`
845
- : `!${escapedOrig}.Is${memberN}()`;
846
- // Create inline narrowing binding: x -> (x.AsN())
847
- const inlineExpr = `(${escapedOrig}.As${memberN}())`;
848
- const narrowedMap = new Map(context.narrowedBindings ?? []);
849
- narrowedMap.set(originalName, { kind: "expr", exprText: inlineExpr });
850
- const narrowedContext = {
851
- ...context,
852
- narrowedBindings: narrowedMap,
853
- };
854
- // Apply narrowing to the appropriate branch
855
- const [trueFrag, trueContext] = polarity === "positive"
856
- ? emitExpression(expr.whenTrue, narrowedContext, branchExpectedType)
857
- : emitExpression(expr.whenTrue, context, branchExpectedType);
858
- const [falseFrag, falseContext] = polarity === "negative"
859
- ? emitExpression(expr.whenFalse, narrowedContext, branchExpectedType)
860
- : emitExpression(expr.whenFalse, trueContext, branchExpectedType);
861
- const text = `${condText} ? ${trueFrag.text} : ${falseFrag.text}`;
862
- // Return context WITHOUT narrowing (don't leak)
863
- const finalContext = {
864
- ...falseContext,
865
- narrowedBindings: context.narrowedBindings,
866
- };
867
- return [{ text, precedence: 3 }, finalContext];
868
- }
869
- // Standard ternary emission (no narrowing)
870
- const [condText, condContext] = emitBooleanCondition(expr.condition, (e, ctx) => emitExpression(e, ctx), context);
871
- // Pass expectedType (or inferred type) to both branches for null/undefined → default conversion
872
- const [trueFrag, trueContext] = emitExpression(expr.whenTrue, condContext, branchExpectedType);
873
- const [falseFrag, falseContext] = emitExpression(expr.whenFalse, trueContext, branchExpectedType);
874
- const text = `${condText} ? ${trueFrag.text} : ${falseFrag.text}`;
875
- return [{ text, precedence: 3 }, falseContext];
876
- };
9
+ export { emitBinary } from "./operators/binary-emitter.js";
10
+ export { emitLogical } from "./operators/logical-emitter.js";
11
+ export { emitUnary, emitUpdate } from "./operators/unary-emitter.js";
12
+ export { emitAssignment } from "./operators/assignment-emitter.js";
13
+ export { emitConditional } from "./operators/conditional-emitter.js";
877
14
  //# sourceMappingURL=operators.js.map