@tsonic/emitter 0.0.61 → 0.0.63

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (531) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/adapter-generator.d.ts +5 -15
  3. package/dist/adapter-generator.d.ts.map +1 -1
  4. package/dist/adapter-generator.js +60 -53
  5. package/dist/adapter-generator.js.map +1 -1
  6. package/dist/contracts/backend-adapter.d.ts +36 -0
  7. package/dist/contracts/backend-adapter.d.ts.map +1 -0
  8. package/dist/contracts/backend-adapter.js +9 -0
  9. package/dist/contracts/backend-adapter.js.map +1 -0
  10. package/dist/contracts/emitter-contract.d.ts +54 -0
  11. package/dist/contracts/emitter-contract.d.ts.map +1 -0
  12. package/dist/contracts/emitter-contract.js +8 -0
  13. package/dist/contracts/emitter-contract.js.map +1 -0
  14. package/dist/contracts/import-classifier.d.ts +36 -0
  15. package/dist/contracts/import-classifier.d.ts.map +1 -0
  16. package/dist/contracts/import-classifier.js +9 -0
  17. package/dist/contracts/import-classifier.js.map +1 -0
  18. package/dist/core/{attributes.d.ts → format/attributes.d.ts} +9 -14
  19. package/dist/core/format/attributes.d.ts.map +1 -0
  20. package/dist/core/format/attributes.js +190 -0
  21. package/dist/core/format/attributes.js.map +1 -0
  22. package/dist/core/format/attributes.test.d.ts.map +1 -0
  23. package/dist/core/{attributes.test.js → format/attributes.test.js} +70 -32
  24. package/dist/core/format/attributes.test.js.map +1 -0
  25. package/dist/core/format/backend-ast/index.d.ts +7 -0
  26. package/dist/core/format/backend-ast/index.d.ts.map +1 -0
  27. package/dist/core/format/backend-ast/index.js +6 -0
  28. package/dist/core/format/backend-ast/index.js.map +1 -0
  29. package/dist/core/format/backend-ast/printer.d.ts +33 -0
  30. package/dist/core/format/backend-ast/printer.d.ts.map +1 -0
  31. package/dist/core/format/backend-ast/printer.js +1151 -0
  32. package/dist/core/format/backend-ast/printer.js.map +1 -0
  33. package/dist/core/format/backend-ast/types.d.ts +504 -0
  34. package/dist/core/format/backend-ast/types.d.ts.map +1 -0
  35. package/dist/core/format/backend-ast/types.js +13 -0
  36. package/dist/core/format/backend-ast/types.js.map +1 -0
  37. package/dist/core/format/backend-ast/utils.d.ts +26 -0
  38. package/dist/core/format/backend-ast/utils.d.ts.map +1 -0
  39. package/dist/core/format/backend-ast/utils.js +65 -0
  40. package/dist/core/format/backend-ast/utils.js.map +1 -0
  41. package/dist/core/{exports.d.ts → format/exports.d.ts} +2 -2
  42. package/dist/core/format/exports.d.ts.map +1 -0
  43. package/dist/core/format/exports.js +22 -0
  44. package/dist/core/format/exports.js.map +1 -0
  45. package/dist/core/format/index.d.ts +9 -0
  46. package/dist/core/format/index.d.ts.map +1 -0
  47. package/dist/core/format/index.js +9 -0
  48. package/dist/core/format/index.js.map +1 -0
  49. package/dist/core/{local-names.d.ts → format/local-names.d.ts} +1 -1
  50. package/dist/core/format/local-names.d.ts.map +1 -0
  51. package/dist/core/{local-names.js → format/local-names.js} +3 -2
  52. package/dist/core/format/local-names.js.map +1 -0
  53. package/dist/core/format/module-emitter/assembly.d.ts +27 -0
  54. package/dist/core/format/module-emitter/assembly.d.ts.map +1 -0
  55. package/dist/core/format/module-emitter/assembly.js +44 -0
  56. package/dist/core/format/module-emitter/assembly.js.map +1 -0
  57. package/dist/core/{module-emitter → format/module-emitter}/header.d.ts +1 -1
  58. package/dist/core/format/module-emitter/header.d.ts.map +1 -0
  59. package/dist/core/{module-emitter → format/module-emitter}/header.js +1 -1
  60. package/dist/core/format/module-emitter/header.js.map +1 -0
  61. package/dist/core/format/module-emitter/index.d.ts.map +1 -0
  62. package/dist/core/format/module-emitter/index.js.map +1 -0
  63. package/dist/core/format/module-emitter/namespace.d.ts +21 -0
  64. package/dist/core/format/module-emitter/namespace.d.ts.map +1 -0
  65. package/dist/core/format/module-emitter/namespace.js +58 -0
  66. package/dist/core/format/module-emitter/namespace.js.map +1 -0
  67. package/dist/core/{module-emitter → format/module-emitter}/orchestrator.d.ts +1 -1
  68. package/dist/core/format/module-emitter/orchestrator.d.ts.map +1 -0
  69. package/dist/core/format/module-emitter/orchestrator.js +254 -0
  70. package/dist/core/format/module-emitter/orchestrator.js.map +1 -0
  71. package/dist/core/format/module-emitter/separation.d.ts.map +1 -0
  72. package/dist/core/format/module-emitter/separation.js.map +1 -0
  73. package/dist/core/{module-emitter → format/module-emitter}/static-container.d.ts +8 -3
  74. package/dist/core/format/module-emitter/static-container.d.ts.map +1 -0
  75. package/dist/core/format/module-emitter/static-container.js +202 -0
  76. package/dist/core/format/module-emitter/static-container.js.map +1 -0
  77. package/dist/core/format/module-emitter.d.ts.map +1 -0
  78. package/dist/core/format/module-emitter.js.map +1 -0
  79. package/dist/core/{options.d.ts → format/options.d.ts} +1 -1
  80. package/dist/core/format/options.d.ts.map +1 -0
  81. package/dist/core/format/options.js.map +1 -0
  82. package/dist/core/index.d.ts +2 -7
  83. package/dist/core/index.d.ts.map +1 -1
  84. package/dist/core/index.js +2 -7
  85. package/dist/core/index.js.map +1 -1
  86. package/dist/core/module-emitter.test.js.map +1 -1
  87. package/dist/core/semantic/boolean-context.d.ts +44 -0
  88. package/dist/core/semantic/boolean-context.d.ts.map +1 -0
  89. package/dist/core/semantic/boolean-context.js +655 -0
  90. package/dist/core/semantic/boolean-context.js.map +1 -0
  91. package/dist/core/semantic/boolean-context.test.d.ts.map +1 -0
  92. package/dist/core/{boolean-context.test.js → semantic/boolean-context.test.js} +56 -103
  93. package/dist/core/semantic/boolean-context.test.js.map +1 -0
  94. package/dist/core/{imports.d.ts → semantic/imports.d.ts} +1 -5
  95. package/dist/core/semantic/imports.d.ts.map +1 -0
  96. package/dist/core/{imports.js → semantic/imports.js} +9 -78
  97. package/dist/core/semantic/imports.js.map +1 -0
  98. package/dist/core/semantic/imports.test.d.ts.map +1 -0
  99. package/dist/core/{imports.test.js → semantic/imports.test.js} +1 -1
  100. package/dist/core/semantic/imports.test.js.map +1 -0
  101. package/dist/core/semantic/index.d.ts +15 -0
  102. package/dist/core/semantic/index.d.ts.map +1 -0
  103. package/dist/core/semantic/index.js +15 -0
  104. package/dist/core/semantic/index.js.map +1 -0
  105. package/dist/core/{local-types.d.ts → semantic/local-types.d.ts} +1 -1
  106. package/dist/core/semantic/local-types.d.ts.map +1 -0
  107. package/dist/core/semantic/local-types.js.map +1 -0
  108. package/dist/core/{module-map.d.ts → semantic/module-map.d.ts} +1 -1
  109. package/dist/core/semantic/module-map.d.ts.map +1 -0
  110. package/dist/core/semantic/module-map.js.map +1 -0
  111. package/dist/core/semantic/module-map.test.d.ts.map +1 -0
  112. package/dist/core/semantic/module-map.test.js.map +1 -0
  113. package/dist/core/semantic/naming-collisions.d.ts.map +1 -0
  114. package/dist/core/{naming-collisions.js → semantic/naming-collisions.js} +3 -2
  115. package/dist/core/semantic/naming-collisions.js.map +1 -0
  116. package/dist/core/{type-alias-index.d.ts → semantic/type-alias-index.d.ts} +1 -1
  117. package/dist/core/semantic/type-alias-index.d.ts.map +1 -0
  118. package/dist/core/semantic/type-alias-index.js.map +1 -0
  119. package/dist/core/semantic/type-compatibility.d.ts.map +1 -0
  120. package/dist/core/semantic/type-compatibility.js.map +1 -0
  121. package/dist/core/{type-member-index.d.ts → semantic/type-member-index.d.ts} +1 -1
  122. package/dist/core/semantic/type-member-index.d.ts.map +1 -0
  123. package/dist/core/semantic/type-member-index.js.map +1 -0
  124. package/dist/core/semantic/type-params.d.ts.map +1 -0
  125. package/dist/core/semantic/type-params.js.map +1 -0
  126. package/dist/core/{type-resolution.d.ts → semantic/type-resolution.d.ts} +3 -6
  127. package/dist/core/semantic/type-resolution.d.ts.map +1 -0
  128. package/dist/core/{type-resolution.js → semantic/type-resolution.js} +78 -47
  129. package/dist/core/semantic/type-resolution.js.map +1 -0
  130. package/dist/core/semantic/type-resolution.test.d.ts.map +1 -0
  131. package/dist/core/{type-resolution.test.js → semantic/type-resolution.test.js} +155 -20
  132. package/dist/core/semantic/type-resolution.test.js.map +1 -0
  133. package/dist/core/semantic/unsafe.d.ts.map +1 -0
  134. package/dist/core/{unsafe.js → semantic/unsafe.js} +8 -6
  135. package/dist/core/semantic/unsafe.js.map +1 -0
  136. package/dist/emitter-types/core.d.ts +50 -12
  137. package/dist/emitter-types/core.d.ts.map +1 -1
  138. package/dist/emitter-types/index.d.ts +1 -1
  139. package/dist/emitter-types/index.d.ts.map +1 -1
  140. package/dist/emitter-types/index.js.map +1 -1
  141. package/dist/emitter.d.ts +1 -1
  142. package/dist/emitter.d.ts.map +1 -1
  143. package/dist/emitter.js +216 -16
  144. package/dist/emitter.js.map +1 -1
  145. package/dist/expression-emitter.d.ts +10 -5
  146. package/dist/expression-emitter.d.ts.map +1 -1
  147. package/dist/expression-emitter.js +135 -121
  148. package/dist/expression-emitter.js.map +1 -1
  149. package/dist/expressions/access.d.ts +4 -3
  150. package/dist/expressions/access.d.ts.map +1 -1
  151. package/dist/expressions/access.js +299 -109
  152. package/dist/expressions/access.js.map +1 -1
  153. package/dist/expressions/calls/call-analysis.d.ts +86 -0
  154. package/dist/expressions/calls/call-analysis.d.ts.map +1 -0
  155. package/dist/expressions/calls/call-analysis.js +284 -0
  156. package/dist/expressions/calls/call-analysis.js.map +1 -0
  157. package/dist/expressions/calls/call-emitter.d.ts +13 -0
  158. package/dist/expressions/calls/call-emitter.d.ts.map +1 -0
  159. package/dist/expressions/calls/call-emitter.js +876 -0
  160. package/dist/expressions/calls/call-emitter.js.map +1 -0
  161. package/dist/expressions/calls/new-emitter.d.ts +13 -0
  162. package/dist/expressions/calls/new-emitter.d.ts.map +1 -0
  163. package/dist/expressions/calls/new-emitter.js +641 -0
  164. package/dist/expressions/calls/new-emitter.js.map +1 -0
  165. package/dist/expressions/calls.d.ts +2 -14
  166. package/dist/expressions/calls.d.ts.map +1 -1
  167. package/dist/expressions/calls.js +2 -744
  168. package/dist/expressions/calls.js.map +1 -1
  169. package/dist/expressions/collections.d.ts +6 -16
  170. package/dist/expressions/collections.d.ts.map +1 -1
  171. package/dist/expressions/collections.js +303 -218
  172. package/dist/expressions/collections.js.map +1 -1
  173. package/dist/expressions/functions.d.ts +6 -5
  174. package/dist/expressions/functions.d.ts.map +1 -1
  175. package/dist/expressions/functions.js +57 -62
  176. package/dist/expressions/functions.js.map +1 -1
  177. package/dist/expressions/identifiers.d.ts +11 -6
  178. package/dist/expressions/identifiers.d.ts.map +1 -1
  179. package/dist/expressions/identifiers.js +81 -25
  180. package/dist/expressions/identifiers.js.map +1 -1
  181. package/dist/expressions/index.d.ts +1 -1
  182. package/dist/expressions/index.d.ts.map +1 -1
  183. package/dist/expressions/index.js +1 -1
  184. package/dist/expressions/index.js.map +1 -1
  185. package/dist/expressions/index.test.js +522 -3
  186. package/dist/expressions/index.test.js.map +1 -1
  187. package/dist/expressions/literals.d.ts +4 -3
  188. package/dist/expressions/literals.d.ts.map +1 -1
  189. package/dist/expressions/literals.js +25 -17
  190. package/dist/expressions/literals.js.map +1 -1
  191. package/dist/expressions/literals.test.js +18 -18
  192. package/dist/expressions/literals.test.js.map +1 -1
  193. package/dist/expressions/operators/assignment-emitter.d.ts +16 -0
  194. package/dist/expressions/operators/assignment-emitter.d.ts.map +1 -0
  195. package/dist/expressions/operators/assignment-emitter.js +118 -0
  196. package/dist/expressions/operators/assignment-emitter.js.map +1 -0
  197. package/dist/expressions/operators/binary-emitter.d.ts +33 -0
  198. package/dist/expressions/operators/binary-emitter.d.ts.map +1 -0
  199. package/dist/expressions/operators/binary-emitter.js +398 -0
  200. package/dist/expressions/operators/binary-emitter.js.map +1 -0
  201. package/dist/expressions/operators/conditional-emitter.d.ts +17 -0
  202. package/dist/expressions/operators/conditional-emitter.d.ts.map +1 -0
  203. package/dist/expressions/operators/conditional-emitter.js +306 -0
  204. package/dist/expressions/operators/conditional-emitter.js.map +1 -0
  205. package/dist/expressions/operators/helpers.d.ts +37 -0
  206. package/dist/expressions/operators/helpers.d.ts.map +1 -0
  207. package/dist/expressions/operators/helpers.js +136 -0
  208. package/dist/expressions/operators/helpers.js.map +1 -0
  209. package/dist/expressions/operators/logical-emitter.d.ts +23 -0
  210. package/dist/expressions/operators/logical-emitter.d.ts.map +1 -0
  211. package/dist/expressions/operators/logical-emitter.js +73 -0
  212. package/dist/expressions/operators/logical-emitter.js.map +1 -0
  213. package/dist/expressions/operators/unary-emitter.d.ts +30 -0
  214. package/dist/expressions/operators/unary-emitter.d.ts.map +1 -0
  215. package/dist/expressions/operators/unary-emitter.js +244 -0
  216. package/dist/expressions/operators/unary-emitter.js.map +1 -0
  217. package/dist/expressions/operators.d.ts +5 -81
  218. package/dist/expressions/operators.d.ts.map +1 -1
  219. package/dist/expressions/operators.js +5 -868
  220. package/dist/expressions/operators.js.map +1 -1
  221. package/dist/expressions/other.d.ts +15 -11
  222. package/dist/expressions/other.d.ts.map +1 -1
  223. package/dist/expressions/other.js +55 -38
  224. package/dist/expressions/other.js.map +1 -1
  225. package/dist/expressions/parentheses.d.ts.map +1 -1
  226. package/dist/expressions/parentheses.js +2 -1
  227. package/dist/expressions/parentheses.js.map +1 -1
  228. package/dist/expressions/precedence.test.js +6 -2
  229. package/dist/expressions/precedence.test.js.map +1 -1
  230. package/dist/generator-exchange.d.ts +10 -3
  231. package/dist/generator-exchange.d.ts.map +1 -1
  232. package/dist/generator-exchange.js +57 -54
  233. package/dist/generator-exchange.js.map +1 -1
  234. package/dist/generator-wrapper.d.ts +17 -65
  235. package/dist/generator-wrapper.d.ts.map +1 -1
  236. package/dist/generator-wrapper.js +396 -220
  237. package/dist/generator-wrapper.js.map +1 -1
  238. package/dist/generator-wrapper.test.js +22 -14
  239. package/dist/generator-wrapper.test.js.map +1 -1
  240. package/dist/golden-shards.d.ts.map +1 -1
  241. package/dist/golden-shards.js.map +1 -1
  242. package/dist/golden-tests/runner.d.ts.map +1 -1
  243. package/dist/golden-tests/runner.js +3 -1
  244. package/dist/golden-tests/runner.js.map +1 -1
  245. package/dist/integration.test.js +166 -1
  246. package/dist/integration.test.js.map +1 -1
  247. package/dist/json-aot-generic.test.js +8 -2
  248. package/dist/json-aot-generic.test.js.map +1 -1
  249. package/dist/patterns.d.ts +18 -88
  250. package/dist/patterns.d.ts.map +1 -1
  251. package/dist/patterns.js +540 -304
  252. package/dist/patterns.js.map +1 -1
  253. package/dist/patterns.test.js +5 -4
  254. package/dist/patterns.test.js.map +1 -1
  255. package/dist/specialization/generation.d.ts +7 -3
  256. package/dist/specialization/generation.d.ts.map +1 -1
  257. package/dist/specialization/generation.js +32 -16
  258. package/dist/specialization/generation.js.map +1 -1
  259. package/dist/specialization/type-aliases.test.js +3 -2
  260. package/dist/specialization/type-aliases.test.js.map +1 -1
  261. package/dist/statement-emitter.d.ts +15 -4
  262. package/dist/statement-emitter.d.ts.map +1 -1
  263. package/dist/statement-emitter.js +54 -47
  264. package/dist/statement-emitter.js.map +1 -1
  265. package/dist/statements/blocks.d.ts +24 -16
  266. package/dist/statements/blocks.d.ts.map +1 -1
  267. package/dist/statements/blocks.js +193 -66
  268. package/dist/statements/blocks.js.map +1 -1
  269. package/dist/statements/classes/index.d.ts +1 -1
  270. package/dist/statements/classes/index.d.ts.map +1 -1
  271. package/dist/statements/classes/index.js +1 -1
  272. package/dist/statements/classes/index.js.map +1 -1
  273. package/dist/statements/classes/inline-types.d.ts +4 -3
  274. package/dist/statements/classes/inline-types.d.ts.map +1 -1
  275. package/dist/statements/classes/inline-types.js +21 -21
  276. package/dist/statements/classes/inline-types.js.map +1 -1
  277. package/dist/statements/classes/members/constructors.d.ts +4 -3
  278. package/dist/statements/classes/members/constructors.d.ts.map +1 -1
  279. package/dist/statements/classes/members/constructors.js +57 -58
  280. package/dist/statements/classes/members/constructors.js.map +1 -1
  281. package/dist/statements/classes/members/methods.d.ts +4 -3
  282. package/dist/statements/classes/members/methods.d.ts.map +1 -1
  283. package/dist/statements/classes/members/methods.js +98 -98
  284. package/dist/statements/classes/members/methods.js.map +1 -1
  285. package/dist/statements/classes/members/orchestrator.d.ts +4 -3
  286. package/dist/statements/classes/members/orchestrator.d.ts.map +1 -1
  287. package/dist/statements/classes/members/orchestrator.js +2 -2
  288. package/dist/statements/classes/members/orchestrator.js.map +1 -1
  289. package/dist/statements/classes/members/properties.d.ts +4 -3
  290. package/dist/statements/classes/members/properties.d.ts.map +1 -1
  291. package/dist/statements/classes/members/properties.js +109 -89
  292. package/dist/statements/classes/members/properties.js.map +1 -1
  293. package/dist/statements/classes/members/shadowing.test.js +7 -2
  294. package/dist/statements/classes/members/shadowing.test.js.map +1 -1
  295. package/dist/statements/classes/members/static-readonly-properties.test.js +10 -2
  296. package/dist/statements/classes/members/static-readonly-properties.test.js.map +1 -1
  297. package/dist/statements/classes/parameters.d.ts +8 -10
  298. package/dist/statements/classes/parameters.d.ts.map +1 -1
  299. package/dist/statements/classes/parameters.js +30 -26
  300. package/dist/statements/classes/parameters.js.map +1 -1
  301. package/dist/statements/classes/properties.d.ts +4 -3
  302. package/dist/statements/classes/properties.d.ts.map +1 -1
  303. package/dist/statements/classes/properties.js +76 -50
  304. package/dist/statements/classes/properties.js.map +1 -1
  305. package/dist/statements/classes.d.ts +1 -1
  306. package/dist/statements/classes.d.ts.map +1 -1
  307. package/dist/statements/classes.js +1 -1
  308. package/dist/statements/classes.js.map +1 -1
  309. package/dist/statements/control/conditionals/guard-analysis.d.ts +169 -0
  310. package/dist/statements/control/conditionals/guard-analysis.d.ts.map +1 -0
  311. package/dist/statements/control/conditionals/guard-analysis.js +591 -0
  312. package/dist/statements/control/conditionals/guard-analysis.js.map +1 -0
  313. package/dist/statements/control/conditionals/if-emitter.d.ts +14 -0
  314. package/dist/statements/control/conditionals/if-emitter.d.ts.map +1 -0
  315. package/dist/statements/control/conditionals/if-emitter.js +725 -0
  316. package/dist/statements/control/conditionals/if-emitter.js.map +1 -0
  317. package/dist/statements/control/conditionals/switch-emitter.d.ts +13 -0
  318. package/dist/statements/control/conditionals/switch-emitter.d.ts.map +1 -0
  319. package/dist/statements/control/conditionals/switch-emitter.js +60 -0
  320. package/dist/statements/control/conditionals/switch-emitter.js.map +1 -0
  321. package/dist/statements/control/conditionals.d.ts +3 -15
  322. package/dist/statements/control/conditionals.d.ts.map +1 -1
  323. package/dist/statements/control/conditionals.js +3 -1065
  324. package/dist/statements/control/conditionals.js.map +1 -1
  325. package/dist/statements/control/exceptions.d.ts +8 -6
  326. package/dist/statements/control/exceptions.d.ts.map +1 -1
  327. package/dist/statements/control/exceptions.js +35 -23
  328. package/dist/statements/control/exceptions.js.map +1 -1
  329. package/dist/statements/control/index.d.ts +3 -3
  330. package/dist/statements/control/index.d.ts.map +1 -1
  331. package/dist/statements/control/index.js +3 -3
  332. package/dist/statements/control/index.js.map +1 -1
  333. package/dist/statements/control/loops.d.ts +14 -12
  334. package/dist/statements/control/loops.d.ts.map +1 -1
  335. package/dist/statements/control/loops.js +147 -82
  336. package/dist/statements/control/loops.js.map +1 -1
  337. package/dist/statements/control.d.ts +1 -1
  338. package/dist/statements/control.d.ts.map +1 -1
  339. package/dist/statements/control.js +1 -1
  340. package/dist/statements/control.js.map +1 -1
  341. package/dist/statements/declarations/classes.d.ts +7 -3
  342. package/dist/statements/declarations/classes.d.ts.map +1 -1
  343. package/dist/statements/declarations/classes.js +72 -86
  344. package/dist/statements/declarations/classes.js.map +1 -1
  345. package/dist/statements/declarations/enums.d.ts +4 -3
  346. package/dist/statements/declarations/enums.d.ts.map +1 -1
  347. package/dist/statements/declarations/enums.js +18 -16
  348. package/dist/statements/declarations/enums.js.map +1 -1
  349. package/dist/statements/declarations/functions.d.ts +18 -2
  350. package/dist/statements/declarations/functions.d.ts.map +1 -1
  351. package/dist/statements/declarations/functions.js +625 -159
  352. package/dist/statements/declarations/functions.js.map +1 -1
  353. package/dist/statements/declarations/index.d.ts +2 -2
  354. package/dist/statements/declarations/index.d.ts.map +1 -1
  355. package/dist/statements/declarations/index.js +2 -2
  356. package/dist/statements/declarations/index.js.map +1 -1
  357. package/dist/statements/declarations/interfaces.d.ts +7 -3
  358. package/dist/statements/declarations/interfaces.d.ts.map +1 -1
  359. package/dist/statements/declarations/interfaces.js +121 -107
  360. package/dist/statements/declarations/interfaces.js.map +1 -1
  361. package/dist/statements/declarations/type-aliases.d.ts +7 -3
  362. package/dist/statements/declarations/type-aliases.d.ts.map +1 -1
  363. package/dist/statements/declarations/type-aliases.js +95 -79
  364. package/dist/statements/declarations/type-aliases.js.map +1 -1
  365. package/dist/statements/declarations/variables.d.ts +12 -2
  366. package/dist/statements/declarations/variables.d.ts.map +1 -1
  367. package/dist/statements/declarations/variables.js +535 -424
  368. package/dist/statements/declarations/variables.js.map +1 -1
  369. package/dist/statements/declarations.d.ts +1 -1
  370. package/dist/statements/declarations.d.ts.map +1 -1
  371. package/dist/statements/declarations.js +1 -1
  372. package/dist/statements/declarations.js.map +1 -1
  373. package/dist/statements/index.d.ts +3 -3
  374. package/dist/statements/index.d.ts.map +1 -1
  375. package/dist/statements/index.js +5 -5
  376. package/dist/statements/index.js.map +1 -1
  377. package/dist/type-emitter.d.ts +1 -1
  378. package/dist/type-emitter.d.ts.map +1 -1
  379. package/dist/type-emitter.js +1 -1
  380. package/dist/type-emitter.js.map +1 -1
  381. package/dist/types/arrays.d.ts +3 -2
  382. package/dist/types/arrays.d.ts.map +1 -1
  383. package/dist/types/arrays.js +7 -5
  384. package/dist/types/arrays.js.map +1 -1
  385. package/dist/types/dictionaries.d.ts +6 -3
  386. package/dist/types/dictionaries.d.ts.map +1 -1
  387. package/dist/types/dictionaries.js +22 -10
  388. package/dist/types/dictionaries.js.map +1 -1
  389. package/dist/types/emitter.d.ts +8 -2
  390. package/dist/types/emitter.d.ts.map +1 -1
  391. package/dist/types/emitter.js +23 -6
  392. package/dist/types/emitter.js.map +1 -1
  393. package/dist/types/functions.d.ts +3 -2
  394. package/dist/types/functions.d.ts.map +1 -1
  395. package/dist/types/functions.js +36 -13
  396. package/dist/types/functions.js.map +1 -1
  397. package/dist/types/index.d.ts +2 -2
  398. package/dist/types/index.d.ts.map +1 -1
  399. package/dist/types/index.js +2 -2
  400. package/dist/types/index.js.map +1 -1
  401. package/dist/types/index.test.js +137 -0
  402. package/dist/types/index.test.js.map +1 -1
  403. package/dist/types/intersections.d.ts +3 -2
  404. package/dist/types/intersections.d.ts.map +1 -1
  405. package/dist/types/intersections.js +2 -2
  406. package/dist/types/intersections.js.map +1 -1
  407. package/dist/types/literals.d.ts +9 -2
  408. package/dist/types/literals.d.ts.map +1 -1
  409. package/dist/types/literals.js +11 -5
  410. package/dist/types/literals.js.map +1 -1
  411. package/dist/types/objects.d.ts +3 -2
  412. package/dist/types/objects.d.ts.map +1 -1
  413. package/dist/types/objects.js +1 -1
  414. package/dist/types/objects.js.map +1 -1
  415. package/dist/types/parameters.d.ts +6 -5
  416. package/dist/types/parameters.d.ts.map +1 -1
  417. package/dist/types/parameters.js +92 -31
  418. package/dist/types/parameters.js.map +1 -1
  419. package/dist/types/parameters.test.js +9 -4
  420. package/dist/types/parameters.test.js.map +1 -1
  421. package/dist/types/primitives.d.ts +5 -4
  422. package/dist/types/primitives.d.ts.map +1 -1
  423. package/dist/types/primitives.js +14 -13
  424. package/dist/types/primitives.js.map +1 -1
  425. package/dist/types/references.d.ts +3 -2
  426. package/dist/types/references.d.ts.map +1 -1
  427. package/dist/types/references.js +187 -104
  428. package/dist/types/references.js.map +1 -1
  429. package/dist/types/references.test.js +138 -0
  430. package/dist/types/references.test.js.map +1 -1
  431. package/dist/types/tuples.d.ts +3 -2
  432. package/dist/types/tuples.d.ts.map +1 -1
  433. package/dist/types/tuples.js +25 -11
  434. package/dist/types/tuples.js.map +1 -1
  435. package/dist/types/unions.d.ts +3 -2
  436. package/dist/types/unions.d.ts.map +1 -1
  437. package/dist/types/unions.js +36 -21
  438. package/dist/types/unions.js.map +1 -1
  439. package/dist/types.d.ts +1 -1
  440. package/dist/types.d.ts.map +1 -1
  441. package/dist/types.js.map +1 -1
  442. package/package.json +2 -2
  443. package/dist/core/attributes.d.ts.map +0 -1
  444. package/dist/core/attributes.js +0 -141
  445. package/dist/core/attributes.js.map +0 -1
  446. package/dist/core/attributes.test.d.ts.map +0 -1
  447. package/dist/core/attributes.test.js.map +0 -1
  448. package/dist/core/boolean-context.d.ts +0 -42
  449. package/dist/core/boolean-context.d.ts.map +0 -1
  450. package/dist/core/boolean-context.js +0 -402
  451. package/dist/core/boolean-context.js.map +0 -1
  452. package/dist/core/boolean-context.test.d.ts.map +0 -1
  453. package/dist/core/boolean-context.test.js.map +0 -1
  454. package/dist/core/exports.d.ts.map +0 -1
  455. package/dist/core/exports.js +0 -28
  456. package/dist/core/exports.js.map +0 -1
  457. package/dist/core/imports.d.ts.map +0 -1
  458. package/dist/core/imports.js.map +0 -1
  459. package/dist/core/imports.test.d.ts.map +0 -1
  460. package/dist/core/imports.test.js.map +0 -1
  461. package/dist/core/local-names.d.ts.map +0 -1
  462. package/dist/core/local-names.js.map +0 -1
  463. package/dist/core/local-types.d.ts.map +0 -1
  464. package/dist/core/local-types.js.map +0 -1
  465. package/dist/core/module-emitter/assembly.d.ts +0 -24
  466. package/dist/core/module-emitter/assembly.d.ts.map +0 -1
  467. package/dist/core/module-emitter/assembly.js +0 -69
  468. package/dist/core/module-emitter/assembly.js.map +0 -1
  469. package/dist/core/module-emitter/header.d.ts.map +0 -1
  470. package/dist/core/module-emitter/header.js.map +0 -1
  471. package/dist/core/module-emitter/index.d.ts.map +0 -1
  472. package/dist/core/module-emitter/index.js.map +0 -1
  473. package/dist/core/module-emitter/namespace.d.ts +0 -14
  474. package/dist/core/module-emitter/namespace.d.ts.map +0 -1
  475. package/dist/core/module-emitter/namespace.js +0 -26
  476. package/dist/core/module-emitter/namespace.js.map +0 -1
  477. package/dist/core/module-emitter/orchestrator.d.ts.map +0 -1
  478. package/dist/core/module-emitter/orchestrator.js +0 -82
  479. package/dist/core/module-emitter/orchestrator.js.map +0 -1
  480. package/dist/core/module-emitter/separation.d.ts.map +0 -1
  481. package/dist/core/module-emitter/separation.js.map +0 -1
  482. package/dist/core/module-emitter/static-container.d.ts.map +0 -1
  483. package/dist/core/module-emitter/static-container.js +0 -139
  484. package/dist/core/module-emitter/static-container.js.map +0 -1
  485. package/dist/core/module-emitter.d.ts.map +0 -1
  486. package/dist/core/module-emitter.js.map +0 -1
  487. package/dist/core/module-map.d.ts.map +0 -1
  488. package/dist/core/module-map.js.map +0 -1
  489. package/dist/core/module-map.test.d.ts.map +0 -1
  490. package/dist/core/module-map.test.js.map +0 -1
  491. package/dist/core/naming-collisions.d.ts.map +0 -1
  492. package/dist/core/naming-collisions.js.map +0 -1
  493. package/dist/core/options.d.ts.map +0 -1
  494. package/dist/core/options.js.map +0 -1
  495. package/dist/core/type-alias-index.d.ts.map +0 -1
  496. package/dist/core/type-alias-index.js.map +0 -1
  497. package/dist/core/type-compatibility.d.ts.map +0 -1
  498. package/dist/core/type-compatibility.js.map +0 -1
  499. package/dist/core/type-member-index.d.ts.map +0 -1
  500. package/dist/core/type-member-index.js.map +0 -1
  501. package/dist/core/type-params.d.ts.map +0 -1
  502. package/dist/core/type-params.js.map +0 -1
  503. package/dist/core/type-resolution.d.ts.map +0 -1
  504. package/dist/core/type-resolution.js.map +0 -1
  505. package/dist/core/type-resolution.test.d.ts.map +0 -1
  506. package/dist/core/type-resolution.test.js.map +0 -1
  507. package/dist/core/unsafe.d.ts.map +0 -1
  508. package/dist/core/unsafe.js.map +0 -1
  509. /package/dist/core/{attributes.test.d.ts → format/attributes.test.d.ts} +0 -0
  510. /package/dist/core/{module-emitter → format/module-emitter}/index.d.ts +0 -0
  511. /package/dist/core/{module-emitter → format/module-emitter}/index.js +0 -0
  512. /package/dist/core/{module-emitter → format/module-emitter}/separation.d.ts +0 -0
  513. /package/dist/core/{module-emitter → format/module-emitter}/separation.js +0 -0
  514. /package/dist/core/{module-emitter.d.ts → format/module-emitter.d.ts} +0 -0
  515. /package/dist/core/{module-emitter.js → format/module-emitter.js} +0 -0
  516. /package/dist/core/{options.js → format/options.js} +0 -0
  517. /package/dist/core/{boolean-context.test.d.ts → semantic/boolean-context.test.d.ts} +0 -0
  518. /package/dist/core/{imports.test.d.ts → semantic/imports.test.d.ts} +0 -0
  519. /package/dist/core/{local-types.js → semantic/local-types.js} +0 -0
  520. /package/dist/core/{module-map.js → semantic/module-map.js} +0 -0
  521. /package/dist/core/{module-map.test.d.ts → semantic/module-map.test.d.ts} +0 -0
  522. /package/dist/core/{module-map.test.js → semantic/module-map.test.js} +0 -0
  523. /package/dist/core/{naming-collisions.d.ts → semantic/naming-collisions.d.ts} +0 -0
  524. /package/dist/core/{type-alias-index.js → semantic/type-alias-index.js} +0 -0
  525. /package/dist/core/{type-compatibility.d.ts → semantic/type-compatibility.d.ts} +0 -0
  526. /package/dist/core/{type-compatibility.js → semantic/type-compatibility.js} +0 -0
  527. /package/dist/core/{type-member-index.js → semantic/type-member-index.js} +0 -0
  528. /package/dist/core/{type-params.d.ts → semantic/type-params.d.ts} +0 -0
  529. /package/dist/core/{type-params.js → semantic/type-params.js} +0 -0
  530. /package/dist/core/{type-resolution.test.d.ts → semantic/type-resolution.test.d.ts} +0 -0
  531. /package/dist/core/{unsafe.d.ts → semantic/unsafe.d.ts} +0 -0
