@tsonic/emitter 0.0.62 → 0.0.64

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 (520) 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} +1 -1
  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/{module-emitter → format/module-emitter}/orchestrator.js +19 -19
  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/semantic/boolean-context.d.ts +44 -0
  87. package/dist/core/semantic/boolean-context.d.ts.map +1 -0
  88. package/dist/core/semantic/boolean-context.js +717 -0
  89. package/dist/core/semantic/boolean-context.js.map +1 -0
  90. package/dist/core/semantic/boolean-context.test.d.ts.map +1 -0
  91. package/dist/core/{boolean-context.test.js → semantic/boolean-context.test.js} +86 -109
  92. package/dist/core/semantic/boolean-context.test.js.map +1 -0
  93. package/dist/core/{imports.d.ts → semantic/imports.d.ts} +1 -5
  94. package/dist/core/semantic/imports.d.ts.map +1 -0
  95. package/dist/core/{imports.js → semantic/imports.js} +56 -74
  96. package/dist/core/semantic/imports.js.map +1 -0
  97. package/dist/core/semantic/imports.test.d.ts.map +1 -0
  98. package/dist/core/semantic/imports.test.js +229 -0
  99. package/dist/core/semantic/imports.test.js.map +1 -0
  100. package/dist/core/semantic/index.d.ts +15 -0
  101. package/dist/core/semantic/index.d.ts.map +1 -0
  102. package/dist/core/semantic/index.js +15 -0
  103. package/dist/core/semantic/index.js.map +1 -0
  104. package/dist/core/{local-types.d.ts → semantic/local-types.d.ts} +1 -1
  105. package/dist/core/semantic/local-types.d.ts.map +1 -0
  106. package/dist/core/semantic/local-types.js.map +1 -0
  107. package/dist/core/{module-map.d.ts → semantic/module-map.d.ts} +1 -1
  108. package/dist/core/semantic/module-map.d.ts.map +1 -0
  109. package/dist/core/semantic/module-map.js.map +1 -0
  110. package/dist/core/semantic/module-map.test.d.ts.map +1 -0
  111. package/dist/core/semantic/module-map.test.js.map +1 -0
  112. package/dist/core/semantic/naming-collisions.d.ts.map +1 -0
  113. package/dist/core/{naming-collisions.js → semantic/naming-collisions.js} +1 -1
  114. package/dist/core/semantic/naming-collisions.js.map +1 -0
  115. package/dist/core/{type-alias-index.d.ts → semantic/type-alias-index.d.ts} +1 -1
  116. package/dist/core/semantic/type-alias-index.d.ts.map +1 -0
  117. package/dist/core/semantic/type-alias-index.js.map +1 -0
  118. package/dist/core/semantic/type-compatibility.d.ts.map +1 -0
  119. package/dist/core/semantic/type-compatibility.js.map +1 -0
  120. package/dist/core/{type-member-index.d.ts → semantic/type-member-index.d.ts} +1 -1
  121. package/dist/core/semantic/type-member-index.d.ts.map +1 -0
  122. package/dist/core/semantic/type-member-index.js.map +1 -0
  123. package/dist/core/semantic/type-params.d.ts.map +1 -0
  124. package/dist/core/semantic/type-params.js.map +1 -0
  125. package/dist/core/{type-resolution.d.ts → semantic/type-resolution.d.ts} +3 -6
  126. package/dist/core/semantic/type-resolution.d.ts.map +1 -0
  127. package/dist/core/{type-resolution.js → semantic/type-resolution.js} +15 -25
  128. package/dist/core/semantic/type-resolution.js.map +1 -0
  129. package/dist/core/semantic/type-resolution.test.d.ts.map +1 -0
  130. package/dist/core/{type-resolution.test.js → semantic/type-resolution.test.js} +11 -19
  131. package/dist/core/semantic/type-resolution.test.js.map +1 -0
  132. package/dist/core/semantic/unsafe.d.ts.map +1 -0
  133. package/dist/core/semantic/unsafe.js.map +1 -0
  134. package/dist/emitter-types/core.d.ts +6 -12
  135. package/dist/emitter-types/core.d.ts.map +1 -1
  136. package/dist/emitter-types/index.d.ts +1 -1
  137. package/dist/emitter-types/index.d.ts.map +1 -1
  138. package/dist/emitter-types/index.js.map +1 -1
  139. package/dist/emitter.d.ts +1 -1
  140. package/dist/emitter.d.ts.map +1 -1
  141. package/dist/emitter.js +9 -8
  142. package/dist/emitter.js.map +1 -1
  143. package/dist/expression-emitter.d.ts +10 -5
  144. package/dist/expression-emitter.d.ts.map +1 -1
  145. package/dist/expression-emitter.js +333 -117
  146. package/dist/expression-emitter.js.map +1 -1
  147. package/dist/expressions/access.d.ts +4 -3
  148. package/dist/expressions/access.d.ts.map +1 -1
  149. package/dist/expressions/access.js +252 -102
  150. package/dist/expressions/access.js.map +1 -1
  151. package/dist/expressions/calls/call-analysis.d.ts +86 -0
  152. package/dist/expressions/calls/call-analysis.d.ts.map +1 -0
  153. package/dist/expressions/calls/call-analysis.js +284 -0
  154. package/dist/expressions/calls/call-analysis.js.map +1 -0
  155. package/dist/expressions/calls/call-emitter.d.ts +13 -0
  156. package/dist/expressions/calls/call-emitter.d.ts.map +1 -0
  157. package/dist/expressions/calls/call-emitter.js +1048 -0
  158. package/dist/expressions/calls/call-emitter.js.map +1 -0
  159. package/dist/expressions/calls/new-emitter.d.ts +13 -0
  160. package/dist/expressions/calls/new-emitter.d.ts.map +1 -0
  161. package/dist/expressions/calls/new-emitter.js +641 -0
  162. package/dist/expressions/calls/new-emitter.js.map +1 -0
  163. package/dist/expressions/calls.d.ts +2 -14
  164. package/dist/expressions/calls.d.ts.map +1 -1
  165. package/dist/expressions/calls.js +2 -909
  166. package/dist/expressions/calls.js.map +1 -1
  167. package/dist/expressions/collections.d.ts +6 -16
  168. package/dist/expressions/collections.d.ts.map +1 -1
  169. package/dist/expressions/collections.js +318 -217
  170. package/dist/expressions/collections.js.map +1 -1
  171. package/dist/expressions/functions.d.ts +6 -5
  172. package/dist/expressions/functions.d.ts.map +1 -1
  173. package/dist/expressions/functions.js +57 -62
  174. package/dist/expressions/functions.js.map +1 -1
  175. package/dist/expressions/identifiers.d.ts +11 -6
  176. package/dist/expressions/identifiers.d.ts.map +1 -1
  177. package/dist/expressions/identifiers.js +76 -25
  178. package/dist/expressions/identifiers.js.map +1 -1
  179. package/dist/expressions/index.d.ts +1 -1
  180. package/dist/expressions/index.d.ts.map +1 -1
  181. package/dist/expressions/index.js +1 -1
  182. package/dist/expressions/index.js.map +1 -1
  183. package/dist/expressions/index.test.js +605 -0
  184. package/dist/expressions/index.test.js.map +1 -1
  185. package/dist/expressions/literals.d.ts +4 -3
  186. package/dist/expressions/literals.d.ts.map +1 -1
  187. package/dist/expressions/literals.js +25 -17
  188. package/dist/expressions/literals.js.map +1 -1
  189. package/dist/expressions/literals.test.js +18 -18
  190. package/dist/expressions/literals.test.js.map +1 -1
  191. package/dist/expressions/operators/assignment-emitter.d.ts +16 -0
  192. package/dist/expressions/operators/assignment-emitter.d.ts.map +1 -0
  193. package/dist/expressions/operators/assignment-emitter.js +118 -0
  194. package/dist/expressions/operators/assignment-emitter.js.map +1 -0
  195. package/dist/expressions/operators/binary-emitter.d.ts +33 -0
  196. package/dist/expressions/operators/binary-emitter.d.ts.map +1 -0
  197. package/dist/expressions/operators/binary-emitter.js +398 -0
  198. package/dist/expressions/operators/binary-emitter.js.map +1 -0
  199. package/dist/expressions/operators/conditional-emitter.d.ts +17 -0
  200. package/dist/expressions/operators/conditional-emitter.d.ts.map +1 -0
  201. package/dist/expressions/operators/conditional-emitter.js +306 -0
  202. package/dist/expressions/operators/conditional-emitter.js.map +1 -0
  203. package/dist/expressions/operators/helpers.d.ts +37 -0
  204. package/dist/expressions/operators/helpers.d.ts.map +1 -0
  205. package/dist/expressions/operators/helpers.js +136 -0
  206. package/dist/expressions/operators/helpers.js.map +1 -0
  207. package/dist/expressions/operators/logical-emitter.d.ts +23 -0
  208. package/dist/expressions/operators/logical-emitter.d.ts.map +1 -0
  209. package/dist/expressions/operators/logical-emitter.js +73 -0
  210. package/dist/expressions/operators/logical-emitter.js.map +1 -0
  211. package/dist/expressions/operators/unary-emitter.d.ts +30 -0
  212. package/dist/expressions/operators/unary-emitter.d.ts.map +1 -0
  213. package/dist/expressions/operators/unary-emitter.js +244 -0
  214. package/dist/expressions/operators/unary-emitter.js.map +1 -0
  215. package/dist/expressions/operators.d.ts +5 -81
  216. package/dist/expressions/operators.d.ts.map +1 -1
  217. package/dist/expressions/operators.js +5 -949
  218. package/dist/expressions/operators.js.map +1 -1
  219. package/dist/expressions/other.d.ts +15 -11
  220. package/dist/expressions/other.d.ts.map +1 -1
  221. package/dist/expressions/other.js +51 -36
  222. package/dist/expressions/other.js.map +1 -1
  223. package/dist/expressions/precedence.test.js +1 -1
  224. package/dist/expressions/precedence.test.js.map +1 -1
  225. package/dist/generator-exchange.d.ts +10 -3
  226. package/dist/generator-exchange.d.ts.map +1 -1
  227. package/dist/generator-exchange.js +57 -54
  228. package/dist/generator-exchange.js.map +1 -1
  229. package/dist/generator-wrapper.d.ts +17 -65
  230. package/dist/generator-wrapper.d.ts.map +1 -1
  231. package/dist/generator-wrapper.js +396 -220
  232. package/dist/generator-wrapper.js.map +1 -1
  233. package/dist/generator-wrapper.test.js +22 -14
  234. package/dist/generator-wrapper.test.js.map +1 -1
  235. package/dist/integration.test.js +169 -1
  236. package/dist/integration.test.js.map +1 -1
  237. package/dist/patterns.d.ts +18 -88
  238. package/dist/patterns.d.ts.map +1 -1
  239. package/dist/patterns.js +540 -304
  240. package/dist/patterns.js.map +1 -1
  241. package/dist/patterns.test.js +5 -4
  242. package/dist/patterns.test.js.map +1 -1
  243. package/dist/specialization/generation.d.ts +7 -3
  244. package/dist/specialization/generation.d.ts.map +1 -1
  245. package/dist/specialization/generation.js +31 -15
  246. package/dist/specialization/generation.js.map +1 -1
  247. package/dist/specialization/type-aliases.test.js +47 -2
  248. package/dist/specialization/type-aliases.test.js.map +1 -1
  249. package/dist/statement-emitter.d.ts +15 -4
  250. package/dist/statement-emitter.d.ts.map +1 -1
  251. package/dist/statement-emitter.js +54 -47
  252. package/dist/statement-emitter.js.map +1 -1
  253. package/dist/statements/blocks.d.ts +24 -16
  254. package/dist/statements/blocks.d.ts.map +1 -1
  255. package/dist/statements/blocks.js +242 -65
  256. package/dist/statements/blocks.js.map +1 -1
  257. package/dist/statements/classes/index.d.ts +1 -1
  258. package/dist/statements/classes/index.d.ts.map +1 -1
  259. package/dist/statements/classes/index.js +1 -1
  260. package/dist/statements/classes/index.js.map +1 -1
  261. package/dist/statements/classes/inline-types.d.ts +4 -3
  262. package/dist/statements/classes/inline-types.d.ts.map +1 -1
  263. package/dist/statements/classes/inline-types.js +21 -21
  264. package/dist/statements/classes/inline-types.js.map +1 -1
  265. package/dist/statements/classes/members/constructors.d.ts +4 -3
  266. package/dist/statements/classes/members/constructors.d.ts.map +1 -1
  267. package/dist/statements/classes/members/constructors.js +57 -58
  268. package/dist/statements/classes/members/constructors.js.map +1 -1
  269. package/dist/statements/classes/members/methods.d.ts +4 -3
  270. package/dist/statements/classes/members/methods.d.ts.map +1 -1
  271. package/dist/statements/classes/members/methods.js +106 -101
  272. package/dist/statements/classes/members/methods.js.map +1 -1
  273. package/dist/statements/classes/members/orchestrator.d.ts +4 -3
  274. package/dist/statements/classes/members/orchestrator.d.ts.map +1 -1
  275. package/dist/statements/classes/members/orchestrator.js +2 -2
  276. package/dist/statements/classes/members/orchestrator.js.map +1 -1
  277. package/dist/statements/classes/members/properties.d.ts +4 -3
  278. package/dist/statements/classes/members/properties.d.ts.map +1 -1
  279. package/dist/statements/classes/members/properties.js +105 -88
  280. package/dist/statements/classes/members/properties.js.map +1 -1
  281. package/dist/statements/classes/members/shadowing.test.js +7 -2
  282. package/dist/statements/classes/members/shadowing.test.js.map +1 -1
  283. package/dist/statements/classes/members/static-readonly-properties.test.js +4 -1
  284. package/dist/statements/classes/members/static-readonly-properties.test.js.map +1 -1
  285. package/dist/statements/classes/parameters.d.ts +8 -10
  286. package/dist/statements/classes/parameters.d.ts.map +1 -1
  287. package/dist/statements/classes/parameters.js +30 -26
  288. package/dist/statements/classes/parameters.js.map +1 -1
  289. package/dist/statements/classes/properties.d.ts +4 -3
  290. package/dist/statements/classes/properties.d.ts.map +1 -1
  291. package/dist/statements/classes/properties.js +76 -50
  292. package/dist/statements/classes/properties.js.map +1 -1
  293. package/dist/statements/classes.d.ts +1 -1
  294. package/dist/statements/classes.d.ts.map +1 -1
  295. package/dist/statements/classes.js +1 -1
  296. package/dist/statements/classes.js.map +1 -1
  297. package/dist/statements/control/conditionals/guard-analysis.d.ts +169 -0
  298. package/dist/statements/control/conditionals/guard-analysis.d.ts.map +1 -0
  299. package/dist/statements/control/conditionals/guard-analysis.js +591 -0
  300. package/dist/statements/control/conditionals/guard-analysis.js.map +1 -0
  301. package/dist/statements/control/conditionals/if-emitter.d.ts +14 -0
  302. package/dist/statements/control/conditionals/if-emitter.d.ts.map +1 -0
  303. package/dist/statements/control/conditionals/if-emitter.js +725 -0
  304. package/dist/statements/control/conditionals/if-emitter.js.map +1 -0
  305. package/dist/statements/control/conditionals/switch-emitter.d.ts +13 -0
  306. package/dist/statements/control/conditionals/switch-emitter.d.ts.map +1 -0
  307. package/dist/statements/control/conditionals/switch-emitter.js +60 -0
  308. package/dist/statements/control/conditionals/switch-emitter.js.map +1 -0
  309. package/dist/statements/control/conditionals.d.ts +3 -15
  310. package/dist/statements/control/conditionals.d.ts.map +1 -1
  311. package/dist/statements/control/conditionals.js +3 -1152
  312. package/dist/statements/control/conditionals.js.map +1 -1
  313. package/dist/statements/control/exceptions.d.ts +8 -6
  314. package/dist/statements/control/exceptions.d.ts.map +1 -1
  315. package/dist/statements/control/exceptions.js +35 -23
  316. package/dist/statements/control/exceptions.js.map +1 -1
  317. package/dist/statements/control/index.d.ts +3 -3
  318. package/dist/statements/control/index.d.ts.map +1 -1
  319. package/dist/statements/control/index.js +3 -3
  320. package/dist/statements/control/index.js.map +1 -1
  321. package/dist/statements/control/loops.d.ts +14 -12
  322. package/dist/statements/control/loops.d.ts.map +1 -1
  323. package/dist/statements/control/loops.js +147 -82
  324. package/dist/statements/control/loops.js.map +1 -1
  325. package/dist/statements/control.d.ts +1 -1
  326. package/dist/statements/control.d.ts.map +1 -1
  327. package/dist/statements/control.js +1 -1
  328. package/dist/statements/control.js.map +1 -1
  329. package/dist/statements/declarations/classes.d.ts +7 -3
  330. package/dist/statements/declarations/classes.d.ts.map +1 -1
  331. package/dist/statements/declarations/classes.js +107 -83
  332. package/dist/statements/declarations/classes.js.map +1 -1
  333. package/dist/statements/declarations/enums.d.ts +4 -3
  334. package/dist/statements/declarations/enums.d.ts.map +1 -1
  335. package/dist/statements/declarations/enums.js +16 -15
  336. package/dist/statements/declarations/enums.js.map +1 -1
  337. package/dist/statements/declarations/functions.d.ts +18 -2
  338. package/dist/statements/declarations/functions.d.ts.map +1 -1
  339. package/dist/statements/declarations/functions.js +633 -162
  340. package/dist/statements/declarations/functions.js.map +1 -1
  341. package/dist/statements/declarations/index.d.ts +2 -2
  342. package/dist/statements/declarations/index.d.ts.map +1 -1
  343. package/dist/statements/declarations/index.js +2 -2
  344. package/dist/statements/declarations/index.js.map +1 -1
  345. package/dist/statements/declarations/interfaces.d.ts +7 -3
  346. package/dist/statements/declarations/interfaces.d.ts.map +1 -1
  347. package/dist/statements/declarations/interfaces.js +138 -105
  348. package/dist/statements/declarations/interfaces.js.map +1 -1
  349. package/dist/statements/declarations/type-aliases.d.ts +7 -3
  350. package/dist/statements/declarations/type-aliases.d.ts.map +1 -1
  351. package/dist/statements/declarations/type-aliases.js +122 -82
  352. package/dist/statements/declarations/type-aliases.js.map +1 -1
  353. package/dist/statements/declarations/variables.d.ts +12 -2
  354. package/dist/statements/declarations/variables.d.ts.map +1 -1
  355. package/dist/statements/declarations/variables.js +541 -428
  356. package/dist/statements/declarations/variables.js.map +1 -1
  357. package/dist/statements/declarations.d.ts +1 -1
  358. package/dist/statements/declarations.d.ts.map +1 -1
  359. package/dist/statements/declarations.js +1 -1
  360. package/dist/statements/declarations.js.map +1 -1
  361. package/dist/statements/index.d.ts +3 -3
  362. package/dist/statements/index.d.ts.map +1 -1
  363. package/dist/statements/index.js +5 -5
  364. package/dist/statements/index.js.map +1 -1
  365. package/dist/statements/index.test.js +307 -0
  366. package/dist/statements/index.test.js.map +1 -1
  367. package/dist/type-emitter.d.ts +1 -1
  368. package/dist/type-emitter.d.ts.map +1 -1
  369. package/dist/type-emitter.js +1 -1
  370. package/dist/type-emitter.js.map +1 -1
  371. package/dist/types/arrays.d.ts +3 -2
  372. package/dist/types/arrays.d.ts.map +1 -1
  373. package/dist/types/arrays.js +7 -5
  374. package/dist/types/arrays.js.map +1 -1
  375. package/dist/types/dictionaries.d.ts +6 -3
  376. package/dist/types/dictionaries.d.ts.map +1 -1
  377. package/dist/types/dictionaries.js +22 -10
  378. package/dist/types/dictionaries.js.map +1 -1
  379. package/dist/types/emitter.d.ts +8 -2
  380. package/dist/types/emitter.d.ts.map +1 -1
  381. package/dist/types/emitter.js +20 -6
  382. package/dist/types/emitter.js.map +1 -1
  383. package/dist/types/functions.d.ts +3 -2
  384. package/dist/types/functions.d.ts.map +1 -1
  385. package/dist/types/functions.js +36 -13
  386. package/dist/types/functions.js.map +1 -1
  387. package/dist/types/index.d.ts +2 -2
  388. package/dist/types/index.d.ts.map +1 -1
  389. package/dist/types/index.js +2 -2
  390. package/dist/types/index.js.map +1 -1
  391. package/dist/types/index.test.js +137 -0
  392. package/dist/types/index.test.js.map +1 -1
  393. package/dist/types/intersections.d.ts +3 -2
  394. package/dist/types/intersections.d.ts.map +1 -1
  395. package/dist/types/intersections.js +2 -2
  396. package/dist/types/intersections.js.map +1 -1
  397. package/dist/types/literals.d.ts +9 -2
  398. package/dist/types/literals.d.ts.map +1 -1
  399. package/dist/types/literals.js +11 -5
  400. package/dist/types/literals.js.map +1 -1
  401. package/dist/types/objects.d.ts +3 -2
  402. package/dist/types/objects.d.ts.map +1 -1
  403. package/dist/types/objects.js +1 -1
  404. package/dist/types/objects.js.map +1 -1
  405. package/dist/types/parameters.d.ts +6 -5
  406. package/dist/types/parameters.d.ts.map +1 -1
  407. package/dist/types/parameters.js +88 -29
  408. package/dist/types/parameters.js.map +1 -1
  409. package/dist/types/parameters.test.js +9 -4
  410. package/dist/types/parameters.test.js.map +1 -1
  411. package/dist/types/primitives.d.ts +5 -4
  412. package/dist/types/primitives.d.ts.map +1 -1
  413. package/dist/types/primitives.js +14 -13
  414. package/dist/types/primitives.js.map +1 -1
  415. package/dist/types/references.d.ts +3 -2
  416. package/dist/types/references.d.ts.map +1 -1
  417. package/dist/types/references.js +135 -111
  418. package/dist/types/references.js.map +1 -1
  419. package/dist/types/tuples.d.ts +3 -2
  420. package/dist/types/tuples.d.ts.map +1 -1
  421. package/dist/types/tuples.js +25 -11
  422. package/dist/types/tuples.js.map +1 -1
  423. package/dist/types/unions.d.ts +3 -2
  424. package/dist/types/unions.d.ts.map +1 -1
  425. package/dist/types/unions.js +36 -21
  426. package/dist/types/unions.js.map +1 -1
  427. package/dist/types.d.ts +1 -1
  428. package/dist/types.d.ts.map +1 -1
  429. package/dist/types.js.map +1 -1
  430. package/package.json +2 -2
  431. package/dist/core/attributes.d.ts.map +0 -1
  432. package/dist/core/attributes.js +0 -141
  433. package/dist/core/attributes.js.map +0 -1
  434. package/dist/core/attributes.test.d.ts.map +0 -1
  435. package/dist/core/attributes.test.js.map +0 -1
  436. package/dist/core/boolean-context.d.ts +0 -42
  437. package/dist/core/boolean-context.d.ts.map +0 -1
  438. package/dist/core/boolean-context.js +0 -442
  439. package/dist/core/boolean-context.js.map +0 -1
  440. package/dist/core/boolean-context.test.d.ts.map +0 -1
  441. package/dist/core/boolean-context.test.js.map +0 -1
  442. package/dist/core/exports.d.ts.map +0 -1
  443. package/dist/core/exports.js +0 -28
  444. package/dist/core/exports.js.map +0 -1
  445. package/dist/core/imports.d.ts.map +0 -1
  446. package/dist/core/imports.js.map +0 -1
  447. package/dist/core/imports.test.d.ts.map +0 -1
  448. package/dist/core/imports.test.js +0 -79
  449. package/dist/core/imports.test.js.map +0 -1
  450. package/dist/core/local-names.d.ts.map +0 -1
  451. package/dist/core/local-names.js.map +0 -1
  452. package/dist/core/local-types.d.ts.map +0 -1
  453. package/dist/core/local-types.js.map +0 -1
  454. package/dist/core/module-emitter/assembly.d.ts +0 -24
  455. package/dist/core/module-emitter/assembly.d.ts.map +0 -1
  456. package/dist/core/module-emitter/assembly.js +0 -69
  457. package/dist/core/module-emitter/assembly.js.map +0 -1
  458. package/dist/core/module-emitter/header.d.ts.map +0 -1
  459. package/dist/core/module-emitter/header.js.map +0 -1
  460. package/dist/core/module-emitter/index.d.ts.map +0 -1
  461. package/dist/core/module-emitter/index.js.map +0 -1
  462. package/dist/core/module-emitter/namespace.d.ts +0 -14
  463. package/dist/core/module-emitter/namespace.d.ts.map +0 -1
  464. package/dist/core/module-emitter/namespace.js +0 -26
  465. package/dist/core/module-emitter/namespace.js.map +0 -1
  466. package/dist/core/module-emitter/orchestrator.d.ts.map +0 -1
  467. package/dist/core/module-emitter/orchestrator.js.map +0 -1
  468. package/dist/core/module-emitter/separation.d.ts.map +0 -1
  469. package/dist/core/module-emitter/separation.js.map +0 -1
  470. package/dist/core/module-emitter/static-container.d.ts.map +0 -1
  471. package/dist/core/module-emitter/static-container.js +0 -139
  472. package/dist/core/module-emitter/static-container.js.map +0 -1
  473. package/dist/core/module-emitter.d.ts.map +0 -1
  474. package/dist/core/module-emitter.js.map +0 -1
  475. package/dist/core/module-map.d.ts.map +0 -1
  476. package/dist/core/module-map.js.map +0 -1
  477. package/dist/core/module-map.test.d.ts.map +0 -1
  478. package/dist/core/module-map.test.js.map +0 -1
  479. package/dist/core/naming-collisions.d.ts.map +0 -1
  480. package/dist/core/naming-collisions.js.map +0 -1
  481. package/dist/core/options.d.ts.map +0 -1
  482. package/dist/core/options.js.map +0 -1
  483. package/dist/core/type-alias-index.d.ts.map +0 -1
  484. package/dist/core/type-alias-index.js.map +0 -1
  485. package/dist/core/type-compatibility.d.ts.map +0 -1
  486. package/dist/core/type-compatibility.js.map +0 -1
  487. package/dist/core/type-member-index.d.ts.map +0 -1
  488. package/dist/core/type-member-index.js.map +0 -1
  489. package/dist/core/type-params.d.ts.map +0 -1
  490. package/dist/core/type-params.js.map +0 -1
  491. package/dist/core/type-resolution.d.ts.map +0 -1
  492. package/dist/core/type-resolution.js.map +0 -1
  493. package/dist/core/type-resolution.test.d.ts.map +0 -1
  494. package/dist/core/type-resolution.test.js.map +0 -1
  495. package/dist/core/unsafe.d.ts.map +0 -1
  496. package/dist/core/unsafe.js.map +0 -1
  497. /package/dist/core/{attributes.test.d.ts → format/attributes.test.d.ts} +0 -0
  498. /package/dist/core/{module-emitter → format/module-emitter}/index.d.ts +0 -0
  499. /package/dist/core/{module-emitter → format/module-emitter}/index.js +0 -0
  500. /package/dist/core/{module-emitter → format/module-emitter}/separation.d.ts +0 -0
  501. /package/dist/core/{module-emitter → format/module-emitter}/separation.js +0 -0
  502. /package/dist/core/{module-emitter.d.ts → format/module-emitter.d.ts} +0 -0
  503. /package/dist/core/{module-emitter.js → format/module-emitter.js} +0 -0
  504. /package/dist/core/{options.js → format/options.js} +0 -0
  505. /package/dist/core/{boolean-context.test.d.ts → semantic/boolean-context.test.d.ts} +0 -0
  506. /package/dist/core/{imports.test.d.ts → semantic/imports.test.d.ts} +0 -0
  507. /package/dist/core/{local-types.js → semantic/local-types.js} +0 -0
  508. /package/dist/core/{module-map.js → semantic/module-map.js} +0 -0
  509. /package/dist/core/{module-map.test.d.ts → semantic/module-map.test.d.ts} +0 -0
  510. /package/dist/core/{module-map.test.js → semantic/module-map.test.js} +0 -0
  511. /package/dist/core/{naming-collisions.d.ts → semantic/naming-collisions.d.ts} +0 -0
  512. /package/dist/core/{type-alias-index.js → semantic/type-alias-index.js} +0 -0
  513. /package/dist/core/{type-compatibility.d.ts → semantic/type-compatibility.d.ts} +0 -0
  514. /package/dist/core/{type-compatibility.js → semantic/type-compatibility.js} +0 -0
  515. /package/dist/core/{type-member-index.js → semantic/type-member-index.js} +0 -0
  516. /package/dist/core/{type-params.d.ts → semantic/type-params.d.ts} +0 -0
  517. /package/dist/core/{type-params.js → semantic/type-params.js} +0 -0
  518. /package/dist/core/{type-resolution.test.d.ts → semantic/type-resolution.test.d.ts} +0 -0
  519. /package/dist/core/{unsafe.d.ts → semantic/unsafe.d.ts} +0 -0
  520. /package/dist/core/{unsafe.js → semantic/unsafe.js} +0 -0
