@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
@@ -1,913 +1,6 @@
1
1
  /**
2
2
  * Call and new expression emitters
3
3
  */
4
- import { emitExpression } from "../expression-emitter.js";
5
- import { emitTypeArguments, generateSpecializedName } from "./identifiers.js";
6
- import { emitType } from "../type-emitter.js";
7
- import { formatPostfixExpressionText } from "./parentheses.js";
8
- import { emitMemberAccess } from "./access.js";
9
- import { containsTypeParameter } from "../core/type-resolution.js";
10
- /**
11
- * Ref/out/in parameter handling:
12
- * The frontend extracts parameter passing modes from resolved signatures
13
- * and attaches them to IrCallExpression.argumentPassing array.
14
- * The emitter reads this array and prefixes arguments with ref/out/in keywords.
15
- */
16
- /**
17
- * Check if an expression is an lvalue (can be passed by reference)
18
- * Only identifiers and member accesses are lvalues in C#
19
- */
20
- const isLValue = (expr) => {
21
- return expr.kind === "identifier" || expr.kind === "memberAccess";
22
- };
23
- /**
24
- * Check if an expression has an `as out<T>`, `as ref<T>`, or `as inref<T>` cast.
25
- * Returns the modifier ("out", "ref", "in") or undefined if not a passing modifier cast.
26
- *
27
- * When TypeScript code has `value as out<int>`, the frontend converts this to
28
- * an expression with `inferredType: { kind: "referenceType", name: "out", ... }`.
29
- */
30
- const getPassingModifierFromCast = (expr) => {
31
- const inferredType = expr.inferredType;
32
- if (!inferredType || inferredType.kind !== "referenceType") {
33
- return undefined;
34
- }
35
- const typeName = inferredType.name;
36
- if (typeName === "out")
37
- return "out";
38
- if (typeName === "ref")
39
- return "ref";
40
- if (typeName === "inref")
41
- return "in"; // inref maps to C# 'in' keyword
42
- return undefined;
43
- };
44
- /**
45
- * Check if a member access expression targets System.Text.Json.JsonSerializer
46
- */
47
- const isJsonSerializerCall = (callee) => {
48
- if (callee.kind !== "memberAccess")
49
- return null;
50
- if (!callee.memberBinding)
51
- return null;
52
- const { type, member } = callee.memberBinding;
53
- // Check if this is System.Text.Json.JsonSerializer
54
- if (type !== "System.Text.Json.JsonSerializer")
55
- return null;
56
- // Check if the member is Serialize or Deserialize
57
- if (member === "Serialize")
58
- return { method: "Serialize" };
59
- if (member === "Deserialize")
60
- return { method: "Deserialize" };
61
- return null;
62
- };
63
- /**
64
- * Check if a call targets global JSON.stringify or JSON.parse
65
- * These global JSON methods compile to JsonSerializer
66
- */
67
- const isGlobalJsonCall = (callee) => {
68
- if (callee.kind !== "memberAccess")
69
- return null;
70
- // Check if object is the global JSON identifier
71
- const obj = callee.object;
72
- if (obj.kind !== "identifier" || obj.name !== "JSON")
73
- return null;
74
- // Check property name
75
- const prop = callee.property;
76
- if (typeof prop !== "string")
77
- return null;
78
- if (prop === "stringify")
79
- return { method: "Serialize" };
80
- if (prop === "parse")
81
- return { method: "Deserialize" };
82
- return null;
83
- };
84
- /**
85
- * Heuristic: Determine if a member access is an instance-style access (receiver.value)
86
- * vs a static type reference (Type.Member).
87
- *
88
- * This mirrors the logic in emitMemberAccess; extension-method lowering only applies
89
- * to instance-style member accesses.
90
- */
91
- const isInstanceMemberAccess = (expr, context) => {
92
- // Imported types (e.g., `Enumerable.Where(...)`) are static receiver expressions,
93
- // even if TypeScript assigns them an inferredType.
94
- if (expr.object.kind === "identifier") {
95
- const importBinding = context.importBindings?.get(expr.object.name);
96
- if (importBinding?.kind === "type") {
97
- return false;
98
- }
99
- // If this isn't an import and we don't have a receiver type, default to instance.
100
- // This matches emitMemberAccess's behavior and prevents local variables from being
101
- // misclassified as static type receivers (which breaks extension method lowering).
102
- if (!expr.object.inferredType) {
103
- return true;
104
- }
105
- }
106
- const objectType = expr.object.inferredType;
107
- return (objectType?.kind === "referenceType" ||
108
- objectType?.kind === "arrayType" ||
109
- objectType?.kind === "intersectionType" ||
110
- objectType?.kind === "unionType" ||
111
- objectType?.kind === "primitiveType" ||
112
- objectType?.kind === "literalType" ||
113
- objectType?.kind === "typeParameterType" ||
114
- objectType?.kind === "unknownType");
115
- };
116
- /**
117
- * Whether to emit an extension method call using fluent instance syntax (receiver.Method(...))
118
- * instead of explicit static invocation (Type.Method(receiver, ...)).
119
- *
120
- * Default: prefer static invocation to avoid relying on `using` directives and to avoid
121
- * accidental binding to an instance member when a type has both an instance method and
122
- * an extension method with the same name.
123
- *
124
- * Exception: certain toolchains (notably EF query precompilation) require the *syntax*
125
- * of extension-method invocation so the analyzer can locate queries in user code.
126
- */
127
- const shouldEmitFluentExtensionCall = (bindingType, memberName) => {
128
- // EF Core query precompilation requires fluent/extension syntax specifically for Queryable.
129
- // Keep Enumerable as explicit static invocation by default to avoid accidental binding to
130
- // instance methods on custom enumerable types.
131
- if (bindingType.startsWith("System.Linq.Queryable"))
132
- return true;
133
- // EF Core query operators (Include/ThenInclude/AsNoTracking/etc.)
134
- if (bindingType.startsWith("Microsoft.EntityFrameworkCore."))
135
- return true;
136
- // EF Core query precompilation also requires fluent syntax for certain Enumerable terminal ops
137
- // (e.g., IQueryable<T>.ToList()/ToArray()). When emitted as explicit static calls
138
- // (Enumerable.ToList(query)), dotnet-ef may not generate interceptors, causing runtime failure
139
- // under NativeAOT ("Query wasn't precompiled and dynamic code isn't supported").
140
- if (bindingType.startsWith("System.Linq.Enumerable") &&
141
- (memberName === "ToList" || memberName === "ToArray")) {
142
- return true;
143
- }
144
- return false;
145
- };
146
- const getTypeNamespace = (typeName) => {
147
- const lastDot = typeName.lastIndexOf(".");
148
- if (lastDot <= 0)
149
- return undefined;
150
- return typeName.slice(0, lastDot);
151
- };
152
- /**
153
- * Whether a C# type string is a builtin/keyword type (optionally nullable).
154
- *
155
- * These must NOT be qualified with a namespace (e.g. `object`, not `MyNs.object`).
156
- */
157
- const isCSharpBuiltinType = (typeStr) => {
158
- const base = typeStr.endsWith("?") ? typeStr.slice(0, -1) : typeStr;
159
- return (base === "string" ||
160
- base === "int" ||
161
- base === "long" ||
162
- base === "short" ||
163
- base === "byte" ||
164
- base === "sbyte" ||
165
- base === "uint" ||
166
- base === "ulong" ||
167
- base === "ushort" ||
168
- base === "float" ||
169
- base === "double" ||
170
- base === "decimal" ||
171
- base === "bool" ||
172
- base === "char" ||
173
- base === "object" ||
174
- base === "void");
175
- };
176
- /**
177
- * Ensure a C# type string has global:: prefix for unambiguous resolution
178
- */
179
- const ensureGlobalPrefix = (typeStr) => {
180
- // Skip already-prefixed types
181
- if (typeStr.startsWith("global::")) {
182
- return typeStr;
183
- }
184
- // Handle pointer types (T*). `global::int*` is invalid; qualify the element type only.
185
- if (typeStr.endsWith("*")) {
186
- const inner = typeStr.slice(0, -1);
187
- return `${ensureGlobalPrefix(inner)}*`;
188
- }
189
- // Handle arrays (T[], T[,], jagged arrays, ...). `global::string[]` is invalid; qualify
190
- // the element type only.
191
- const arrayMatch = /(\[[,\s]*\])$/.exec(typeStr);
192
- if (arrayMatch) {
193
- const suffix = arrayMatch[1];
194
- if (!suffix)
195
- return typeStr;
196
- const inner = typeStr.slice(0, -suffix.length);
197
- return `${ensureGlobalPrefix(inner)}${suffix}`;
198
- }
199
- // Skip primitives (and other builtin keyword types) after handling suffix forms.
200
- if (isCSharpBuiltinType(typeStr)) {
201
- return typeStr;
202
- }
203
- // Handle generic types: List<Foo> -> global::List<global::Foo>
204
- // For now, just add prefix to the outer type
205
- // The inner types should already be handled by emitType
206
- return `global::${typeStr}`;
207
- };
208
- /**
209
- * Register a type with the JSON AOT registry.
210
- * Ensures types are fully qualified with namespace for the AOT source generator.
211
- */
212
- const registerJsonAotType = (type, context) => {
213
- if (!type)
214
- return;
215
- if (!context.options.jsonAotRegistry)
216
- return;
217
- // NativeAOT JSON source generation requires CLOSED types.
218
- // If the type contains any generic parameters in the current scope (T, U, ...),
219
- // we cannot emit `[JsonSerializable(typeof(T))]` because `T` is not in scope in the
220
- // generated context class. Skip registration to keep emission valid.
221
- if (containsTypeParameter(type, context.typeParameters ?? new Set())) {
222
- context.options.jsonAotRegistry.needsJsonAot = true;
223
- return;
224
- }
225
- const registry = context.options.jsonAotRegistry;
226
- const [rawTypeStr] = emitType(type, { ...context, qualifyLocalTypes: true });
227
- const typeStr = rawTypeStr.endsWith("?")
228
- ? rawTypeStr.slice(0, -1)
229
- : rawTypeStr;
230
- registry.rootTypes.add(ensureGlobalPrefix(typeStr));
231
- registry.needsJsonAot = true;
232
- };
233
- /**
234
- * Check if a call expression needs an explicit cast because the inferred type
235
- * differs from the C# return type. This handles cases like Math.floor() which
236
- * returns double in C# but is cast to int in TypeScript via `as int`.
237
- */
238
- const needsIntCast = (expr, calleeName) => {
239
- // Check if the inferred type is int (a reference type from @tsonic/core)
240
- const inferredType = expr.inferredType;
241
- if (!inferredType ||
242
- inferredType.kind !== "referenceType" ||
243
- inferredType.name !== "int") {
244
- return false;
245
- }
246
- // Check if this is a Math method that returns double
247
- const mathMethodsReturningDouble = [
248
- "Math.floor",
249
- "Math.ceil",
250
- "Math.round",
251
- "Math.abs",
252
- "Math.pow",
253
- "Math.sqrt",
254
- "Math.min",
255
- "Math.max",
256
- ];
257
- return mathMethodsReturningDouble.some((m) => calleeName === m || calleeName.endsWith(`.${m.split(".").pop()}`));
258
- };
259
- /**
260
- * Emit a JsonSerializer call with NativeAOT-compatible options.
261
- * Rewrites:
262
- * JsonSerializer.Serialize(value) → JsonSerializer.Serialize(value, TsonicJson.Options)
263
- * JsonSerializer.Deserialize<T>(json) → JsonSerializer.Deserialize<T>(json, TsonicJson.Options)
264
- */
265
- const emitJsonSerializerCall = (expr, context, method) => {
266
- let currentContext = context;
267
- // Register the type with the JSON AOT registry
268
- if (method === "Serialize") {
269
- // For Serialize, get type from first argument's inferredType
270
- const firstArg = expr.arguments[0];
271
- if (firstArg && firstArg.kind !== "spread") {
272
- registerJsonAotType(firstArg.inferredType, context);
273
- }
274
- }
275
- else {
276
- // For Deserialize, get type from type arguments
277
- const typeArg = expr.typeArguments?.[0];
278
- if (typeArg) {
279
- registerJsonAotType(typeArg, context);
280
- }
281
- }
282
- // Emit type arguments for Deserialize<T>
283
- let typeArgsStr = "";
284
- if (expr.typeArguments && expr.typeArguments.length > 0) {
285
- const [typeArgs, typeContext] = emitTypeArguments(expr.typeArguments, currentContext);
286
- typeArgsStr = typeArgs;
287
- currentContext = typeContext;
288
- }
289
- // Emit arguments
290
- const args = [];
291
- for (const arg of expr.arguments) {
292
- if (arg.kind === "spread") {
293
- const [spreadFrag, ctx] = emitExpression(arg.expression, currentContext);
294
- args.push(spreadFrag.text);
295
- currentContext = ctx;
296
- }
297
- else {
298
- const [argFrag, ctx] = emitExpression(arg, currentContext);
299
- args.push(argFrag.text);
300
- currentContext = ctx;
301
- }
302
- }
303
- // Add TsonicJson.Options only when NativeAOT JSON context generation is enabled.
304
- if (context.options.jsonAotRegistry) {
305
- args.push("TsonicJson.Options");
306
- }
307
- const text = `global::System.Text.Json.JsonSerializer.${method}${typeArgsStr}(${args.join(", ")})`;
308
- return [{ text }, currentContext];
309
- };
310
- /**
311
- * Emit a function call expression
312
- */
313
- export const emitCall = (expr, context) => {
314
- // Void promise resolve: emit as zero-arg call when safe.
315
- // C# Action (zero-arg) cannot accept arguments, so resolve() and resolve(undefined)
316
- // both map to resolve(). Only strip when there are no arguments or a single
317
- // `undefined` identifier — other argument forms may have side effects that must
318
- // not be dropped. Name-based matching is scoped to the executor body; shadowing
319
- // the resolve name inside the executor is technically possible but extremely rare.
320
- if (expr.callee.kind === "identifier" &&
321
- context.voidResolveNames?.has(expr.callee.name)) {
322
- const isZeroArg = expr.arguments.length === 0;
323
- const isSingleUndefined = expr.arguments.length === 1 &&
324
- expr.arguments[0]?.kind === "identifier" &&
325
- expr.arguments[0].name === "undefined";
326
- if (isZeroArg || isSingleUndefined) {
327
- const [calleeFrag, calleeCtx] = emitExpression(expr.callee, context);
328
- const calleeText = formatPostfixExpressionText(expr.callee, calleeFrag.text);
329
- return [{ text: `${calleeText}()` }, calleeCtx];
330
- }
331
- }
332
- // Check for JsonSerializer calls (NativeAOT support)
333
- const jsonCall = isJsonSerializerCall(expr.callee);
334
- if (jsonCall) {
335
- return emitJsonSerializerCall(expr, context, jsonCall.method);
336
- }
337
- // Check for global JSON.stringify/parse calls
338
- // These compile to JsonSerializer.Serialize/Deserialize
339
- const globalJsonCall = isGlobalJsonCall(expr.callee);
340
- if (globalJsonCall) {
341
- return emitJsonSerializerCall(expr, context, globalJsonCall.method);
342
- }
343
- // EF Core query precompilation has a known limitation: `query.ToList().ToArray()`
344
- // fails to precompile (captured locals may be treated as "unknown identifiers").
345
- // Since `ToList().ToArray()` is equivalent to `ToArray()` for IEnumerable<T>,
346
- // canonicalize this pattern to `query.ToArray()` so NativeAOT precompilation works.
347
- if (expr.callee.kind === "memberAccess" &&
348
- expr.callee.property === "ToArray" &&
349
- expr.arguments.length === 0 &&
350
- expr.callee.object.kind === "call") {
351
- const innerCall = expr.callee.object;
352
- if (innerCall.callee.kind === "memberAccess" &&
353
- innerCall.callee.memberBinding?.isExtensionMethod &&
354
- isInstanceMemberAccess(innerCall.callee, context) &&
355
- innerCall.callee.memberBinding.type.startsWith("System.Linq.Enumerable") &&
356
- innerCall.callee.memberBinding.member === "ToList" &&
357
- innerCall.arguments.length === 0) {
358
- let currentContext = context;
359
- // Ensure extension methods are in scope.
360
- currentContext.usings.add("System.Linq");
361
- const receiverExpr = innerCall.callee.object;
362
- const [receiverFrag, receiverCtx] = emitExpression(receiverExpr, currentContext);
363
- currentContext = receiverCtx;
364
- const receiverText = formatPostfixExpressionText(receiverExpr, receiverFrag.text);
365
- const text = `${receiverText}.ToArray()`;
366
- return [{ text }, currentContext];
367
- }
368
- }
369
- // Extension method lowering: emit explicit static invocation with receiver as first arg.
370
- // This avoids relying on C# `using` directives for extension method discovery.
371
- if (expr.callee.kind === "memberAccess" &&
372
- expr.callee.memberBinding?.isExtensionMethod &&
373
- isInstanceMemberAccess(expr.callee, context)) {
374
- let currentContext = context;
375
- const binding = expr.callee.memberBinding;
376
- const receiverExpr = expr.callee.object;
377
- const [receiverFrag, receiverContext] = emitExpression(receiverExpr, currentContext);
378
- currentContext = receiverContext;
379
- // Some ecosystems (notably EF Core query precompilation) require fluent syntax
380
- // so the tooling can locate queries in syntax trees. For those namespaces,
381
- // emit `receiver.Method(...)` and add a `using` directive for the namespace.
382
- if (shouldEmitFluentExtensionCall(binding.type, binding.member)) {
383
- const ns = getTypeNamespace(binding.type);
384
- if (ns) {
385
- currentContext.usings.add(ns);
386
- }
387
- // Handle generic type arguments
388
- let typeArgsStr = "";
389
- if (expr.typeArguments && expr.typeArguments.length > 0) {
390
- const [typeArgs, typeContext] = emitTypeArguments(expr.typeArguments, currentContext);
391
- typeArgsStr = typeArgs;
392
- currentContext = typeContext;
393
- }
394
- // Get parameter types from IR (extracted from resolved signature in frontend)
395
- const parameterTypes = expr.parameterTypes ?? [];
396
- const args = [];
397
- for (let i = 0; i < expr.arguments.length; i++) {
398
- const arg = expr.arguments[i];
399
- if (!arg)
400
- continue;
401
- const expectedType = parameterTypes[i];
402
- if (arg.kind === "spread") {
403
- const [spreadFrag, ctx] = emitExpression(arg.expression, currentContext);
404
- args.push(`params ${spreadFrag.text}`);
405
- currentContext = ctx;
406
- }
407
- else {
408
- const castModifier = getPassingModifierFromCast(arg);
409
- if (castModifier && isLValue(arg)) {
410
- const [argFrag, ctx] = emitExpression(arg, currentContext);
411
- args.push(`${castModifier} ${argFrag.text}`);
412
- currentContext = ctx;
413
- }
414
- else {
415
- const [argFrag, ctx] = emitExpression(arg, currentContext, expectedType);
416
- const passingMode = expr.argumentPassing?.[i];
417
- const prefix = passingMode && passingMode !== "value" && isLValue(arg)
418
- ? `${passingMode} `
419
- : "";
420
- args.push(`${prefix}${argFrag.text}`);
421
- currentContext = ctx;
422
- }
423
- }
424
- }
425
- const receiverText = formatPostfixExpressionText(receiverExpr, receiverFrag.text);
426
- const op = expr.isOptional ? "?." : ".";
427
- const baseCallText = `${receiverText}${op}${binding.member}${typeArgsStr}(${args.join(", ")})`;
428
- const text = needsIntCast(expr, binding.member)
429
- ? `(int)${baseCallText}`
430
- : baseCallText;
431
- return [{ text }, currentContext];
432
- }
433
- let finalCalleeName = `global::${binding.type}.${binding.member}`;
434
- // Handle generic type arguments
435
- let typeArgsStr = "";
436
- if (expr.typeArguments && expr.typeArguments.length > 0) {
437
- if (expr.requiresSpecialization) {
438
- const [specializedName, specContext] = generateSpecializedName(finalCalleeName, expr.typeArguments, currentContext);
439
- finalCalleeName = specializedName;
440
- currentContext = specContext;
441
- }
442
- else {
443
- const [typeArgs, typeContext] = emitTypeArguments(expr.typeArguments, currentContext);
444
- typeArgsStr = typeArgs;
445
- currentContext = typeContext;
446
- }
447
- }
448
- const parameterTypes = expr.parameterTypes ?? [];
449
- const args = [receiverFrag.text];
450
- for (let i = 0; i < expr.arguments.length; i++) {
451
- const arg = expr.arguments[i];
452
- if (!arg)
453
- continue;
454
- const expectedType = parameterTypes[i];
455
- if (arg.kind === "spread") {
456
- const [spreadFrag, ctx] = emitExpression(arg.expression, currentContext);
457
- args.push(`params ${spreadFrag.text}`);
458
- currentContext = ctx;
459
- }
460
- else {
461
- const castModifier = getPassingModifierFromCast(arg);
462
- if (castModifier && isLValue(arg)) {
463
- const [argFrag, ctx] = emitExpression(arg, currentContext);
464
- args.push(`${castModifier} ${argFrag.text}`);
465
- currentContext = ctx;
466
- }
467
- else {
468
- const [argFrag, ctx] = emitExpression(arg, currentContext, expectedType);
469
- const passingMode = expr.argumentPassing?.[i];
470
- const prefix = passingMode && passingMode !== "value" && isLValue(arg)
471
- ? `${passingMode} `
472
- : "";
473
- args.push(`${prefix}${argFrag.text}`);
474
- currentContext = ctx;
475
- }
476
- }
477
- }
478
- const baseCallText = `${finalCalleeName}${typeArgsStr}(${args.join(", ")})`;
479
- // JS runtime helpers often return List<T> for array-like results, while the IR
480
- // models them as native CLR arrays. When the IR expects an array, coerce via
481
- // Enumerable.ToArray to preserve the IR contract.
482
- const callText = expr.inferredType?.kind === "arrayType"
483
- ? `global::System.Linq.Enumerable.ToArray(${baseCallText})`
484
- : baseCallText;
485
- const text = needsIntCast(expr, finalCalleeName)
486
- ? `(int)${callText}`
487
- : callText;
488
- return [{ text }, currentContext];
489
- }
490
- // Regular function call
491
- const [calleeFrag, newContext] = expr.callee.kind === "memberAccess"
492
- ? emitMemberAccess(expr.callee, context, "call")
493
- : emitExpression(expr.callee, context);
494
- let currentContext = newContext;
495
- // Handle generic type arguments
496
- let typeArgsStr = "";
497
- let finalCalleeName = calleeFrag.text;
498
- if (expr.typeArguments && expr.typeArguments.length > 0) {
499
- if (expr.requiresSpecialization) {
500
- // Monomorphisation: Generate specialized method name
501
- // e.g., process<string> → process__string
502
- const [specializedName, specContext] = generateSpecializedName(calleeFrag.text, expr.typeArguments, currentContext);
503
- finalCalleeName = specializedName;
504
- currentContext = specContext;
505
- }
506
- else {
507
- // Emit explicit type arguments for generic call
508
- // e.g., identity<string>(value)
509
- const [typeArgs, typeContext] = emitTypeArguments(expr.typeArguments, currentContext);
510
- typeArgsStr = typeArgs;
511
- currentContext = typeContext;
512
- }
513
- }
514
- // Get parameter types from IR (extracted from resolved signature in frontend)
515
- const parameterTypes = expr.parameterTypes ?? [];
516
- const args = [];
517
- for (let i = 0; i < expr.arguments.length; i++) {
518
- const arg = expr.arguments[i];
519
- if (!arg)
520
- continue; // Skip undefined (shouldn't happen in valid IR)
521
- // Get expected type for this argument from parameter types
522
- const expectedType = parameterTypes[i];
523
- if (arg.kind === "spread") {
524
- // Spread in function call
525
- const [spreadFrag, ctx] = emitExpression(arg.expression, currentContext);
526
- args.push(`params ${spreadFrag.text}`);
527
- currentContext = ctx;
528
- }
529
- else {
530
- // Check if this argument has an explicit `as out<T>` / `as ref<T>` / `as inref<T>` cast
531
- const castModifier = getPassingModifierFromCast(arg);
532
- if (castModifier && isLValue(arg)) {
533
- // Emit the expression without the cast wrapper, with the modifier prefix
534
- // For `value as out<int>`, emit `out value`
535
- const [argFrag, ctx] = emitExpression(arg, currentContext);
536
- args.push(`${castModifier} ${argFrag.text}`);
537
- currentContext = ctx;
538
- }
539
- else {
540
- const [argFrag, ctx] = emitExpression(arg, currentContext, expectedType);
541
- // Check if this argument needs ref/out/in prefix from function signature
542
- // Only add prefix if argument is an lvalue (identifier or member access)
543
- const passingMode = expr.argumentPassing?.[i];
544
- const prefix = passingMode && passingMode !== "value" && isLValue(arg)
545
- ? `${passingMode} `
546
- : "";
547
- args.push(`${prefix}${argFrag.text}`);
548
- currentContext = ctx;
549
- }
550
- }
551
- }
552
- // For member-access calls, the receiver parenthesization is already handled inside
553
- // `emitMemberAccess`. Wrapping the full `obj.Member` in parentheses can change meaning
554
- // in C# (e.g., `(obj.Member)()` attempts to invoke a delegate rather than calling a method).
555
- const calleeText = expr.callee.kind === "memberAccess"
556
- ? `${finalCalleeName}${typeArgsStr}`
557
- : formatPostfixExpressionText(expr.callee, `${finalCalleeName}${typeArgsStr}`);
558
- const callOp = expr.isOptional ? "?." : "";
559
- const callText = `${calleeText}${callOp}(${args.join(", ")})`;
560
- // Add cast if needed (e.g., Math.floor returning double but asserted as int)
561
- const text = needsIntCast(expr, finalCalleeName)
562
- ? `(int)${callText}`
563
- : callText;
564
- return [{ text }, currentContext];
565
- };
566
- /**
567
- * Check if a new expression is new List<T>([...]) with an array literal argument
568
- * This pattern should be emitted as collection initializer: new List<T> { ... }
569
- */
570
- const isListConstructorWithArrayLiteral = (expr) => {
571
- // Only apply to BCL List<T> so the rewrite is semantics-safe.
572
- // (We rely on List<T> having a parameterless ctor + Add for collection initializer.)
573
- const inferredType = expr.inferredType;
574
- if (inferredType?.kind !== "referenceType") {
575
- return false;
576
- }
577
- const typeId = inferredType.typeId;
578
- if (!typeId ||
579
- !typeId.clrName.startsWith("System.Collections.Generic.List")) {
580
- return false;
581
- }
582
- // Must have exactly one type argument
583
- if (!expr.typeArguments || expr.typeArguments.length !== 1) {
584
- return false;
585
- }
586
- // Check if callee is identifier "List"
587
- if (expr.callee.kind !== "identifier" || expr.callee.name !== "List") {
588
- return false;
589
- }
590
- // Must have exactly one argument that is an array literal
591
- if (expr.arguments.length !== 1) {
592
- return false;
593
- }
594
- const arg = expr.arguments[0];
595
- if (!arg || arg.kind === "spread" || arg.kind !== "array") {
596
- return false;
597
- }
598
- // Collection initializers don't support spreads/holes, so reject them here.
599
- for (const element of arg.elements) {
600
- if (!element || element.kind === "spread") {
601
- return false;
602
- }
603
- }
604
- return true;
605
- };
606
- /**
607
- * Emit new List<T>([...]) as collection initializer: new List<T> { ... }
608
- *
609
- * Examples:
610
- * new List<int>([1, 2, 3]) → new List<int> { 1, 2, 3 }
611
- * new List<string>(["a", "b"]) → new List<string> { "a", "b" }
612
- * new List<User>([u1, u2]) → new List<User> { u1, u2 }
613
- */
614
- const emitListCollectionInitializer = (expr, context) => {
615
- let currentContext = context;
616
- const [calleeFrag, calleeContext] = emitExpression(expr.callee, currentContext);
617
- currentContext = calleeContext;
618
- // Handle generic type arguments consistently with emitNew()
619
- let typeArgsStr = "";
620
- let finalClassName = calleeFrag.text;
621
- if (expr.typeArguments && expr.typeArguments.length > 0) {
622
- if (expr.requiresSpecialization) {
623
- const [specializedName, specContext] = generateSpecializedName(calleeFrag.text, expr.typeArguments, currentContext);
624
- finalClassName = specializedName;
625
- currentContext = specContext;
626
- }
627
- else {
628
- const [typeArgs, typeContext] = emitTypeArguments(expr.typeArguments, currentContext);
629
- typeArgsStr = typeArgs;
630
- currentContext = typeContext;
631
- }
632
- }
633
- // Get the array literal argument
634
- const arrayLiteral = expr.arguments[0];
635
- // Emit each element
636
- const elements = [];
637
- for (const element of arrayLiteral.elements) {
638
- if (element === undefined) {
639
- continue; // Skip undefined slots (sparse arrays)
640
- }
641
- if (element.kind === "spread") {
642
- // Not supported (guarded by isListConstructorWithArrayLiteral)
643
- const [fallbackFrag, fallbackContext] = emitNew(expr, currentContext);
644
- return [fallbackFrag, fallbackContext];
645
- }
646
- else {
647
- const [elemFrag, ctx] = emitExpression(element, currentContext);
648
- elements.push(elemFrag.text);
649
- currentContext = ctx;
650
- }
651
- }
652
- // Use collection initializer syntax
653
- const text = elements.length === 0
654
- ? `new ${finalClassName}${typeArgsStr}()`
655
- : `new ${finalClassName}${typeArgsStr} { ${elements.join(", ")} }`;
656
- return [{ text }, currentContext];
657
- };
658
- /**
659
- * Check if a new expression is new Array<T>(size)
660
- * Returns the element type if it is, undefined otherwise
661
- */
662
- const isArrayConstructorCall = (expr) => {
663
- // Check if callee is identifier "Array"
664
- if (expr.callee.kind !== "identifier" || expr.callee.name !== "Array") {
665
- return false;
666
- }
667
- // Must have exactly one type argument
668
- if (!expr.typeArguments || expr.typeArguments.length !== 1) {
669
- return false;
670
- }
671
- return true;
672
- };
673
- /**
674
- * Emit new Array<T>(size) as new T[size]
675
- *
676
- * Examples:
677
- * new Array<int>(10) → new int[10]
678
- * new Array<string>(5) → new string[5]
679
- * new Array<User>(count) → new User[count]
680
- * new Array<int>() → new int[0]
681
- */
682
- const emitArrayConstructor = (expr, context) => {
683
- let currentContext = context;
684
- // Get the element type (verified by isArrayConstructorCall)
685
- const typeArgs = expr.typeArguments;
686
- const elementType = typeArgs?.[0];
687
- if (!elementType) {
688
- return [{ text: "new object[0]" }, currentContext];
689
- }
690
- const [elementTypeStr, typeContext] = emitType(elementType, currentContext);
691
- currentContext = typeContext;
692
- // Get the size argument (if any)
693
- let sizeStr = "0"; // Default to empty array if no size argument
694
- if (expr.arguments.length > 0) {
695
- const sizeArg = expr.arguments[0];
696
- if (sizeArg && sizeArg.kind !== "spread") {
697
- const [sizeFrag, sizeContext] = emitExpression(sizeArg, currentContext);
698
- sizeStr = sizeFrag.text;
699
- currentContext = sizeContext;
700
- }
701
- }
702
- const text = `new ${elementTypeStr}[${sizeStr}]`;
703
- return [{ text }, currentContext];
704
- };
705
- const isPromiseConstructorCall = (expr) => {
706
- return expr.callee.kind === "identifier" && expr.callee.name === "Promise";
707
- };
708
- const isVoidLikeType = (type) => {
709
- if (!type)
710
- return false;
711
- return (type.kind === "voidType" ||
712
- (type.kind === "primitiveType" && type.name === "undefined"));
713
- };
714
- /**
715
- * Check if a type contains `void` in a position where it would be emitted
716
- * as a C# generic type argument (union member, type argument, etc.).
717
- * C# forbids `void` as a generic type argument, so such types are invalid.
718
- */
719
- const containsVoidInGenericPosition = (type) => {
720
- if (!type)
721
- return false;
722
- if (type.kind === "unionType") {
723
- return type.types.some((t) => isVoidLikeType(t) || containsVoidInGenericPosition(t));
724
- }
725
- if (type.kind === "referenceType" && type.typeArguments) {
726
- return type.typeArguments.some((t) => isVoidLikeType(t) || containsVoidInGenericPosition(t));
727
- }
728
- if (type.kind === "functionType") {
729
- return (type.parameters.some((p) => containsVoidInGenericPosition(p.type)) ||
730
- containsVoidInGenericPosition(type.returnType));
731
- }
732
- return false;
733
- };
734
- const getPromiseValueType = (expr) => {
735
- const inferred = expr.inferredType;
736
- if (inferred?.kind === "referenceType") {
737
- const candidate = inferred.typeArguments?.[0];
738
- if (candidate && !isVoidLikeType(candidate)) {
739
- return candidate;
740
- }
741
- if (candidate && isVoidLikeType(candidate)) {
742
- return undefined;
743
- }
744
- }
745
- const explicit = expr.typeArguments?.[0];
746
- if (explicit && !isVoidLikeType(explicit)) {
747
- return explicit;
748
- }
749
- return undefined;
750
- };
751
- const getExecutorArity = (expr) => {
752
- const executor = expr.arguments[0];
753
- if (executor &&
754
- executor.kind !== "spread" &&
755
- (executor.kind === "arrowFunction" ||
756
- executor.kind === "functionExpression")) {
757
- return executor.parameters.length;
758
- }
759
- const executorType = expr.parameterTypes?.[0];
760
- if (executorType?.kind === "functionType") {
761
- return executorType.parameters.length;
762
- }
763
- return 1;
764
- };
765
- const emitPromiseConstructor = (expr, context) => {
766
- const executor = expr.arguments[0];
767
- if (!executor || executor.kind === "spread") {
768
- throw new Error("Unsupported Promise constructor form: expected an executor function argument.");
769
- }
770
- let currentContext = context;
771
- const [taskTypeTextRaw, taskTypeContext] = expr.inferredType
772
- ? emitType(expr.inferredType, currentContext)
773
- : ["global::System.Threading.Tasks.Task", currentContext];
774
- currentContext = taskTypeContext;
775
- const taskTypeText = taskTypeTextRaw.length > 0
776
- ? taskTypeTextRaw
777
- : "global::System.Threading.Tasks.Task";
778
- const promiseValueType = getPromiseValueType(expr);
779
- let valueTypeText = "bool";
780
- if (promiseValueType) {
781
- const [valueType, valueTypeContext] = emitType(promiseValueType, currentContext);
782
- valueTypeText = valueType;
783
- currentContext = valueTypeContext;
784
- }
785
- // For void promises, track the resolve parameter name so call emitter
786
- // can strip arguments from resolve(undefined) calls (C# Action is zero-arg)
787
- const resolveParam = !promiseValueType &&
788
- (executor.kind === "arrowFunction" ||
789
- executor.kind === "functionExpression")
790
- ? executor.parameters[0]
791
- : undefined;
792
- const resolveParamName = resolveParam?.pattern.kind === "identifierPattern"
793
- ? resolveParam.pattern.name
794
- : undefined;
795
- const executorEmitContext = resolveParamName
796
- ? { ...currentContext, voidResolveNames: new Set([resolveParamName]) }
797
- : currentContext;
798
- // For void promises, the resolve parameter's TS type may be
799
- // `(value: void | PromiseLike<void>) => void` which emits as `Action<Union<void, Task>>` —
800
- // invalid in C# (void cannot be a generic type argument). Strip the type annotation only
801
- // when it contains void-in-generic, letting C# infer from the outer delegate cast.
802
- // When the type is clean (e.g., `() => void` → `Action`), keep it for clarity.
803
- const resolveParamHasVoidGeneric = resolveParam?.type?.kind === "functionType" &&
804
- resolveParam.type.parameters.some((p) => containsVoidInGenericPosition(p.type));
805
- const emittedExecutor = resolveParamHasVoidGeneric &&
806
- (executor.kind === "arrowFunction" ||
807
- executor.kind === "functionExpression")
808
- ? {
809
- ...executor,
810
- parameters: executor.parameters.map((p, i) => i === 0 ? { ...p, type: undefined } : p),
811
- }
812
- : executor;
813
- const [executorFrag, executorContext] = emitExpression(emittedExecutor, executorEmitContext, expr.parameterTypes?.[0]);
814
- // Strip voidResolveNames from returned context to prevent leakage into enclosing scope
815
- currentContext = resolveParamName
816
- ? { ...executorContext, voidResolveNames: undefined }
817
- : executorContext;
818
- const executorText = formatPostfixExpressionText(executor, executorFrag.text);
819
- const executorArity = getExecutorArity(expr);
820
- const resolveCallbackType = promiseValueType
821
- ? `global::System.Action<${valueTypeText}>`
822
- : "global::System.Action";
823
- const executorDelegateType = executorArity >= 2
824
- ? `global::System.Action<${resolveCallbackType}, global::System.Action<object?>>`
825
- : `global::System.Action<${resolveCallbackType}>`;
826
- const executorInvokeTarget = `((${executorDelegateType})${executorText})`;
827
- const invokeArgs = executorArity >= 2
828
- ? "__tsonic_resolve, __tsonic_reject"
829
- : "__tsonic_resolve";
830
- const resolveDecl = promiseValueType
831
- ? `global::System.Action<${valueTypeText}> __tsonic_resolve = (value) => __tsonic_tcs.TrySetResult(value);`
832
- : "global::System.Action __tsonic_resolve = () => __tsonic_tcs.TrySetResult(true);";
833
- const text = `((global::System.Func<${taskTypeText}>)(() => { ` +
834
- `var __tsonic_tcs = new global::System.Threading.Tasks.TaskCompletionSource<${valueTypeText}>(); ` +
835
- `${resolveDecl} ` +
836
- `global::System.Action<object?> __tsonic_reject = (error) => __tsonic_tcs.TrySetException((error as global::System.Exception) ?? new global::System.Exception(error?.ToString() ?? "Promise rejected")); ` +
837
- `try { ${executorInvokeTarget}(${invokeArgs}); } catch (global::System.Exception ex) { __tsonic_tcs.TrySetException(ex); } ` +
838
- `return __tsonic_tcs.Task; }))()`;
839
- return [{ text }, currentContext];
840
- };
841
- /**
842
- * Emit a new expression
843
- */
844
- export const emitNew = (expr, context) => {
845
- // Special case: new Array<T>(size) → new T[size]
846
- if (isArrayConstructorCall(expr)) {
847
- return emitArrayConstructor(expr, context);
848
- }
849
- // Special case: new List<T>([...]) → new List<T> { ... }
850
- if (isListConstructorWithArrayLiteral(expr)) {
851
- return emitListCollectionInitializer(expr, context);
852
- }
853
- // Promise constructor lowering:
854
- // new Promise<T>((resolve, reject) => { ... })
855
- // becomes a TaskCompletionSource<T>-backed Task expression.
856
- if (isPromiseConstructorCall(expr)) {
857
- return emitPromiseConstructor(expr, context);
858
- }
859
- const [calleeFrag, newContext] = emitExpression(expr.callee, context);
860
- let currentContext = newContext;
861
- // Handle generic type arguments
862
- let typeArgsStr = "";
863
- let finalClassName = calleeFrag.text;
864
- if (expr.typeArguments && expr.typeArguments.length > 0) {
865
- if (expr.requiresSpecialization) {
866
- // Monomorphisation: Generate specialized class name
867
- // e.g., new Box<string>() → new Box__string()
868
- const [specializedName, specContext] = generateSpecializedName(calleeFrag.text, expr.typeArguments, currentContext);
869
- finalClassName = specializedName;
870
- currentContext = specContext;
871
- }
872
- else {
873
- // Emit explicit type arguments for generic constructor
874
- // e.g., new Box<string>(value)
875
- const [typeArgs, typeContext] = emitTypeArguments(expr.typeArguments, currentContext);
876
- typeArgsStr = typeArgs;
877
- currentContext = typeContext;
878
- }
879
- }
880
- const args = [];
881
- const parameterTypes = expr.parameterTypes ?? [];
882
- for (let i = 0; i < expr.arguments.length; i++) {
883
- const arg = expr.arguments[i];
884
- if (!arg)
885
- continue;
886
- if (arg.kind === "spread") {
887
- const [spreadFrag, ctx] = emitExpression(arg.expression, currentContext);
888
- args.push(`params ${spreadFrag.text}`);
889
- currentContext = ctx;
890
- }
891
- else {
892
- const expectedType = parameterTypes[i];
893
- const castModifier = getPassingModifierFromCast(arg);
894
- if (castModifier && isLValue(arg)) {
895
- const [argFrag, ctx] = emitExpression(arg, currentContext);
896
- args.push(`${castModifier} ${argFrag.text}`);
897
- currentContext = ctx;
898
- }
899
- else {
900
- const [argFrag, ctx] = emitExpression(arg, currentContext, expectedType);
901
- const passingMode = expr.argumentPassing?.[i];
902
- const prefix = passingMode && passingMode !== "value" && isLValue(arg)
903
- ? `${passingMode} `
904
- : "";
905
- args.push(`${prefix}${argFrag.text}`);
906
- currentContext = ctx;
907
- }
908
- }
909
- }
910
- const text = `new ${finalClassName}${typeArgsStr}(${args.join(", ")})`;
911
- return [{ text }, currentContext];
912
- };
4
+ export { emitCall } from "./calls/call-emitter.js";
5
+ export { emitNew } from "./calls/new-emitter.js";
913
6
  //# sourceMappingURL=calls.js.map