@@ -1,748 +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("?") ? rawTypeStr.slice(0, -1) : rawTypeStr;
228
- registry.rootTypes.add(ensureGlobalPrefix(typeStr));
229
- registry.needsJsonAot = true;
230
- };
231
- /**
232
- * Check if a call expression needs an explicit cast because the inferred type
233
- * differs from the C# return type. This handles cases like Math.floor() which
234
- * returns double in C# but is cast to int in TypeScript via `as int`.
235
- */
236
- const needsIntCast = (expr, calleeName) => {
237
- // Check if the inferred type is int (a reference type from @tsonic/core)
238
- const inferredType = expr.inferredType;
239
- if (!inferredType ||
240
- inferredType.kind !== "referenceType" ||
241
- inferredType.name !== "int") {
242
- return false;
243
- }
244
- // Check if this is a Math method that returns double
245
- const mathMethodsReturningDouble = [
246
- "Math.floor",
247
- "Math.ceil",
248
- "Math.round",
249
- "Math.abs",
250
- "Math.pow",
251
- "Math.sqrt",
252
- "Math.min",
253
- "Math.max",
254
- ];
255
- return mathMethodsReturningDouble.some((m) => calleeName === m || calleeName.endsWith(`.${m.split(".").pop()}`));
256
- };
257
- /**
258
- * Emit a JsonSerializer call with NativeAOT-compatible options.
259
- * Rewrites:
260
- * JsonSerializer.Serialize(value) → JsonSerializer.Serialize(value, TsonicJson.Options)
261
- * JsonSerializer.Deserialize<T>(json) → JsonSerializer.Deserialize<T>(json, TsonicJson.Options)
262
- */
263
- const emitJsonSerializerCall = (expr, context, method) => {
264
- let currentContext = context;
265
- // Register the type with the JSON AOT registry
266
- if (method === "Serialize") {
267
- // For Serialize, get type from first argument's inferredType
268
- const firstArg = expr.arguments[0];
269
- if (firstArg && firstArg.kind !== "spread") {
270
- registerJsonAotType(firstArg.inferredType, context);
271
- }
272
- }
273
- else {
274
- // For Deserialize, get type from type arguments
275
- const typeArg = expr.typeArguments?.[0];
276
- if (typeArg) {
277
- registerJsonAotType(typeArg, context);
278
- }
279
- }
280
- // Emit type arguments for Deserialize<T>
281
- let typeArgsStr = "";
282
- if (expr.typeArguments && expr.typeArguments.length > 0) {
283
- const [typeArgs, typeContext] = emitTypeArguments(expr.typeArguments, currentContext);
284
- typeArgsStr = typeArgs;
285
- currentContext = typeContext;
286
- }
287
- // Emit arguments
288
- const args = [];
289
- for (const arg of expr.arguments) {
290
- if (arg.kind === "spread") {
291
- const [spreadFrag, ctx] = emitExpression(arg.expression, currentContext);
292
- args.push(spreadFrag.text);
293
- currentContext = ctx;
294
- }
295
- else {
296
- const [argFrag, ctx] = emitExpression(arg, currentContext);
297
- args.push(argFrag.text);
298
- currentContext = ctx;
299
- }
300
- }
301
- // Add TsonicJson.Options as the last argument for NativeAOT compatibility
302
- args.push("TsonicJson.Options");
303
- const text = `global::System.Text.Json.JsonSerializer.${method}${typeArgsStr}(${args.join(", ")})`;
304
- return [{ text }, currentContext];
305
- };
306
- /**
307
- * Emit a function call expression
308
- */
309
- export const emitCall = (expr, context) => {
310
- // Check for JsonSerializer calls (NativeAOT support)
311
- const jsonCall = isJsonSerializerCall(expr.callee);
312
- if (jsonCall) {
313
- return emitJsonSerializerCall(expr, context, jsonCall.method);
314
- }
315
- // Check for global JSON.stringify/parse calls
316
- // These compile to JsonSerializer.Serialize/Deserialize
317
- const globalJsonCall = isGlobalJsonCall(expr.callee);
318
- if (globalJsonCall) {
319
- return emitJsonSerializerCall(expr, context, globalJsonCall.method);
320
- }
321
- // EF Core query precompilation has a known limitation: `query.ToList().ToArray()`
322
- // fails to precompile (captured locals may be treated as "unknown identifiers").
323
- // Since `ToList().ToArray()` is equivalent to `ToArray()` for IEnumerable<T>,
324
- // canonicalize this pattern to `query.ToArray()` so NativeAOT precompilation works.
325
- if (expr.callee.kind === "memberAccess" &&
326
- expr.callee.property === "ToArray" &&
327
- expr.arguments.length === 0 &&
328
- expr.callee.object.kind === "call") {
329
- const innerCall = expr.callee.object;
330
- if (innerCall.callee.kind === "memberAccess" &&
331
- innerCall.callee.memberBinding?.isExtensionMethod &&
332
- isInstanceMemberAccess(innerCall.callee, context) &&
333
- innerCall.callee.memberBinding.type.startsWith("System.Linq.Enumerable") &&
334
- innerCall.callee.memberBinding.member === "ToList" &&
335
- innerCall.arguments.length === 0) {
336
- let currentContext = context;
337
- // Ensure extension methods are in scope.
338
- currentContext.usings.add("System.Linq");
339
- const receiverExpr = innerCall.callee.object;
340
- const [receiverFrag, receiverCtx] = emitExpression(receiverExpr, currentContext);
341
- currentContext = receiverCtx;
342
- const receiverText = formatPostfixExpressionText(receiverExpr, receiverFrag.text);
343
- const text = `${receiverText}.ToArray()`;
344
- return [{ text }, currentContext];
345
- }
346
- }
347
- // Extension method lowering: emit explicit static invocation with receiver as first arg.
348
- // This avoids relying on C# `using` directives for extension method discovery.
349
- if (expr.callee.kind === "memberAccess" &&
350
- expr.callee.memberBinding?.isExtensionMethod &&
351
- isInstanceMemberAccess(expr.callee, context)) {
352
- let currentContext = context;
353
- const binding = expr.callee.memberBinding;
354
- const receiverExpr = expr.callee.object;
355
- const [receiverFrag, receiverContext] = emitExpression(receiverExpr, currentContext);
356
- currentContext = receiverContext;
357
- // Some ecosystems (notably EF Core query precompilation) require fluent syntax
358
- // so the tooling can locate queries in syntax trees. For those namespaces,
359
- // emit `receiver.Method(...)` and add a `using` directive for the namespace.
360
- if (shouldEmitFluentExtensionCall(binding.type, binding.member)) {
361
- const ns = getTypeNamespace(binding.type);
362
- if (ns) {
363
- currentContext.usings.add(ns);
364
- }
365
- // Handle generic type arguments
366
- let typeArgsStr = "";
367
- if (expr.typeArguments && expr.typeArguments.length > 0) {
368
- const [typeArgs, typeContext] = emitTypeArguments(expr.typeArguments, currentContext);
369
- typeArgsStr = typeArgs;
370
- currentContext = typeContext;
371
- }
372
- // Get parameter types from IR (extracted from resolved signature in frontend)
373
- const parameterTypes = expr.parameterTypes ?? [];
374
- const args = [];
375
- for (let i = 0; i < expr.arguments.length; i++) {
376
- const arg = expr.arguments[i];
377
- if (!arg)
378
- continue;
379
- const expectedType = parameterTypes[i];
380
- if (arg.kind === "spread") {
381
- const [spreadFrag, ctx] = emitExpression(arg.expression, currentContext);
382
- args.push(`params ${spreadFrag.text}`);
383
- currentContext = ctx;
384
- }
385
- else {
386
- const castModifier = getPassingModifierFromCast(arg);
387
- if (castModifier && isLValue(arg)) {
388
- const [argFrag, ctx] = emitExpression(arg, currentContext);
389
- args.push(`${castModifier} ${argFrag.text}`);
390
- currentContext = ctx;
391
- }
392
- else {
393
- const [argFrag, ctx] = emitExpression(arg, currentContext, expectedType);
394
- const passingMode = expr.argumentPassing?.[i];
395
- const prefix = passingMode && passingMode !== "value" && isLValue(arg)
396
- ? `${passingMode} `
397
- : "";
398
- args.push(`${prefix}${argFrag.text}`);
399
- currentContext = ctx;
400
- }
401
- }
402
- }
403
- const receiverText = formatPostfixExpressionText(receiverExpr, receiverFrag.text);
404
- const op = expr.isOptional ? "?." : ".";
405
- const baseCallText = `${receiverText}${op}${binding.member}${typeArgsStr}(${args.join(", ")})`;
406
- const text = needsIntCast(expr, binding.member)
407
- ? `(int)${baseCallText}`
408
- : baseCallText;
409
- return [{ text }, currentContext];
410
- }
411
- let finalCalleeName = `global::${binding.type}.${binding.member}`;
412
- // Handle generic type arguments
413
- let typeArgsStr = "";
414
- if (expr.typeArguments && expr.typeArguments.length > 0) {
415
- if (expr.requiresSpecialization) {
416
- const [specializedName, specContext] = generateSpecializedName(finalCalleeName, expr.typeArguments, currentContext);
417
- finalCalleeName = specializedName;
418
- currentContext = specContext;
419
- }
420
- else {
421
- const [typeArgs, typeContext] = emitTypeArguments(expr.typeArguments, currentContext);
422
- typeArgsStr = typeArgs;
423
- currentContext = typeContext;
424
- }
425
- }
426
- const parameterTypes = expr.parameterTypes ?? [];
427
- const args = [receiverFrag.text];
428
- for (let i = 0; i < expr.arguments.length; i++) {
429
- const arg = expr.arguments[i];
430
- if (!arg)
431
- continue;
432
- const expectedType = parameterTypes[i];
433
- if (arg.kind === "spread") {
434
- const [spreadFrag, ctx] = emitExpression(arg.expression, currentContext);
435
- args.push(`params ${spreadFrag.text}`);
436
- currentContext = ctx;
437
- }
438
- else {
439
- const castModifier = getPassingModifierFromCast(arg);
440
- if (castModifier && isLValue(arg)) {
441
- const [argFrag, ctx] = emitExpression(arg, currentContext);
442
- args.push(`${castModifier} ${argFrag.text}`);
443
- currentContext = ctx;
444
- }
445
- else {
446
- const [argFrag, ctx] = emitExpression(arg, currentContext, expectedType);
447
- const passingMode = expr.argumentPassing?.[i];
448
- const prefix = passingMode && passingMode !== "value" && isLValue(arg)
449
- ? `${passingMode} `
450
- : "";
451
- args.push(`${prefix}${argFrag.text}`);
452
- currentContext = ctx;
453
- }
454
- }
455
- }
456
- const baseCallText = `${finalCalleeName}${typeArgsStr}(${args.join(", ")})`;
457
- // JS runtime helpers often return List<T> for array-like results, while the IR
458
- // models them as native CLR arrays. When the IR expects an array, coerce via
459
- // Enumerable.ToArray to preserve the IR contract.
460
- const callText = expr.inferredType?.kind === "arrayType"
461
- ? `global::System.Linq.Enumerable.ToArray(${baseCallText})`
462
- : baseCallText;
463
- const text = needsIntCast(expr, finalCalleeName)
464
- ? `(int)${callText}`
465
- : callText;
466
- return [{ text }, currentContext];
467
- }
468
- // Regular function call
469
- const [calleeFrag, newContext] = expr.callee.kind === "memberAccess"
470
- ? emitMemberAccess(expr.callee, context, "call")
471
- : emitExpression(expr.callee, context);
472
- let currentContext = newContext;
473
- // Handle generic type arguments
474
- let typeArgsStr = "";
475
- let finalCalleeName = calleeFrag.text;
476
- if (expr.typeArguments && expr.typeArguments.length > 0) {
477
- if (expr.requiresSpecialization) {
478
- // Monomorphisation: Generate specialized method name
479
- // e.g., process<string> → process__string
480
- const [specializedName, specContext] = generateSpecializedName(calleeFrag.text, expr.typeArguments, currentContext);
481
- finalCalleeName = specializedName;
482
- currentContext = specContext;
483
- }
484
- else {
485
- // Emit explicit type arguments for generic call
486
- // e.g., identity<string>(value)
487
- const [typeArgs, typeContext] = emitTypeArguments(expr.typeArguments, currentContext);
488
- typeArgsStr = typeArgs;
489
- currentContext = typeContext;
490
- }
491
- }
492
- // Get parameter types from IR (extracted from resolved signature in frontend)
493
- const parameterTypes = expr.parameterTypes ?? [];
494
- const args = [];
495
- for (let i = 0; i < expr.arguments.length; i++) {
496
- const arg = expr.arguments[i];
497
- if (!arg)
498
- continue; // Skip undefined (shouldn't happen in valid IR)
499
- // Get expected type for this argument from parameter types
500
- const expectedType = parameterTypes[i];
501
- if (arg.kind === "spread") {
502
- // Spread in function call
503
- const [spreadFrag, ctx] = emitExpression(arg.expression, currentContext);
504
- args.push(`params ${spreadFrag.text}`);
505
- currentContext = ctx;
506
- }
507
- else {
508
- // Check if this argument has an explicit `as out<T>` / `as ref<T>` / `as inref<T>` cast
509
- const castModifier = getPassingModifierFromCast(arg);
510
- if (castModifier && isLValue(arg)) {
511
- // Emit the expression without the cast wrapper, with the modifier prefix
512
- // For `value as out<int>`, emit `out value`
513
- const [argFrag, ctx] = emitExpression(arg, currentContext);
514
- args.push(`${castModifier} ${argFrag.text}`);
515
- currentContext = ctx;
516
- }
517
- else {
518
- const [argFrag, ctx] = emitExpression(arg, currentContext, expectedType);
519
- // Check if this argument needs ref/out/in prefix from function signature
520
- // Only add prefix if argument is an lvalue (identifier or member access)
521
- const passingMode = expr.argumentPassing?.[i];
522
- const prefix = passingMode && passingMode !== "value" && isLValue(arg)
523
- ? `${passingMode} `
524
- : "";
525
- args.push(`${prefix}${argFrag.text}`);
526
- currentContext = ctx;
527
- }
528
- }
529
- }
530
- // For member-access calls, the receiver parenthesization is already handled inside
531
- // `emitMemberAccess`. Wrapping the full `obj.Member` in parentheses can change meaning
532
- // in C# (e.g., `(obj.Member)()` attempts to invoke a delegate rather than calling a method).
533
- const calleeText = expr.callee.kind === "memberAccess"
534
- ? `${finalCalleeName}${typeArgsStr}`
535
- : formatPostfixExpressionText(expr.callee, `${finalCalleeName}${typeArgsStr}`);
536
- const callOp = expr.isOptional ? "?." : "";
537
- const callText = `${calleeText}${callOp}(${args.join(", ")})`;
538
- // Add cast if needed (e.g., Math.floor returning double but asserted as int)
539
- const text = needsIntCast(expr, finalCalleeName)
540
- ? `(int)${callText}`
541
- : callText;
542
- return [{ text }, currentContext];
543
- };
544
- /**
545
- * Check if a new expression is new List<T>([...]) with an array literal argument
546
- * This pattern should be emitted as collection initializer: new List<T> { ... }
547
- */
548
- const isListConstructorWithArrayLiteral = (expr) => {
549
- // Only apply to BCL List<T> so the rewrite is semantics-safe.
550
- // (We rely on List<T> having a parameterless ctor + Add for collection initializer.)
551
- const inferredType = expr.inferredType;
552
- if (inferredType?.kind !== "referenceType") {
553
- return false;
554
- }
555
- const typeId = inferredType.typeId;
556
- if (!typeId || !typeId.clrName.startsWith("System.Collections.Generic.List")) {
557
- return false;
558
- }
559
- // Must have exactly one type argument
560
- if (!expr.typeArguments || expr.typeArguments.length !== 1) {
561
- return false;
562
- }
563
- // Check if callee is identifier "List"
564
- if (expr.callee.kind !== "identifier" || expr.callee.name !== "List") {
565
- return false;
566
- }
567
- // Must have exactly one argument that is an array literal
568
- if (expr.arguments.length !== 1) {
569
- return false;
570
- }
571
- const arg = expr.arguments[0];
572
- if (!arg || arg.kind === "spread" || arg.kind !== "array") {
573
- return false;
574
- }
575
- // Collection initializers don't support spreads/holes, so reject them here.
576
- for (const element of arg.elements) {
577
- if (!element || element.kind === "spread") {
578
- return false;
579
- }
580
- }
581
- return true;
582
- };
583
- /**
584
- * Emit new List<T>([...]) as collection initializer: new List<T> { ... }
585
- *
586
- * Examples:
587
- * new List<int>([1, 2, 3]) → new List<int> { 1, 2, 3 }
588
- * new List<string>(["a", "b"]) → new List<string> { "a", "b" }
589
- * new List<User>([u1, u2]) → new List<User> { u1, u2 }
590
- */
591
- const emitListCollectionInitializer = (expr, context) => {
592
- let currentContext = context;
593
- const [calleeFrag, calleeContext] = emitExpression(expr.callee, currentContext);
594
- currentContext = calleeContext;
595
- // Handle generic type arguments consistently with emitNew()
596
- let typeArgsStr = "";
597
- let finalClassName = calleeFrag.text;
598
- if (expr.typeArguments && expr.typeArguments.length > 0) {
599
- if (expr.requiresSpecialization) {
600
- const [specializedName, specContext] = generateSpecializedName(calleeFrag.text, expr.typeArguments, currentContext);
601
- finalClassName = specializedName;
602
- currentContext = specContext;
603
- }
604
- else {
605
- const [typeArgs, typeContext] = emitTypeArguments(expr.typeArguments, currentContext);
606
- typeArgsStr = typeArgs;
607
- currentContext = typeContext;
608
- }
609
- }
610
- // Get the array literal argument
611
- const arrayLiteral = expr.arguments[0];
612
- // Emit each element
613
- const elements = [];
614
- for (const element of arrayLiteral.elements) {
615
- if (element === undefined) {
616
- continue; // Skip undefined slots (sparse arrays)
617
- }
618
- if (element.kind === "spread") {
619
- // Not supported (guarded by isListConstructorWithArrayLiteral)
620
- const [fallbackFrag, fallbackContext] = emitNew(expr, currentContext);
621
- return [fallbackFrag, fallbackContext];
622
- }
623
- else {
624
- const [elemFrag, ctx] = emitExpression(element, currentContext);
625
- elements.push(elemFrag.text);
626
- currentContext = ctx;
627
- }
628
- }
629
- // Use collection initializer syntax
630
- const text = elements.length === 0
631
- ? `new ${finalClassName}${typeArgsStr}()`
632
- : `new ${finalClassName}${typeArgsStr} { ${elements.join(", ")} }`;
633
- return [{ text }, currentContext];
634
- };
635
- /**
636
- * Check if a new expression is new Array<T>(size)
637
- * Returns the element type if it is, undefined otherwise
638
- */
639
- const isArrayConstructorCall = (expr) => {
640
- // Check if callee is identifier "Array"
641
- if (expr.callee.kind !== "identifier" || expr.callee.name !== "Array") {
642
- return false;
643
- }
644
- // Must have exactly one type argument
645
- if (!expr.typeArguments || expr.typeArguments.length !== 1) {
646
- return false;
647
- }
648
- return true;
649
- };
650
- /**
651
- * Emit new Array<T>(size) as new T[size]
652
- *
653
- * Examples:
654
- * new Array<int>(10) → new int[10]
655
- * new Array<string>(5) → new string[5]
656
- * new Array<User>(count) → new User[count]
657
- * new Array<int>() → new int[0]
658
- */
659
- const emitArrayConstructor = (expr, context) => {
660
- let currentContext = context;
661
- // Get the element type (verified by isArrayConstructorCall)
662
- const typeArgs = expr.typeArguments;
663
- const elementType = typeArgs?.[0];
664
- if (!elementType) {
665
- return [{ text: "new object[0]" }, currentContext];
666
- }
667
- const [elementTypeStr, typeContext] = emitType(elementType, currentContext);
668
- currentContext = typeContext;
669
- // Get the size argument (if any)
670
- let sizeStr = "0"; // Default to empty array if no size argument
671
- if (expr.arguments.length > 0) {
672
- const sizeArg = expr.arguments[0];
673
- if (sizeArg && sizeArg.kind !== "spread") {
674
- const [sizeFrag, sizeContext] = emitExpression(sizeArg, currentContext);
675
- sizeStr = sizeFrag.text;
676
- currentContext = sizeContext;
677
- }
678
- }
679
- const text = `new ${elementTypeStr}[${sizeStr}]`;
680
- return [{ text }, currentContext];
681
- };
682
- /**
683
- * Emit a new expression
684
- */
685
- export const emitNew = (expr, context) => {
686
- // Special case: new Array<T>(size) → new T[size]
687
- if (isArrayConstructorCall(expr)) {
688
- return emitArrayConstructor(expr, context);
689
- }
690
- // Special case: new List<T>([...]) → new List<T> { ... }
691
- if (isListConstructorWithArrayLiteral(expr)) {
692
- return emitListCollectionInitializer(expr, context);
693
- }
694
- const [calleeFrag, newContext] = emitExpression(expr.callee, context);
695
- let currentContext = newContext;
696
- // Handle generic type arguments
697
- let typeArgsStr = "";
698
- let finalClassName = calleeFrag.text;
699
- if (expr.typeArguments && expr.typeArguments.length > 0) {
700
- if (expr.requiresSpecialization) {
701
- // Monomorphisation: Generate specialized class name
702
- // e.g., new Box<string>() → new Box__string()
703
- const [specializedName, specContext] = generateSpecializedName(calleeFrag.text, expr.typeArguments, currentContext);
704
- finalClassName = specializedName;
705
- currentContext = specContext;
706
- }
707
- else {
708
- // Emit explicit type arguments for generic constructor
709
- // e.g., new Box<string>(value)
710
- const [typeArgs, typeContext] = emitTypeArguments(expr.typeArguments, currentContext);
711
- typeArgsStr = typeArgs;
712
- currentContext = typeContext;
713
- }
714
- }
715
- const args = [];
716
- const parameterTypes = expr.parameterTypes ?? [];
717
- for (let i = 0; i < expr.arguments.length; i++) {
718
- const arg = expr.arguments[i];
719
- if (!arg)
720
- continue;
721
- if (arg.kind === "spread") {
722
- const [spreadFrag, ctx] = emitExpression(arg.expression, currentContext);
723
- args.push(`params ${spreadFrag.text}`);
724
- currentContext = ctx;
725
- }
726
- else {
727
- const expectedType = parameterTypes[i];
728
- const castModifier = getPassingModifierFromCast(arg);
729
- if (castModifier && isLValue(arg)) {
730
- const [argFrag, ctx] = emitExpression(arg, currentContext);
731
- args.push(`${castModifier} ${argFrag.text}`);
732
- currentContext = ctx;
733
- }
734
- else {
735
- const [argFrag, ctx] = emitExpression(arg, currentContext, expectedType);
736
- const passingMode = expr.argumentPassing?.[i];
737
- const prefix = passingMode && passingMode !== "value" && isLValue(arg)
738
- ? `${passingMode} `
739
- : "";
740
- args.push(`${prefix}${argFrag.text}`);
741
- currentContext = ctx;
742
- }
743
- }
744
- }
745
- const text = `new ${finalClassName}${typeArgsStr}(${args.join(", ")})`;
746
- return [{ text }, currentContext];
747
- };
4
+ export { emitCall } from "./calls/call-emitter.js";
5
+ export { emitNew } from "./calls/new-emitter.js";
748
6
  //# sourceMappingURL=calls.js.map