@@ -0,0 +1,717 @@
1
+ /**
2
+ * Boolean-context emission (truthiness / ToBoolean)
3
+ *
4
+ * In TypeScript, any value can be used in a boolean context (truthy/falsy).
5
+ * In C#, only boolean expressions are valid conditions (if/while/for/?:/!).
6
+ *
7
+ * This module provides a shared, deterministic lowering for boolean contexts.
8
+ * All functions return typed CSharpExpressionAst nodes — no text bridging.
9
+ *
10
+ * IMPORTANT:
11
+ * - This operates on IR + emitted AST; it must not import emitExpressionAst to avoid cycles.
12
+ * - Callers provide an emit function.
13
+ */
14
+ import { allocateLocalName } from "../format/local-names.js";
15
+ import { substituteTypeArgs } from "./type-resolution.js";
16
+ const stripGlobalPrefix = (name) => name.startsWith("global::") ? name.slice("global::".length) : name;
17
+ /**
18
+ * Coerce CLR primitive reference types (System.Boolean, System.Int32, ...) to IR primitiveType.
19
+ *
20
+ * This prevents boolean-context lowering from emitting `x != null` for CLR value types,
21
+ * which is both semantically wrong and can silently miscompile (it compiles with boxing).
22
+ */
23
+ const coerceClrPrimitiveToPrimitiveType = (type) => {
24
+ if (type.kind !== "referenceType")
25
+ return undefined;
26
+ const resolved = type.resolvedClrType ?? type.typeId?.clrName;
27
+ if (!resolved)
28
+ return undefined;
29
+ const clr = stripGlobalPrefix(resolved);
30
+ switch (clr) {
31
+ case "System.Boolean":
32
+ case "bool":
33
+ return { kind: "primitiveType", name: "boolean" };
34
+ case "System.String":
35
+ case "string":
36
+ return { kind: "primitiveType", name: "string" };
37
+ case "System.Int32":
38
+ case "int":
39
+ return { kind: "primitiveType", name: "int" };
40
+ case "System.Double":
41
+ case "double":
42
+ return { kind: "primitiveType", name: "number" };
43
+ case "System.Char":
44
+ case "char":
45
+ return { kind: "primitiveType", name: "char" };
46
+ }
47
+ return undefined;
48
+ };
49
+ /**
50
+ * Check if an expression's inferred type is boolean.
51
+ */
52
+ const isBooleanCondition = (expr) => {
53
+ const type = expr.inferredType;
54
+ if (!type)
55
+ return false;
56
+ if (type.kind === "primitiveType") {
57
+ return type.name === "boolean";
58
+ }
59
+ // Some CLR APIs (via bindings) surface as referenceType with a resolved CLR primitive
60
+ // (e.g. System.Boolean). Treat those as booleans for C# conditions.
61
+ const coerced = coerceClrPrimitiveToPrimitiveType(type);
62
+ return (!!coerced && coerced.kind === "primitiveType" && coerced.name === "boolean");
63
+ };
64
+ /**
65
+ * Expressions that are always boolean in JS/TS, even if the IR is missing inferredType.
66
+ *
67
+ * This makes boolean-context emission robust: comparisons and `!expr` are already valid
68
+ * C# conditions and should not be rewritten to `!= null` fallbacks.
69
+ */
70
+ const isInherentlyBooleanExpression = (expr) => {
71
+ if (expr.kind === "binary") {
72
+ return (expr.operator === "==" ||
73
+ expr.operator === "!=" ||
74
+ expr.operator === "===" ||
75
+ expr.operator === "!==" ||
76
+ expr.operator === "<" ||
77
+ expr.operator === ">" ||
78
+ expr.operator === "<=" ||
79
+ expr.operator === ">=" ||
80
+ expr.operator === "instanceof" ||
81
+ expr.operator === "in");
82
+ }
83
+ if (expr.kind === "unary") {
84
+ return expr.operator === "!";
85
+ }
86
+ return false;
87
+ };
88
+ // ============================================================
89
+ // AST construction helpers
90
+ // ============================================================
91
+ /** Wrap an AST expression in parentheses if it has lower precedence than `is` (relational = 10). */
92
+ const wrapForIs = (ast) => {
93
+ switch (ast.kind) {
94
+ case "assignmentExpression":
95
+ case "conditionalExpression":
96
+ case "lambdaExpression":
97
+ case "throwExpression":
98
+ return { kind: "parenthesizedExpression", expression: ast };
99
+ case "binaryExpression": {
100
+ // Binary operators with precedence < relational (10) need wrapping
101
+ switch (ast.operatorToken) {
102
+ case "??":
103
+ case "||":
104
+ case "&&":
105
+ case "|":
106
+ case "^":
107
+ case "&":
108
+ case "==":
109
+ case "!=":
110
+ return { kind: "parenthesizedExpression", expression: ast };
111
+ default:
112
+ return ast;
113
+ }
114
+ }
115
+ default:
116
+ return ast;
117
+ }
118
+ };
119
+ const identifierExpr = (name) => ({
120
+ kind: "identifierExpression",
121
+ identifier: name,
122
+ });
123
+ const literalExpr = (text) => ({
124
+ kind: "literalExpression",
125
+ text,
126
+ });
127
+ const predefinedType = (keyword) => ({
128
+ kind: "predefinedType",
129
+ keyword,
130
+ });
131
+ const identifierType = (name) => ({
132
+ kind: "identifierType",
133
+ name,
134
+ });
135
+ const castExpr = (type, expression) => ({
136
+ kind: "castExpression",
137
+ type,
138
+ expression,
139
+ });
140
+ const typePattern = (type) => ({
141
+ kind: "typePattern",
142
+ type,
143
+ });
144
+ const notEqualsExpr = (left, right) => ({
145
+ kind: "binaryExpression",
146
+ operatorToken: "!=",
147
+ left,
148
+ right,
149
+ });
150
+ const andExpr = (left, right) => ({
151
+ kind: "binaryExpression",
152
+ operatorToken: "&&",
153
+ left,
154
+ right,
155
+ });
156
+ const notExpr = (operand) => ({
157
+ kind: "prefixUnaryExpression",
158
+ operatorToken: "!",
159
+ operand,
160
+ });
161
+ const staticMemberExpr = (typeName, memberName) => ({
162
+ kind: "memberAccessExpression",
163
+ expression: identifierExpr(typeName),
164
+ memberName,
165
+ });
166
+ const callExpr = (callee, args) => ({
167
+ kind: "invocationExpression",
168
+ expression: callee,
169
+ arguments: args,
170
+ });
171
+ const makeSwitchArm = (pattern, expression) => ({ pattern, expression });
172
+ const buildTruthySwitchAst = (tmp) => {
173
+ const tmpExpr = identifierExpr(tmp);
174
+ const typedNonZeroArm = (type, zeroLiteralText) => makeSwitchArm(typePattern(type), notEqualsExpr(castExpr(type, tmpExpr), literalExpr(zeroLiteralText)));
175
+ const floatLikeArm = (type, isNaNStaticTypeName, zeroLiteralText) => {
176
+ const casted = castExpr(type, tmpExpr);
177
+ const nonZero = notEqualsExpr(casted, literalExpr(zeroLiteralText));
178
+ const isNaNCall = callExpr(staticMemberExpr(isNaNStaticTypeName, "IsNaN"), [
179
+ castExpr(type, tmpExpr),
180
+ ]);
181
+ return makeSwitchArm(typePattern(type), andExpr(nonZero, notExpr(isNaNCall)));
182
+ };
183
+ return {
184
+ kind: "switchExpression",
185
+ governingExpression: tmpExpr,
186
+ arms: [
187
+ makeSwitchArm(typePattern(predefinedType("bool")), castExpr(predefinedType("bool"), tmpExpr)),
188
+ makeSwitchArm(typePattern(predefinedType("string")), notEqualsExpr({
189
+ kind: "memberAccessExpression",
190
+ expression: castExpr(predefinedType("string"), tmpExpr),
191
+ memberName: "Length",
192
+ }, literalExpr("0"))),
193
+ typedNonZeroArm(predefinedType("sbyte"), "0"),
194
+ typedNonZeroArm(predefinedType("byte"), "0"),
195
+ typedNonZeroArm(predefinedType("short"), "0"),
196
+ typedNonZeroArm(predefinedType("ushort"), "0"),
197
+ typedNonZeroArm(predefinedType("int"), "0"),
198
+ typedNonZeroArm(predefinedType("uint"), "0U"),
199
+ typedNonZeroArm(predefinedType("long"), "0L"),
200
+ typedNonZeroArm(predefinedType("ulong"), "0UL"),
201
+ typedNonZeroArm(predefinedType("nint"), "0"),
202
+ typedNonZeroArm(predefinedType("nuint"), "0"),
203
+ typedNonZeroArm(identifierType("global::System.Int128"), "0"),
204
+ typedNonZeroArm(identifierType("global::System.UInt128"), "0"),
205
+ floatLikeArm(identifierType("global::System.Half"), "global::System.Half", "(global::System.Half)0"),
206
+ floatLikeArm(predefinedType("float"), "global::System.Single", "0f"),
207
+ floatLikeArm(predefinedType("double"), "global::System.Double", "0d"),
208
+ typedNonZeroArm(predefinedType("decimal"), "0m"),
209
+ typedNonZeroArm(predefinedType("char"), "'\\0'"),
210
+ makeSwitchArm({ kind: "discardPattern" }, literalExpr("true")),
211
+ ],
212
+ };
213
+ };
214
+ // ============================================================
215
+ // Runtime truthiness (AST-native)
216
+ // ============================================================
217
+ const emitRuntimeTruthinessConditionAst = (emittedAst, context) => {
218
+ // Use a pattern variable to evaluate the operand exactly once, then apply JS-like truthiness.
219
+ //
220
+ // This is the airplane-grade fallback when we cannot trust inferredType:
221
+ // - Never emit `x != null` for unknowns (silently miscompiles boxed value types like bool/int).
222
+ // - Use runtime type checks to preserve semantics deterministically.
223
+ const nextId = (context.tempVarId ?? 0) + 1;
224
+ const ctxWithId = { ...context, tempVarId: nextId };
225
+ const alloc = allocateLocalName(`__tsonic_truthy_${nextId}`, ctxWithId);
226
+ const tmp = alloc.emittedName;
227
+ // Build: (operand is object __tmp && (__tmp switch { ... }))
228
+ const isObjectExpr = {
229
+ kind: "isExpression",
230
+ expression: wrapForIs(emittedAst),
231
+ pattern: {
232
+ kind: "declarationPattern",
233
+ type: { kind: "predefinedType", keyword: "object" },
234
+ designation: tmp,
235
+ },
236
+ };
237
+ const switchExpr = {
238
+ kind: "parenthesizedExpression",
239
+ expression: buildTruthySwitchAst(tmp),
240
+ };
241
+ return [
242
+ {
243
+ kind: "parenthesizedExpression",
244
+ expression: {
245
+ kind: "binaryExpression",
246
+ operatorToken: "&&",
247
+ left: isObjectExpr,
248
+ right: switchExpr,
249
+ },
250
+ },
251
+ alloc.context,
252
+ ];
253
+ };
254
+ // ============================================================
255
+ // Type resolution helpers
256
+ // ============================================================
257
+ const resolveLocalTypeAlias = (type, context) => {
258
+ let current = type;
259
+ const visited = new Set();
260
+ while (current.kind === "referenceType") {
261
+ const name = current.name;
262
+ if (visited.has(name))
263
+ break;
264
+ visited.add(name);
265
+ const local = context.localTypes?.get(name);
266
+ if (!local || local.kind !== "typeAlias")
267
+ break;
268
+ // If the alias is generic, substitute type arguments when provided.
269
+ if (local.typeParameters.length > 0) {
270
+ if (!current.typeArguments || current.typeArguments.length === 0)
271
+ break;
272
+ current = substituteTypeArgs(local.type, local.typeParameters, current.typeArguments);
273
+ continue;
274
+ }
275
+ current = local.type;
276
+ }
277
+ return current;
278
+ };
279
+ const isNullishType = (type) => type.kind === "primitiveType" &&
280
+ (type.name === "null" || type.name === "undefined");
281
+ const getLiteralUnionBasePrimitive = (types) => {
282
+ let base;
283
+ for (const t of types) {
284
+ if (t.kind !== "literalType")
285
+ return undefined;
286
+ const v = t.value;
287
+ const next = typeof v === "string"
288
+ ? "string"
289
+ : typeof v === "number"
290
+ ? "number"
291
+ : typeof v === "boolean"
292
+ ? "boolean"
293
+ : undefined;
294
+ if (!next)
295
+ return undefined;
296
+ if (!base)
297
+ base = next;
298
+ else if (base !== next)
299
+ return undefined;
300
+ }
301
+ return base;
302
+ };
303
+ // ============================================================
304
+ // Union truthiness (AST-native)
305
+ // ============================================================
306
+ const emitUnionTruthinessConditionAst = (expr, emittedAst, unionType, context) => {
307
+ // Align boolean-context emission with union type emission:
308
+ // - (T | null | undefined) behaves like a nullable (falsy when nullish)
309
+ // - literal unions behave like their primitive base at runtime
310
+ // - 2-8 unions emit as global::Tsonic.Runtime.Union<T1..Tn>, which requires per-variant truthiness
311
+ const nonNullTypes = unionType.types.filter((t) => !isNullishType(t));
312
+ const hasNullish = nonNullTypes.length !== unionType.types.length;
313
+ const literalBase = getLiteralUnionBasePrimitive(nonNullTypes);
314
+ if (literalBase) {
315
+ const baseType = {
316
+ kind: "primitiveType",
317
+ name: literalBase,
318
+ };
319
+ if (!hasNullish) {
320
+ return toBooleanConditionAst({ ...expr, inferredType: baseType }, emittedAst, context);
321
+ }
322
+ // Nullable literal union (e.g. "a" | "b" | null) → value is falsy when nullish.
323
+ const nextId = (context.tempVarId ?? 0) + 1;
324
+ const ctxWithId = { ...context, tempVarId: nextId };
325
+ const alloc = allocateLocalName(`__tsonic_truthy_nullable_${nextId}`, ctxWithId);
326
+ const tmp = alloc.emittedName;
327
+ const [innerCondAst, innerCtx] = toBooleanConditionAst({
328
+ kind: "identifier",
329
+ name: tmp,
330
+ inferredType: baseType,
331
+ }, identifierExpr(tmp), alloc.context);
332
+ const emittedNonNull = literalBase === "string"
333
+ ? "string"
334
+ : literalBase === "number"
335
+ ? "double"
336
+ : "bool";
337
+ // Build: (operand is Type tmp && innerCond)
338
+ return [
339
+ {
340
+ kind: "parenthesizedExpression",
341
+ expression: {
342
+ kind: "binaryExpression",
343
+ operatorToken: "&&",
344
+ left: {
345
+ kind: "isExpression",
346
+ expression: wrapForIs(emittedAst),
347
+ pattern: {
348
+ kind: "declarationPattern",
349
+ type: { kind: "predefinedType", keyword: emittedNonNull },
350
+ designation: tmp,
351
+ },
352
+ },
353
+ right: innerCondAst,
354
+ },
355
+ },
356
+ innerCtx,
357
+ ];
358
+ }
359
+ // Nullable union: (T | null | undefined) → treat as `T?` truthiness.
360
+ if (hasNullish && nonNullTypes.length === 1) {
361
+ const nonNull = nonNullTypes[0];
362
+ if (!nonNull)
363
+ return [literalExpr("false"), context];
364
+ // For non-primitive nullable unions (e.g. `T[] | undefined`, `SomeRef | null`),
365
+ // emit truthiness directly against the operand with non-null inferred type.
366
+ // This avoids nested nullable pattern variables while preserving exact semantics.
367
+ if (nonNull.kind !== "primitiveType") {
368
+ return toBooleanConditionAst({ ...expr, inferredType: nonNull }, emittedAst, context);
369
+ }
370
+ const nextId = (context.tempVarId ?? 0) + 1;
371
+ const ctxWithId = { ...context, tempVarId: nextId };
372
+ const alloc = allocateLocalName(`__tsonic_truthy_nullable_${nextId}`, ctxWithId);
373
+ const tmp = alloc.emittedName;
374
+ // Pattern-match the non-null value into a strongly-typed temp and apply truthiness to it.
375
+ // This handles both nullable value types (int?) and nullable reference types (string?).
376
+ const [innerCondAst, innerCtx] = toBooleanConditionAst({
377
+ kind: "identifier",
378
+ name: tmp,
379
+ inferredType: nonNull,
380
+ }, identifierExpr(tmp), alloc.context);
381
+ const emittedNonNull = nonNull.name === "number"
382
+ ? "double"
383
+ : nonNull.name === "int"
384
+ ? "int"
385
+ : nonNull.name === "string"
386
+ ? "string"
387
+ : nonNull.name === "boolean"
388
+ ? "bool"
389
+ : nonNull.name === "char"
390
+ ? "char"
391
+ : "object";
392
+ // Build: (operand is Type tmp && innerCond)
393
+ return [
394
+ {
395
+ kind: "parenthesizedExpression",
396
+ expression: {
397
+ kind: "binaryExpression",
398
+ operatorToken: "&&",
399
+ left: {
400
+ kind: "isExpression",
401
+ expression: wrapForIs(emittedAst),
402
+ pattern: {
403
+ kind: "declarationPattern",
404
+ type: { kind: "predefinedType", keyword: emittedNonNull },
405
+ designation: tmp,
406
+ },
407
+ },
408
+ right: innerCondAst,
409
+ },
410
+ },
411
+ innerCtx,
412
+ ];
413
+ }
414
+ // 2-8 unions use runtime Union<T1..Tn>. We must inspect the active variant.
415
+ if (unionType.types.length >= 2 && unionType.types.length <= 8) {
416
+ const nextId = (context.tempVarId ?? 0) + 1;
417
+ const ctxWithId = { ...context, tempVarId: nextId };
418
+ const alloc = allocateLocalName(`__tsonic_truthy_union_${nextId}`, ctxWithId);
419
+ const u = alloc.emittedName;
420
+ // Build per-member truthiness ASTs
421
+ let chainCtx = alloc.context;
422
+ const branchAsts = [];
423
+ for (let i = 0; i < unionType.types.length; i++) {
424
+ const memberN = i + 1;
425
+ const memberType = unionType.types[i];
426
+ if (!memberType || isNullishType(memberType)) {
427
+ branchAsts.push(literalExpr("false"));
428
+ continue;
429
+ }
430
+ const memberEmittedAst = {
431
+ kind: "invocationExpression",
432
+ expression: {
433
+ kind: "memberAccessExpression",
434
+ expression: identifierExpr(u),
435
+ memberName: `As${memberN}`,
436
+ },
437
+ arguments: [],
438
+ };
439
+ const [memberCondAst, memberCtx] = toBooleanConditionAst({
440
+ kind: "identifier",
441
+ name: `${u}__${memberN}`,
442
+ inferredType: memberType,
443
+ }, memberEmittedAst, chainCtx);
444
+ branchAsts.push(memberCondAst);
445
+ chainCtx = memberCtx;
446
+ }
447
+ // Build nested conditional chain: u.Is1() ? (cond1) : u.Is2() ? (cond2) : ...
448
+ const buildChain = (start) => {
449
+ const last = branchAsts[branchAsts.length - 1];
450
+ if (start === branchAsts.length - 1) {
451
+ return last ?? literalExpr("false");
452
+ }
453
+ const branch = branchAsts[start];
454
+ return {
455
+ kind: "conditionalExpression",
456
+ condition: {
457
+ kind: "invocationExpression",
458
+ expression: {
459
+ kind: "memberAccessExpression",
460
+ expression: identifierExpr(u),
461
+ memberName: `Is${start + 1}`,
462
+ },
463
+ arguments: [],
464
+ },
465
+ whenTrue: {
466
+ kind: "parenthesizedExpression",
467
+ expression: branch ?? literalExpr("false"),
468
+ },
469
+ whenFalse: {
470
+ kind: "parenthesizedExpression",
471
+ expression: buildChain(start + 1),
472
+ },
473
+ };
474
+ };
475
+ const chainAst = buildChain(0);
476
+ // Build: (operand is var u && u is not null && (chain))
477
+ return [
478
+ {
479
+ kind: "parenthesizedExpression",
480
+ expression: {
481
+ kind: "binaryExpression",
482
+ operatorToken: "&&",
483
+ left: {
484
+ kind: "binaryExpression",
485
+ operatorToken: "&&",
486
+ left: {
487
+ kind: "isExpression",
488
+ expression: wrapForIs(emittedAst),
489
+ pattern: { kind: "varPattern", designation: u },
490
+ },
491
+ right: {
492
+ kind: "isExpression",
493
+ expression: identifierExpr(u),
494
+ pattern: {
495
+ kind: "negatedPattern",
496
+ pattern: {
497
+ kind: "constantPattern",
498
+ expression: literalExpr("null"),
499
+ },
500
+ },
501
+ },
502
+ },
503
+ right: {
504
+ kind: "parenthesizedExpression",
505
+ expression: chainAst,
506
+ },
507
+ },
508
+ },
509
+ chainCtx,
510
+ ];
511
+ }
512
+ // Fallback for unions >8 (emitted as object): runtime truthiness matches JS semantics.
513
+ return emitRuntimeTruthinessConditionAst(emittedAst, context);
514
+ };
515
+ // ============================================================
516
+ // Main boolean-condition lowering (AST-native)
517
+ // ============================================================
518
+ /**
519
+ * Convert an expression to a valid C# boolean condition, returning a typed AST node.
520
+ *
521
+ * Rules (deterministic):
522
+ * - Booleans: use as-is
523
+ * - Reference types (objects, arrays, dictionaries, unions, ...): runtime truthiness
524
+ * - Strings: `!string.IsNullOrEmpty(expr)`
525
+ * - Numbers: JS truthiness check: false iff 0 or NaN
526
+ * - int: `expr != 0`
527
+ * - char: `expr != '\0'`
528
+ * - null/undefined literals: `false`
529
+ */
530
+ export const toBooleanConditionAst = (expr, emittedAst, context) => {
531
+ const inferredType = expr.inferredType;
532
+ const resolved = inferredType
533
+ ? resolveLocalTypeAlias(coerceClrPrimitiveToPrimitiveType(inferredType) ?? inferredType, context)
534
+ : undefined;
535
+ const type = resolved;
536
+ // Literal truthiness can be fully resolved without re-evaluating anything.
537
+ if (expr.kind === "literal") {
538
+ if (expr.value === null || expr.value === undefined) {
539
+ return [literalExpr("false"), context];
540
+ }
541
+ if (typeof expr.value === "boolean") {
542
+ return [literalExpr(expr.value ? "true" : "false"), context];
543
+ }
544
+ if (typeof expr.value === "number") {
545
+ return [literalExpr(expr.value === 0 ? "false" : "true"), context];
546
+ }
547
+ if (typeof expr.value === "string") {
548
+ return [literalExpr(expr.value.length === 0 ? "false" : "true"), context];
549
+ }
550
+ }
551
+ // If already boolean, use as-is
552
+ if (isBooleanCondition(expr)) {
553
+ return [emittedAst, context];
554
+ }
555
+ // If we can prove from syntax alone that this is a boolean expression, use as-is.
556
+ if (isInherentlyBooleanExpression(expr)) {
557
+ return [emittedAst, context];
558
+ }
559
+ // Unknown/any/missing type: use a safe runtime truthiness check instead of `!= null`,
560
+ // which can silently miscompile boxed value types (e.g., bool).
561
+ if (!type || type.kind === "unknownType" || type.kind === "anyType") {
562
+ return emitRuntimeTruthinessConditionAst(emittedAst, context);
563
+ }
564
+ if (type.kind === "unionType") {
565
+ return emitUnionTruthinessConditionAst(expr, emittedAst, type, context);
566
+ }
567
+ // Non-primitive types in TS can still map to CLR value types (e.g. `long`, `System.Boolean` wrappers).
568
+ // Never emit `x != null` here: it can silently miscompile boxed value types (always true).
569
+ // Use canonical runtime truthiness instead.
570
+ if (type.kind !== "primitiveType") {
571
+ return emitRuntimeTruthinessConditionAst(emittedAst, context);
572
+ }
573
+ // For primitives that are not boolean
574
+ if (type.kind === "primitiveType") {
575
+ switch (type.name) {
576
+ case "null":
577
+ case "undefined":
578
+ return [literalExpr("false"), context];
579
+ case "string":
580
+ // !string.IsNullOrEmpty(expr)
581
+ return [
582
+ {
583
+ kind: "parenthesizedExpression",
584
+ expression: {
585
+ kind: "prefixUnaryExpression",
586
+ operatorToken: "!",
587
+ operand: {
588
+ kind: "invocationExpression",
589
+ expression: {
590
+ kind: "memberAccessExpression",
591
+ expression: literalExpr("string"),
592
+ memberName: "IsNullOrEmpty",
593
+ },
594
+ arguments: [emittedAst],
595
+ },
596
+ },
597
+ },
598
+ context,
599
+ ];
600
+ case "int":
601
+ // expr != 0
602
+ return [
603
+ {
604
+ kind: "parenthesizedExpression",
605
+ expression: {
606
+ kind: "binaryExpression",
607
+ operatorToken: "!=",
608
+ left: emittedAst,
609
+ right: literalExpr("0"),
610
+ },
611
+ },
612
+ context,
613
+ ];
614
+ case "char":
615
+ // expr != '\0'
616
+ return [
617
+ {
618
+ kind: "parenthesizedExpression",
619
+ expression: {
620
+ kind: "binaryExpression",
621
+ operatorToken: "!=",
622
+ left: emittedAst,
623
+ right: literalExpr("'\\0'"),
624
+ },
625
+ },
626
+ context,
627
+ ];
628
+ case "number": {
629
+ // JS truthiness for numbers: falsy iff 0 or NaN.
630
+ // Use a pattern var to avoid evaluating the expression twice.
631
+ // Build: (operand is double __tmp && __tmp != 0 && !double.IsNaN(__tmp))
632
+ const nextId = (context.tempVarId ?? 0) + 1;
633
+ const ctxWithId = { ...context, tempVarId: nextId };
634
+ const numAlloc = allocateLocalName(`__tsonic_truthy_num_${nextId}`, ctxWithId);
635
+ const tmp = numAlloc.emittedName;
636
+ return [
637
+ {
638
+ kind: "parenthesizedExpression",
639
+ expression: {
640
+ kind: "binaryExpression",
641
+ operatorToken: "&&",
642
+ left: {
643
+ kind: "isExpression",
644
+ expression: wrapForIs(emittedAst),
645
+ pattern: {
646
+ kind: "declarationPattern",
647
+ type: { kind: "predefinedType", keyword: "double" },
648
+ designation: tmp,
649
+ },
650
+ },
651
+ right: {
652
+ kind: "binaryExpression",
653
+ operatorToken: "&&",
654
+ left: {
655
+ kind: "binaryExpression",
656
+ operatorToken: "!=",
657
+ left: identifierExpr(tmp),
658
+ right: literalExpr("0"),
659
+ },
660
+ right: {
661
+ kind: "prefixUnaryExpression",
662
+ operatorToken: "!",
663
+ operand: {
664
+ kind: "invocationExpression",
665
+ expression: {
666
+ kind: "memberAccessExpression",
667
+ expression: literalExpr("double"),
668
+ memberName: "IsNaN",
669
+ },
670
+ arguments: [identifierExpr(tmp)],
671
+ },
672
+ },
673
+ },
674
+ },
675
+ },
676
+ numAlloc.context,
677
+ ];
678
+ }
679
+ case "boolean":
680
+ return [emittedAst, context];
681
+ }
682
+ }
683
+ return [emittedAst, context];
684
+ };
685
+ /**
686
+ * Emit a boolean-context expression as a typed AST node.
687
+ *
688
+ * Special-cases logical &&/|| into proper binaryExpression AST nodes
689
+ * with printer-handled parenthesization.
690
+ */
691
+ export const emitBooleanConditionAst = (expr, emitExprAst, context) => {
692
+ if (expr.kind === "logical" &&
693
+ (expr.operator === "&&" || expr.operator === "||")) {
694
+ const [leftAst, leftCtx] = emitBooleanConditionAst(expr.left, emitExprAst, context);
695
+ const [rightAst, rightCtx] = emitBooleanConditionAst(expr.right, emitExprAst, leftCtx);
696
+ return [
697
+ {
698
+ kind: "binaryExpression",
699
+ operatorToken: expr.operator,
700
+ left: leftAst,
701
+ right: rightAst,
702
+ },
703
+ rightCtx,
704
+ ];
705
+ }
706
+ const [exprAst, exprCtx] = emitExprAst(expr, context);
707
+ return toBooleanConditionAst(expr, exprAst, exprCtx);
708
+ };
709
+ /**
710
+ * Whether a type is boolean.
711
+ *
712
+ * Used by callers that need a fast check (e.g., logical operator selection).
713
+ */
714
+ export const isBooleanType = (type) => {
715
+ return !!type && type.kind === "primitiveType" && type.name === "boolean";
716
+ };
717
+ //# sourceMappingURL=boolean-context.js.map