@tsonic/emitter 0.0.62 → 0.0.64

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (520) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/adapter-generator.d.ts +5 -15
  3. package/dist/adapter-generator.d.ts.map +1 -1
  4. package/dist/adapter-generator.js +60 -53
  5. package/dist/adapter-generator.js.map +1 -1
  6. package/dist/contracts/backend-adapter.d.ts +36 -0
  7. package/dist/contracts/backend-adapter.d.ts.map +1 -0
  8. package/dist/contracts/backend-adapter.js +9 -0
  9. package/dist/contracts/backend-adapter.js.map +1 -0
  10. package/dist/contracts/emitter-contract.d.ts +54 -0
  11. package/dist/contracts/emitter-contract.d.ts.map +1 -0
  12. package/dist/contracts/emitter-contract.js +8 -0
  13. package/dist/contracts/emitter-contract.js.map +1 -0
  14. package/dist/contracts/import-classifier.d.ts +36 -0
  15. package/dist/contracts/import-classifier.d.ts.map +1 -0
  16. package/dist/contracts/import-classifier.js +9 -0
  17. package/dist/contracts/import-classifier.js.map +1 -0
  18. package/dist/core/{attributes.d.ts → format/attributes.d.ts} +9 -14
  19. package/dist/core/format/attributes.d.ts.map +1 -0
  20. package/dist/core/format/attributes.js +190 -0
  21. package/dist/core/format/attributes.js.map +1 -0
  22. package/dist/core/format/attributes.test.d.ts.map +1 -0
  23. package/dist/core/{attributes.test.js → format/attributes.test.js} +70 -32
  24. package/dist/core/format/attributes.test.js.map +1 -0
  25. package/dist/core/format/backend-ast/index.d.ts +7 -0
  26. package/dist/core/format/backend-ast/index.d.ts.map +1 -0
  27. package/dist/core/format/backend-ast/index.js +6 -0
  28. package/dist/core/format/backend-ast/index.js.map +1 -0
  29. package/dist/core/format/backend-ast/printer.d.ts +33 -0
  30. package/dist/core/format/backend-ast/printer.d.ts.map +1 -0
  31. package/dist/core/format/backend-ast/printer.js +1151 -0
  32. package/dist/core/format/backend-ast/printer.js.map +1 -0
  33. package/dist/core/format/backend-ast/types.d.ts +504 -0
  34. package/dist/core/format/backend-ast/types.d.ts.map +1 -0
  35. package/dist/core/format/backend-ast/types.js +13 -0
  36. package/dist/core/format/backend-ast/types.js.map +1 -0
  37. package/dist/core/format/backend-ast/utils.d.ts +26 -0
  38. package/dist/core/format/backend-ast/utils.d.ts.map +1 -0
  39. package/dist/core/format/backend-ast/utils.js +65 -0
  40. package/dist/core/format/backend-ast/utils.js.map +1 -0
  41. package/dist/core/{exports.d.ts → format/exports.d.ts} +2 -2
  42. package/dist/core/format/exports.d.ts.map +1 -0
  43. package/dist/core/format/exports.js +22 -0
  44. package/dist/core/format/exports.js.map +1 -0
  45. package/dist/core/format/index.d.ts +9 -0
  46. package/dist/core/format/index.d.ts.map +1 -0
  47. package/dist/core/format/index.js +9 -0
  48. package/dist/core/format/index.js.map +1 -0
  49. package/dist/core/{local-names.d.ts → format/local-names.d.ts} +1 -1
  50. package/dist/core/format/local-names.d.ts.map +1 -0
  51. package/dist/core/{local-names.js → format/local-names.js} +1 -1
  52. package/dist/core/format/local-names.js.map +1 -0
  53. package/dist/core/format/module-emitter/assembly.d.ts +27 -0
  54. package/dist/core/format/module-emitter/assembly.d.ts.map +1 -0
  55. package/dist/core/format/module-emitter/assembly.js +44 -0
  56. package/dist/core/format/module-emitter/assembly.js.map +1 -0
  57. package/dist/core/{module-emitter → format/module-emitter}/header.d.ts +1 -1
  58. package/dist/core/format/module-emitter/header.d.ts.map +1 -0
  59. package/dist/core/{module-emitter → format/module-emitter}/header.js +1 -1
  60. package/dist/core/format/module-emitter/header.js.map +1 -0
  61. package/dist/core/format/module-emitter/index.d.ts.map +1 -0
  62. package/dist/core/format/module-emitter/index.js.map +1 -0
  63. package/dist/core/format/module-emitter/namespace.d.ts +21 -0
  64. package/dist/core/format/module-emitter/namespace.d.ts.map +1 -0
  65. package/dist/core/format/module-emitter/namespace.js +58 -0
  66. package/dist/core/format/module-emitter/namespace.js.map +1 -0
  67. package/dist/core/{module-emitter → format/module-emitter}/orchestrator.d.ts +1 -1
  68. package/dist/core/format/module-emitter/orchestrator.d.ts.map +1 -0
  69. package/dist/core/{module-emitter → format/module-emitter}/orchestrator.js +19 -19
  70. package/dist/core/format/module-emitter/orchestrator.js.map +1 -0
  71. package/dist/core/format/module-emitter/separation.d.ts.map +1 -0
  72. package/dist/core/format/module-emitter/separation.js.map +1 -0
  73. package/dist/core/{module-emitter → format/module-emitter}/static-container.d.ts +8 -3
  74. package/dist/core/format/module-emitter/static-container.d.ts.map +1 -0
  75. package/dist/core/format/module-emitter/static-container.js +202 -0
  76. package/dist/core/format/module-emitter/static-container.js.map +1 -0
  77. package/dist/core/format/module-emitter.d.ts.map +1 -0
  78. package/dist/core/format/module-emitter.js.map +1 -0
  79. package/dist/core/{options.d.ts → format/options.d.ts} +1 -1
  80. package/dist/core/format/options.d.ts.map +1 -0
  81. package/dist/core/format/options.js.map +1 -0
  82. package/dist/core/index.d.ts +2 -7
  83. package/dist/core/index.d.ts.map +1 -1
  84. package/dist/core/index.js +2 -7
  85. package/dist/core/index.js.map +1 -1
  86. package/dist/core/semantic/boolean-context.d.ts +44 -0
  87. package/dist/core/semantic/boolean-context.d.ts.map +1 -0
  88. package/dist/core/semantic/boolean-context.js +717 -0
  89. package/dist/core/semantic/boolean-context.js.map +1 -0
  90. package/dist/core/semantic/boolean-context.test.d.ts.map +1 -0
  91. package/dist/core/{boolean-context.test.js → semantic/boolean-context.test.js} +86 -109
  92. package/dist/core/semantic/boolean-context.test.js.map +1 -0
  93. package/dist/core/{imports.d.ts → semantic/imports.d.ts} +1 -5
  94. package/dist/core/semantic/imports.d.ts.map +1 -0
  95. package/dist/core/{imports.js → semantic/imports.js} +56 -74
  96. package/dist/core/semantic/imports.js.map +1 -0
  97. package/dist/core/semantic/imports.test.d.ts.map +1 -0
  98. package/dist/core/semantic/imports.test.js +229 -0
  99. package/dist/core/semantic/imports.test.js.map +1 -0
  100. package/dist/core/semantic/index.d.ts +15 -0
  101. package/dist/core/semantic/index.d.ts.map +1 -0
  102. package/dist/core/semantic/index.js +15 -0
  103. package/dist/core/semantic/index.js.map +1 -0
  104. package/dist/core/{local-types.d.ts → semantic/local-types.d.ts} +1 -1
  105. package/dist/core/semantic/local-types.d.ts.map +1 -0
  106. package/dist/core/semantic/local-types.js.map +1 -0
  107. package/dist/core/{module-map.d.ts → semantic/module-map.d.ts} +1 -1
  108. package/dist/core/semantic/module-map.d.ts.map +1 -0
  109. package/dist/core/semantic/module-map.js.map +1 -0
  110. package/dist/core/semantic/module-map.test.d.ts.map +1 -0
  111. package/dist/core/semantic/module-map.test.js.map +1 -0
  112. package/dist/core/semantic/naming-collisions.d.ts.map +1 -0
  113. package/dist/core/{naming-collisions.js → semantic/naming-collisions.js} +1 -1
  114. package/dist/core/semantic/naming-collisions.js.map +1 -0
  115. package/dist/core/{type-alias-index.d.ts → semantic/type-alias-index.d.ts} +1 -1
  116. package/dist/core/semantic/type-alias-index.d.ts.map +1 -0
  117. package/dist/core/semantic/type-alias-index.js.map +1 -0
  118. package/dist/core/semantic/type-compatibility.d.ts.map +1 -0
  119. package/dist/core/semantic/type-compatibility.js.map +1 -0
  120. package/dist/core/{type-member-index.d.ts → semantic/type-member-index.d.ts} +1 -1
  121. package/dist/core/semantic/type-member-index.d.ts.map +1 -0
  122. package/dist/core/semantic/type-member-index.js.map +1 -0
  123. package/dist/core/semantic/type-params.d.ts.map +1 -0
  124. package/dist/core/semantic/type-params.js.map +1 -0
  125. package/dist/core/{type-resolution.d.ts → semantic/type-resolution.d.ts} +3 -6
  126. package/dist/core/semantic/type-resolution.d.ts.map +1 -0
  127. package/dist/core/{type-resolution.js → semantic/type-resolution.js} +15 -25
  128. package/dist/core/semantic/type-resolution.js.map +1 -0
  129. package/dist/core/semantic/type-resolution.test.d.ts.map +1 -0
  130. package/dist/core/{type-resolution.test.js → semantic/type-resolution.test.js} +11 -19
  131. package/dist/core/semantic/type-resolution.test.js.map +1 -0
  132. package/dist/core/semantic/unsafe.d.ts.map +1 -0
  133. package/dist/core/semantic/unsafe.js.map +1 -0
  134. package/dist/emitter-types/core.d.ts +6 -12
  135. package/dist/emitter-types/core.d.ts.map +1 -1
  136. package/dist/emitter-types/index.d.ts +1 -1
  137. package/dist/emitter-types/index.d.ts.map +1 -1
  138. package/dist/emitter-types/index.js.map +1 -1
  139. package/dist/emitter.d.ts +1 -1
  140. package/dist/emitter.d.ts.map +1 -1
  141. package/dist/emitter.js +9 -8
  142. package/dist/emitter.js.map +1 -1
  143. package/dist/expression-emitter.d.ts +10 -5
  144. package/dist/expression-emitter.d.ts.map +1 -1
  145. package/dist/expression-emitter.js +333 -117
  146. package/dist/expression-emitter.js.map +1 -1
  147. package/dist/expressions/access.d.ts +4 -3
  148. package/dist/expressions/access.d.ts.map +1 -1
  149. package/dist/expressions/access.js +252 -102
  150. package/dist/expressions/access.js.map +1 -1
  151. package/dist/expressions/calls/call-analysis.d.ts +86 -0
  152. package/dist/expressions/calls/call-analysis.d.ts.map +1 -0
  153. package/dist/expressions/calls/call-analysis.js +284 -0
  154. package/dist/expressions/calls/call-analysis.js.map +1 -0
  155. package/dist/expressions/calls/call-emitter.d.ts +13 -0
  156. package/dist/expressions/calls/call-emitter.d.ts.map +1 -0
  157. package/dist/expressions/calls/call-emitter.js +1048 -0
  158. package/dist/expressions/calls/call-emitter.js.map +1 -0
  159. package/dist/expressions/calls/new-emitter.d.ts +13 -0
  160. package/dist/expressions/calls/new-emitter.d.ts.map +1 -0
  161. package/dist/expressions/calls/new-emitter.js +641 -0
  162. package/dist/expressions/calls/new-emitter.js.map +1 -0
  163. package/dist/expressions/calls.d.ts +2 -14
  164. package/dist/expressions/calls.d.ts.map +1 -1
  165. package/dist/expressions/calls.js +2 -909
  166. package/dist/expressions/calls.js.map +1 -1
  167. package/dist/expressions/collections.d.ts +6 -16
  168. package/dist/expressions/collections.d.ts.map +1 -1
  169. package/dist/expressions/collections.js +318 -217
  170. package/dist/expressions/collections.js.map +1 -1
  171. package/dist/expressions/functions.d.ts +6 -5
  172. package/dist/expressions/functions.d.ts.map +1 -1
  173. package/dist/expressions/functions.js +57 -62
  174. package/dist/expressions/functions.js.map +1 -1
  175. package/dist/expressions/identifiers.d.ts +11 -6
  176. package/dist/expressions/identifiers.d.ts.map +1 -1
  177. package/dist/expressions/identifiers.js +76 -25
  178. package/dist/expressions/identifiers.js.map +1 -1
  179. package/dist/expressions/index.d.ts +1 -1
  180. package/dist/expressions/index.d.ts.map +1 -1
  181. package/dist/expressions/index.js +1 -1
  182. package/dist/expressions/index.js.map +1 -1
  183. package/dist/expressions/index.test.js +605 -0
  184. package/dist/expressions/index.test.js.map +1 -1
  185. package/dist/expressions/literals.d.ts +4 -3
  186. package/dist/expressions/literals.d.ts.map +1 -1
  187. package/dist/expressions/literals.js +25 -17
  188. package/dist/expressions/literals.js.map +1 -1
  189. package/dist/expressions/literals.test.js +18 -18
  190. package/dist/expressions/literals.test.js.map +1 -1
  191. package/dist/expressions/operators/assignment-emitter.d.ts +16 -0
  192. package/dist/expressions/operators/assignment-emitter.d.ts.map +1 -0
  193. package/dist/expressions/operators/assignment-emitter.js +118 -0
  194. package/dist/expressions/operators/assignment-emitter.js.map +1 -0
  195. package/dist/expressions/operators/binary-emitter.d.ts +33 -0
  196. package/dist/expressions/operators/binary-emitter.d.ts.map +1 -0
  197. package/dist/expressions/operators/binary-emitter.js +398 -0
  198. package/dist/expressions/operators/binary-emitter.js.map +1 -0
  199. package/dist/expressions/operators/conditional-emitter.d.ts +17 -0
  200. package/dist/expressions/operators/conditional-emitter.d.ts.map +1 -0
  201. package/dist/expressions/operators/conditional-emitter.js +306 -0
  202. package/dist/expressions/operators/conditional-emitter.js.map +1 -0
  203. package/dist/expressions/operators/helpers.d.ts +37 -0
  204. package/dist/expressions/operators/helpers.d.ts.map +1 -0
  205. package/dist/expressions/operators/helpers.js +136 -0
  206. package/dist/expressions/operators/helpers.js.map +1 -0
  207. package/dist/expressions/operators/logical-emitter.d.ts +23 -0
  208. package/dist/expressions/operators/logical-emitter.d.ts.map +1 -0
  209. package/dist/expressions/operators/logical-emitter.js +73 -0
  210. package/dist/expressions/operators/logical-emitter.js.map +1 -0
  211. package/dist/expressions/operators/unary-emitter.d.ts +30 -0
  212. package/dist/expressions/operators/unary-emitter.d.ts.map +1 -0
  213. package/dist/expressions/operators/unary-emitter.js +244 -0
  214. package/dist/expressions/operators/unary-emitter.js.map +1 -0
  215. package/dist/expressions/operators.d.ts +5 -81
  216. package/dist/expressions/operators.d.ts.map +1 -1
  217. package/dist/expressions/operators.js +5 -949
  218. package/dist/expressions/operators.js.map +1 -1
  219. package/dist/expressions/other.d.ts +15 -11
  220. package/dist/expressions/other.d.ts.map +1 -1
  221. package/dist/expressions/other.js +51 -36
  222. package/dist/expressions/other.js.map +1 -1
  223. package/dist/expressions/precedence.test.js +1 -1
  224. package/dist/expressions/precedence.test.js.map +1 -1
  225. package/dist/generator-exchange.d.ts +10 -3
  226. package/dist/generator-exchange.d.ts.map +1 -1
  227. package/dist/generator-exchange.js +57 -54
  228. package/dist/generator-exchange.js.map +1 -1
  229. package/dist/generator-wrapper.d.ts +17 -65
  230. package/dist/generator-wrapper.d.ts.map +1 -1
  231. package/dist/generator-wrapper.js +396 -220
  232. package/dist/generator-wrapper.js.map +1 -1
  233. package/dist/generator-wrapper.test.js +22 -14
  234. package/dist/generator-wrapper.test.js.map +1 -1
  235. package/dist/integration.test.js +169 -1
  236. package/dist/integration.test.js.map +1 -1
  237. package/dist/patterns.d.ts +18 -88
  238. package/dist/patterns.d.ts.map +1 -1
  239. package/dist/patterns.js +540 -304
  240. package/dist/patterns.js.map +1 -1
  241. package/dist/patterns.test.js +5 -4
  242. package/dist/patterns.test.js.map +1 -1
  243. package/dist/specialization/generation.d.ts +7 -3
  244. package/dist/specialization/generation.d.ts.map +1 -1
  245. package/dist/specialization/generation.js +31 -15
  246. package/dist/specialization/generation.js.map +1 -1
  247. package/dist/specialization/type-aliases.test.js +47 -2
  248. package/dist/specialization/type-aliases.test.js.map +1 -1
  249. package/dist/statement-emitter.d.ts +15 -4
  250. package/dist/statement-emitter.d.ts.map +1 -1
  251. package/dist/statement-emitter.js +54 -47
  252. package/dist/statement-emitter.js.map +1 -1
  253. package/dist/statements/blocks.d.ts +24 -16
  254. package/dist/statements/blocks.d.ts.map +1 -1
  255. package/dist/statements/blocks.js +242 -65
  256. package/dist/statements/blocks.js.map +1 -1
  257. package/dist/statements/classes/index.d.ts +1 -1
  258. package/dist/statements/classes/index.d.ts.map +1 -1
  259. package/dist/statements/classes/index.js +1 -1
  260. package/dist/statements/classes/index.js.map +1 -1
  261. package/dist/statements/classes/inline-types.d.ts +4 -3
  262. package/dist/statements/classes/inline-types.d.ts.map +1 -1
  263. package/dist/statements/classes/inline-types.js +21 -21
  264. package/dist/statements/classes/inline-types.js.map +1 -1
  265. package/dist/statements/classes/members/constructors.d.ts +4 -3
  266. package/dist/statements/classes/members/constructors.d.ts.map +1 -1
  267. package/dist/statements/classes/members/constructors.js +57 -58
  268. package/dist/statements/classes/members/constructors.js.map +1 -1
  269. package/dist/statements/classes/members/methods.d.ts +4 -3
  270. package/dist/statements/classes/members/methods.d.ts.map +1 -1
  271. package/dist/statements/classes/members/methods.js +106 -101
  272. package/dist/statements/classes/members/methods.js.map +1 -1
  273. package/dist/statements/classes/members/orchestrator.d.ts +4 -3
  274. package/dist/statements/classes/members/orchestrator.d.ts.map +1 -1
  275. package/dist/statements/classes/members/orchestrator.js +2 -2
  276. package/dist/statements/classes/members/orchestrator.js.map +1 -1
  277. package/dist/statements/classes/members/properties.d.ts +4 -3
  278. package/dist/statements/classes/members/properties.d.ts.map +1 -1
  279. package/dist/statements/classes/members/properties.js +105 -88
  280. package/dist/statements/classes/members/properties.js.map +1 -1
  281. package/dist/statements/classes/members/shadowing.test.js +7 -2
  282. package/dist/statements/classes/members/shadowing.test.js.map +1 -1
  283. package/dist/statements/classes/members/static-readonly-properties.test.js +4 -1
  284. package/dist/statements/classes/members/static-readonly-properties.test.js.map +1 -1
  285. package/dist/statements/classes/parameters.d.ts +8 -10
  286. package/dist/statements/classes/parameters.d.ts.map +1 -1
  287. package/dist/statements/classes/parameters.js +30 -26
  288. package/dist/statements/classes/parameters.js.map +1 -1
  289. package/dist/statements/classes/properties.d.ts +4 -3
  290. package/dist/statements/classes/properties.d.ts.map +1 -1
  291. package/dist/statements/classes/properties.js +76 -50
  292. package/dist/statements/classes/properties.js.map +1 -1
  293. package/dist/statements/classes.d.ts +1 -1
  294. package/dist/statements/classes.d.ts.map +1 -1
  295. package/dist/statements/classes.js +1 -1
  296. package/dist/statements/classes.js.map +1 -1
  297. package/dist/statements/control/conditionals/guard-analysis.d.ts +169 -0
  298. package/dist/statements/control/conditionals/guard-analysis.d.ts.map +1 -0
  299. package/dist/statements/control/conditionals/guard-analysis.js +591 -0
  300. package/dist/statements/control/conditionals/guard-analysis.js.map +1 -0
  301. package/dist/statements/control/conditionals/if-emitter.d.ts +14 -0
  302. package/dist/statements/control/conditionals/if-emitter.d.ts.map +1 -0
  303. package/dist/statements/control/conditionals/if-emitter.js +725 -0
  304. package/dist/statements/control/conditionals/if-emitter.js.map +1 -0
  305. package/dist/statements/control/conditionals/switch-emitter.d.ts +13 -0
  306. package/dist/statements/control/conditionals/switch-emitter.d.ts.map +1 -0
  307. package/dist/statements/control/conditionals/switch-emitter.js +60 -0
  308. package/dist/statements/control/conditionals/switch-emitter.js.map +1 -0
  309. package/dist/statements/control/conditionals.d.ts +3 -15
  310. package/dist/statements/control/conditionals.d.ts.map +1 -1
  311. package/dist/statements/control/conditionals.js +3 -1152
  312. package/dist/statements/control/conditionals.js.map +1 -1
  313. package/dist/statements/control/exceptions.d.ts +8 -6
  314. package/dist/statements/control/exceptions.d.ts.map +1 -1
  315. package/dist/statements/control/exceptions.js +35 -23
  316. package/dist/statements/control/exceptions.js.map +1 -1
  317. package/dist/statements/control/index.d.ts +3 -3
  318. package/dist/statements/control/index.d.ts.map +1 -1
  319. package/dist/statements/control/index.js +3 -3
  320. package/dist/statements/control/index.js.map +1 -1
  321. package/dist/statements/control/loops.d.ts +14 -12
  322. package/dist/statements/control/loops.d.ts.map +1 -1
  323. package/dist/statements/control/loops.js +147 -82
  324. package/dist/statements/control/loops.js.map +1 -1
  325. package/dist/statements/control.d.ts +1 -1
  326. package/dist/statements/control.d.ts.map +1 -1
  327. package/dist/statements/control.js +1 -1
  328. package/dist/statements/control.js.map +1 -1
  329. package/dist/statements/declarations/classes.d.ts +7 -3
  330. package/dist/statements/declarations/classes.d.ts.map +1 -1
  331. package/dist/statements/declarations/classes.js +107 -83
  332. package/dist/statements/declarations/classes.js.map +1 -1
  333. package/dist/statements/declarations/enums.d.ts +4 -3
  334. package/dist/statements/declarations/enums.d.ts.map +1 -1
  335. package/dist/statements/declarations/enums.js +16 -15
  336. package/dist/statements/declarations/enums.js.map +1 -1
  337. package/dist/statements/declarations/functions.d.ts +18 -2
  338. package/dist/statements/declarations/functions.d.ts.map +1 -1
  339. package/dist/statements/declarations/functions.js +633 -162
  340. package/dist/statements/declarations/functions.js.map +1 -1
  341. package/dist/statements/declarations/index.d.ts +2 -2
  342. package/dist/statements/declarations/index.d.ts.map +1 -1
  343. package/dist/statements/declarations/index.js +2 -2
  344. package/dist/statements/declarations/index.js.map +1 -1
  345. package/dist/statements/declarations/interfaces.d.ts +7 -3
  346. package/dist/statements/declarations/interfaces.d.ts.map +1 -1
  347. package/dist/statements/declarations/interfaces.js +138 -105
  348. package/dist/statements/declarations/interfaces.js.map +1 -1
  349. package/dist/statements/declarations/type-aliases.d.ts +7 -3
  350. package/dist/statements/declarations/type-aliases.d.ts.map +1 -1
  351. package/dist/statements/declarations/type-aliases.js +122 -82
  352. package/dist/statements/declarations/type-aliases.js.map +1 -1
  353. package/dist/statements/declarations/variables.d.ts +12 -2
  354. package/dist/statements/declarations/variables.d.ts.map +1 -1
  355. package/dist/statements/declarations/variables.js +541 -428
  356. package/dist/statements/declarations/variables.js.map +1 -1
  357. package/dist/statements/declarations.d.ts +1 -1
  358. package/dist/statements/declarations.d.ts.map +1 -1
  359. package/dist/statements/declarations.js +1 -1
  360. package/dist/statements/declarations.js.map +1 -1
  361. package/dist/statements/index.d.ts +3 -3
  362. package/dist/statements/index.d.ts.map +1 -1
  363. package/dist/statements/index.js +5 -5
  364. package/dist/statements/index.js.map +1 -1
  365. package/dist/statements/index.test.js +307 -0
  366. package/dist/statements/index.test.js.map +1 -1
  367. package/dist/type-emitter.d.ts +1 -1
  368. package/dist/type-emitter.d.ts.map +1 -1
  369. package/dist/type-emitter.js +1 -1
  370. package/dist/type-emitter.js.map +1 -1
  371. package/dist/types/arrays.d.ts +3 -2
  372. package/dist/types/arrays.d.ts.map +1 -1
  373. package/dist/types/arrays.js +7 -5
  374. package/dist/types/arrays.js.map +1 -1
  375. package/dist/types/dictionaries.d.ts +6 -3
  376. package/dist/types/dictionaries.d.ts.map +1 -1
  377. package/dist/types/dictionaries.js +22 -10
  378. package/dist/types/dictionaries.js.map +1 -1
  379. package/dist/types/emitter.d.ts +8 -2
  380. package/dist/types/emitter.d.ts.map +1 -1
  381. package/dist/types/emitter.js +20 -6
  382. package/dist/types/emitter.js.map +1 -1
  383. package/dist/types/functions.d.ts +3 -2
  384. package/dist/types/functions.d.ts.map +1 -1
  385. package/dist/types/functions.js +36 -13
  386. package/dist/types/functions.js.map +1 -1
  387. package/dist/types/index.d.ts +2 -2
  388. package/dist/types/index.d.ts.map +1 -1
  389. package/dist/types/index.js +2 -2
  390. package/dist/types/index.js.map +1 -1
  391. package/dist/types/index.test.js +137 -0
  392. package/dist/types/index.test.js.map +1 -1
  393. package/dist/types/intersections.d.ts +3 -2
  394. package/dist/types/intersections.d.ts.map +1 -1
  395. package/dist/types/intersections.js +2 -2
  396. package/dist/types/intersections.js.map +1 -1
  397. package/dist/types/literals.d.ts +9 -2
  398. package/dist/types/literals.d.ts.map +1 -1
  399. package/dist/types/literals.js +11 -5
  400. package/dist/types/literals.js.map +1 -1
  401. package/dist/types/objects.d.ts +3 -2
  402. package/dist/types/objects.d.ts.map +1 -1
  403. package/dist/types/objects.js +1 -1
  404. package/dist/types/objects.js.map +1 -1
  405. package/dist/types/parameters.d.ts +6 -5
  406. package/dist/types/parameters.d.ts.map +1 -1
  407. package/dist/types/parameters.js +88 -29
  408. package/dist/types/parameters.js.map +1 -1
  409. package/dist/types/parameters.test.js +9 -4
  410. package/dist/types/parameters.test.js.map +1 -1
  411. package/dist/types/primitives.d.ts +5 -4
  412. package/dist/types/primitives.d.ts.map +1 -1
  413. package/dist/types/primitives.js +14 -13
  414. package/dist/types/primitives.js.map +1 -1
  415. package/dist/types/references.d.ts +3 -2
  416. package/dist/types/references.d.ts.map +1 -1
  417. package/dist/types/references.js +135 -111
  418. package/dist/types/references.js.map +1 -1
  419. package/dist/types/tuples.d.ts +3 -2
  420. package/dist/types/tuples.d.ts.map +1 -1
  421. package/dist/types/tuples.js +25 -11
  422. package/dist/types/tuples.js.map +1 -1
  423. package/dist/types/unions.d.ts +3 -2
  424. package/dist/types/unions.d.ts.map +1 -1
  425. package/dist/types/unions.js +36 -21
  426. package/dist/types/unions.js.map +1 -1
  427. package/dist/types.d.ts +1 -1
  428. package/dist/types.d.ts.map +1 -1
  429. package/dist/types.js.map +1 -1
  430. package/package.json +2 -2
  431. package/dist/core/attributes.d.ts.map +0 -1
  432. package/dist/core/attributes.js +0 -141
  433. package/dist/core/attributes.js.map +0 -1
  434. package/dist/core/attributes.test.d.ts.map +0 -1
  435. package/dist/core/attributes.test.js.map +0 -1
  436. package/dist/core/boolean-context.d.ts +0 -42
  437. package/dist/core/boolean-context.d.ts.map +0 -1
  438. package/dist/core/boolean-context.js +0 -442
  439. package/dist/core/boolean-context.js.map +0 -1
  440. package/dist/core/boolean-context.test.d.ts.map +0 -1
  441. package/dist/core/boolean-context.test.js.map +0 -1
  442. package/dist/core/exports.d.ts.map +0 -1
  443. package/dist/core/exports.js +0 -28
  444. package/dist/core/exports.js.map +0 -1
  445. package/dist/core/imports.d.ts.map +0 -1
  446. package/dist/core/imports.js.map +0 -1
  447. package/dist/core/imports.test.d.ts.map +0 -1
  448. package/dist/core/imports.test.js +0 -79
  449. package/dist/core/imports.test.js.map +0 -1
  450. package/dist/core/local-names.d.ts.map +0 -1
  451. package/dist/core/local-names.js.map +0 -1
  452. package/dist/core/local-types.d.ts.map +0 -1
  453. package/dist/core/local-types.js.map +0 -1
  454. package/dist/core/module-emitter/assembly.d.ts +0 -24
  455. package/dist/core/module-emitter/assembly.d.ts.map +0 -1
  456. package/dist/core/module-emitter/assembly.js +0 -69
  457. package/dist/core/module-emitter/assembly.js.map +0 -1
  458. package/dist/core/module-emitter/header.d.ts.map +0 -1
  459. package/dist/core/module-emitter/header.js.map +0 -1
  460. package/dist/core/module-emitter/index.d.ts.map +0 -1
  461. package/dist/core/module-emitter/index.js.map +0 -1
  462. package/dist/core/module-emitter/namespace.d.ts +0 -14
  463. package/dist/core/module-emitter/namespace.d.ts.map +0 -1
  464. package/dist/core/module-emitter/namespace.js +0 -26
  465. package/dist/core/module-emitter/namespace.js.map +0 -1
  466. package/dist/core/module-emitter/orchestrator.d.ts.map +0 -1
  467. package/dist/core/module-emitter/orchestrator.js.map +0 -1
  468. package/dist/core/module-emitter/separation.d.ts.map +0 -1
  469. package/dist/core/module-emitter/separation.js.map +0 -1
  470. package/dist/core/module-emitter/static-container.d.ts.map +0 -1
  471. package/dist/core/module-emitter/static-container.js +0 -139
  472. package/dist/core/module-emitter/static-container.js.map +0 -1
  473. package/dist/core/module-emitter.d.ts.map +0 -1
  474. package/dist/core/module-emitter.js.map +0 -1
  475. package/dist/core/module-map.d.ts.map +0 -1
  476. package/dist/core/module-map.js.map +0 -1
  477. package/dist/core/module-map.test.d.ts.map +0 -1
  478. package/dist/core/module-map.test.js.map +0 -1
  479. package/dist/core/naming-collisions.d.ts.map +0 -1
  480. package/dist/core/naming-collisions.js.map +0 -1
  481. package/dist/core/options.d.ts.map +0 -1
  482. package/dist/core/options.js.map +0 -1
  483. package/dist/core/type-alias-index.d.ts.map +0 -1
  484. package/dist/core/type-alias-index.js.map +0 -1
  485. package/dist/core/type-compatibility.d.ts.map +0 -1
  486. package/dist/core/type-compatibility.js.map +0 -1
  487. package/dist/core/type-member-index.d.ts.map +0 -1
  488. package/dist/core/type-member-index.js.map +0 -1
  489. package/dist/core/type-params.d.ts.map +0 -1
  490. package/dist/core/type-params.js.map +0 -1
  491. package/dist/core/type-resolution.d.ts.map +0 -1
  492. package/dist/core/type-resolution.js.map +0 -1
  493. package/dist/core/type-resolution.test.d.ts.map +0 -1
  494. package/dist/core/type-resolution.test.js.map +0 -1
  495. package/dist/core/unsafe.d.ts.map +0 -1
  496. package/dist/core/unsafe.js.map +0 -1
  497. /package/dist/core/{attributes.test.d.ts → format/attributes.test.d.ts} +0 -0
  498. /package/dist/core/{module-emitter → format/module-emitter}/index.d.ts +0 -0
  499. /package/dist/core/{module-emitter → format/module-emitter}/index.js +0 -0
  500. /package/dist/core/{module-emitter → format/module-emitter}/separation.d.ts +0 -0
  501. /package/dist/core/{module-emitter → format/module-emitter}/separation.js +0 -0
  502. /package/dist/core/{module-emitter.d.ts → format/module-emitter.d.ts} +0 -0
  503. /package/dist/core/{module-emitter.js → format/module-emitter.js} +0 -0
  504. /package/dist/core/{options.js → format/options.js} +0 -0
  505. /package/dist/core/{boolean-context.test.d.ts → semantic/boolean-context.test.d.ts} +0 -0
  506. /package/dist/core/{imports.test.d.ts → semantic/imports.test.d.ts} +0 -0
  507. /package/dist/core/{local-types.js → semantic/local-types.js} +0 -0
  508. /package/dist/core/{module-map.js → semantic/module-map.js} +0 -0
  509. /package/dist/core/{module-map.test.d.ts → semantic/module-map.test.d.ts} +0 -0
  510. /package/dist/core/{module-map.test.js → semantic/module-map.test.js} +0 -0
  511. /package/dist/core/{naming-collisions.d.ts → semantic/naming-collisions.d.ts} +0 -0
  512. /package/dist/core/{type-alias-index.js → semantic/type-alias-index.js} +0 -0
  513. /package/dist/core/{type-compatibility.d.ts → semantic/type-compatibility.d.ts} +0 -0
  514. /package/dist/core/{type-compatibility.js → semantic/type-compatibility.js} +0 -0
  515. /package/dist/core/{type-member-index.js → semantic/type-member-index.js} +0 -0
  516. /package/dist/core/{type-params.d.ts → semantic/type-params.d.ts} +0 -0
  517. /package/dist/core/{type-params.js → semantic/type-params.js} +0 -0
  518. /package/dist/core/{type-resolution.test.d.ts → semantic/type-resolution.test.d.ts} +0 -0
  519. /package/dist/core/{unsafe.d.ts → semantic/unsafe.d.ts} +0 -0
  520. /package/dist/core/{unsafe.js → semantic/unsafe.js} +0 -0
@@ -0,0 +1,1151 @@
1
+ /**
2
+ * Backend AST Printer
3
+ *
4
+ * Converts typed C# AST nodes into deterministic C# source text.
5
+ * Pure and stateless - no parsing, no string heuristics.
6
+ *
7
+ * Parenthesization is derived from operator precedence tables,
8
+ * not from advisory metadata on fragments.
9
+ */
10
+ // ============================================================
11
+ // C# reserved keywords for identifier escaping
12
+ // ============================================================
13
+ const CSHARP_KEYWORDS = new Set([
14
+ "abstract",
15
+ "as",
16
+ "bool",
17
+ "break",
18
+ "byte",
19
+ "case",
20
+ "catch",
21
+ "char",
22
+ "checked",
23
+ "class",
24
+ "const",
25
+ "continue",
26
+ "decimal",
27
+ "default",
28
+ "delegate",
29
+ "do",
30
+ "double",
31
+ "else",
32
+ "enum",
33
+ "event",
34
+ "explicit",
35
+ "extern",
36
+ "finally",
37
+ "fixed",
38
+ "float",
39
+ "for",
40
+ "foreach",
41
+ "goto",
42
+ "if",
43
+ "implicit",
44
+ "in",
45
+ "int",
46
+ "interface",
47
+ "internal",
48
+ "is",
49
+ "lock",
50
+ "long",
51
+ "namespace",
52
+ "new",
53
+ "null",
54
+ "object",
55
+ "operator",
56
+ "out",
57
+ "override",
58
+ "params",
59
+ "private",
60
+ "protected",
61
+ "public",
62
+ "readonly",
63
+ "ref",
64
+ "return",
65
+ "sbyte",
66
+ "sealed",
67
+ "short",
68
+ "sizeof",
69
+ "stackalloc",
70
+ "static",
71
+ "string",
72
+ "struct",
73
+ "switch",
74
+ "throw",
75
+ "try",
76
+ "typeof",
77
+ "uint",
78
+ "ulong",
79
+ "unchecked",
80
+ "unsafe",
81
+ "ushort",
82
+ "using",
83
+ "virtual",
84
+ "void",
85
+ "volatile",
86
+ "while",
87
+ ]);
88
+ /**
89
+ * C# predefined type keywords that should NOT be escaped with @
90
+ * when used in type position (they are the type name itself).
91
+ */
92
+ const PREDEFINED_TYPE_KEYWORDS = new Set([
93
+ "bool",
94
+ "byte",
95
+ "char",
96
+ "decimal",
97
+ "double",
98
+ "float",
99
+ "int",
100
+ "long",
101
+ "object",
102
+ "sbyte",
103
+ "short",
104
+ "string",
105
+ "uint",
106
+ "ulong",
107
+ "ushort",
108
+ "void",
109
+ "nint",
110
+ "nuint",
111
+ ]);
112
+ /**
113
+ * Escape a C# identifier if it's a keyword.
114
+ * Preserves predefined type keywords when used as types.
115
+ */
116
+ const escapeIdentifier = (name) => CSHARP_KEYWORDS.has(name) ? `@${name}` : name;
117
+ /**
118
+ * Escape segments in a qualified name (e.g. "global::Foo.stackalloc.Bar").
119
+ * The "global::" prefix and predefined type keywords are preserved.
120
+ */
121
+ const escapeQualifiedName = (name, preservePredefinedTypeKeywords = false) => {
122
+ const globalPrefix = "global::";
123
+ const hasGlobal = name.startsWith(globalPrefix);
124
+ const body = hasGlobal ? name.slice(globalPrefix.length) : name;
125
+ const escaped = body
126
+ .split(".")
127
+ .map((segment) => CSHARP_KEYWORDS.has(segment) &&
128
+ !(preservePredefinedTypeKeywords && PREDEFINED_TYPE_KEYWORDS.has(segment))
129
+ ? `@${segment}`
130
+ : segment)
131
+ .join(".");
132
+ return hasGlobal ? `${globalPrefix}${escaped}` : escaped;
133
+ };
134
+ // ============================================================
135
+ // Operator precedence for parenthesization
136
+ // ============================================================
137
+ /**
138
+ * C# operator precedence levels (higher = binds tighter).
139
+ * Used by the printer to insert parentheses only when necessary.
140
+ */
141
+ const getOperatorPrecedence = (op) => {
142
+ switch (op) {
143
+ // Assignment operators (lowest)
144
+ case "=":
145
+ case "+=":
146
+ case "-=":
147
+ case "*=":
148
+ case "/=":
149
+ case "%=":
150
+ case "&=":
151
+ case "|=":
152
+ case "^=":
153
+ case "<<=":
154
+ case ">>=":
155
+ case "??=":
156
+ return 1;
157
+ // Conditional ternary
158
+ // (handled separately, not via this function)
159
+ // Null-coalescing
160
+ case "??":
161
+ return 3;
162
+ // Logical OR
163
+ case "||":
164
+ return 4;
165
+ // Logical AND
166
+ case "&&":
167
+ return 5;
168
+ // Bitwise OR
169
+ case "|":
170
+ return 6;
171
+ // Bitwise XOR
172
+ case "^":
173
+ return 7;
174
+ // Bitwise AND
175
+ case "&":
176
+ return 8;
177
+ // Equality
178
+ case "==":
179
+ case "!=":
180
+ return 9;
181
+ // Relational (includes is, as - handled separately)
182
+ case "<":
183
+ case ">":
184
+ case "<=":
185
+ case ">=":
186
+ return 10;
187
+ // Shift
188
+ case "<<":
189
+ case ">>":
190
+ return 11;
191
+ // Additive
192
+ case "+":
193
+ case "-":
194
+ return 12;
195
+ // Multiplicative
196
+ case "*":
197
+ case "/":
198
+ case "%":
199
+ return 13;
200
+ default:
201
+ return 0;
202
+ }
203
+ };
204
+ /**
205
+ * Get the effective precedence of an expression for parenthesization decisions.
206
+ */
207
+ const getExpressionPrecedence = (expr) => {
208
+ switch (expr.kind) {
209
+ case "assignmentExpression":
210
+ return 1;
211
+ case "conditionalExpression":
212
+ return 2;
213
+ case "binaryExpression":
214
+ return getOperatorPrecedence(expr.operatorToken);
215
+ case "isExpression":
216
+ case "asExpression":
217
+ return 10; // Relational level
218
+ case "prefixUnaryExpression":
219
+ return 14; // Unary prefix
220
+ case "postfixUnaryExpression":
221
+ return 15; // Unary postfix
222
+ case "castExpression":
223
+ return 14; // Cast is at unary level
224
+ case "awaitExpression":
225
+ return 14; // Await is at unary level
226
+ // Primary expressions (highest precedence)
227
+ case "literalExpression":
228
+ case "identifierExpression":
229
+ case "parenthesizedExpression":
230
+ case "memberAccessExpression":
231
+ case "conditionalMemberAccessExpression":
232
+ case "elementAccessExpression":
233
+ case "conditionalElementAccessExpression":
234
+ case "invocationExpression":
235
+ case "objectCreationExpression":
236
+ case "arrayCreationExpression":
237
+ case "stackAllocArrayCreationExpression":
238
+ case "defaultExpression":
239
+ case "typeofExpression":
240
+ case "interpolatedStringExpression":
241
+ case "suppressNullableWarningExpression":
242
+ case "switchExpression":
243
+ return 16;
244
+ case "argumentModifierExpression":
245
+ return 16; // Argument modifier is used in argument position only
246
+ case "tupleExpression":
247
+ return 16; // Tuple literals are primary expressions
248
+ case "lambdaExpression":
249
+ return 0; // Lambda needs parens almost everywhere
250
+ case "throwExpression":
251
+ return 0; // Throw expression is very low precedence
252
+ default:
253
+ return 0;
254
+ }
255
+ };
256
+ /**
257
+ * Whether an expression needs parenthesization when used as an operand
258
+ * of a binary expression with the given parent precedence.
259
+ */
260
+ const needsParensInBinary = (child, parentPrecedence, isRightOperand) => {
261
+ const childPrec = getExpressionPrecedence(child);
262
+ if (childPrec < parentPrecedence)
263
+ return true;
264
+ // For same-precedence, right-associative operators (assignment)
265
+ // don't need parens on the right side
266
+ if (childPrec === parentPrecedence && isRightOperand) {
267
+ // Assignment is right-associative
268
+ if (child.kind === "assignmentExpression") {
269
+ return false;
270
+ }
271
+ // Associative operators at exclusive precedence levels: grouping doesn't
272
+ // change semantics, so right-side parens are unnecessary.
273
+ // Each of these operators is the sole occupant of its precedence level,
274
+ // so same-prec right child must be the same operator.
275
+ if (child.kind === "binaryExpression" &&
276
+ (child.operatorToken === "&&" ||
277
+ child.operatorToken === "||" ||
278
+ child.operatorToken === "|" ||
279
+ child.operatorToken === "&" ||
280
+ child.operatorToken === "^")) {
281
+ return false;
282
+ }
283
+ // Left-associative (and ?? for readability): right operand at same precedence needs parens
284
+ return true;
285
+ }
286
+ return false;
287
+ };
288
+ /**
289
+ * Wrap expression text in parens if needed for the given context.
290
+ */
291
+ const parenthesizeIfNeeded = (expr, parentPrecedence, isRightOperand) => {
292
+ const text = printExpression(expr);
293
+ return needsParensInBinary(expr, parentPrecedence, isRightOperand)
294
+ ? `(${text})`
295
+ : text;
296
+ };
297
+ // ============================================================
298
+ // Type Printer
299
+ // ============================================================
300
+ export const printType = (type) => {
301
+ switch (type.kind) {
302
+ case "predefinedType":
303
+ return type.keyword;
304
+ case "identifierType": {
305
+ const name = escapeQualifiedName(type.name, true);
306
+ if (!type.typeArguments || type.typeArguments.length === 0) {
307
+ return name;
308
+ }
309
+ const args = type.typeArguments.map(printType).join(", ");
310
+ return `${name}<${args}>`;
311
+ }
312
+ case "nullableType":
313
+ return `${printType(type.underlyingType)}?`;
314
+ case "arrayType": {
315
+ const elem = printType(type.elementType);
316
+ if (type.rank === 1) {
317
+ return `${elem}[]`;
318
+ }
319
+ const commas = ",".repeat(type.rank - 1);
320
+ return `${elem}[${commas}]`;
321
+ }
322
+ case "pointerType":
323
+ return `${printType(type.elementType)}*`;
324
+ case "tupleType": {
325
+ const elems = type.elements
326
+ .map((e) => e.name ? `${printType(e.type)} ${e.name}` : printType(e.type))
327
+ .join(", ");
328
+ return `(${elems})`;
329
+ }
330
+ case "varType":
331
+ return "var";
332
+ default: {
333
+ const exhaustiveCheck = type;
334
+ throw new Error(`ICE: Unhandled type AST kind: ${exhaustiveCheck.kind}`);
335
+ }
336
+ }
337
+ };
338
+ // ============================================================
339
+ // Expression Printer
340
+ // ============================================================
341
+ export const printExpression = (expr) => {
342
+ switch (expr.kind) {
343
+ case "literalExpression":
344
+ return expr.text;
345
+ case "identifierExpression":
346
+ return escapeIdentifier(expr.identifier);
347
+ case "parenthesizedExpression":
348
+ return `(${printExpression(expr.expression)})`;
349
+ case "memberAccessExpression":
350
+ return `${printPrimaryExpression(expr.expression)}.${escapeIdentifier(expr.memberName)}`;
351
+ case "conditionalMemberAccessExpression":
352
+ return `${printPrimaryExpression(expr.expression)}?.${escapeIdentifier(expr.memberName)}`;
353
+ case "elementAccessExpression": {
354
+ const args = expr.arguments.map(printExpression).join(", ");
355
+ return `${printPrimaryExpression(expr.expression)}[${args}]`;
356
+ }
357
+ case "conditionalElementAccessExpression": {
358
+ const args = expr.arguments.map(printExpression).join(", ");
359
+ return `${printPrimaryExpression(expr.expression)}?[${args}]`;
360
+ }
361
+ case "invocationExpression": {
362
+ const callee = printPrimaryExpression(expr.expression);
363
+ const typeArgs = expr.typeArguments && expr.typeArguments.length > 0
364
+ ? `<${expr.typeArguments.map(printType).join(", ")}>`
365
+ : "";
366
+ const args = expr.arguments.map(printExpression).join(", ");
367
+ return `${callee}${typeArgs}(${args})`;
368
+ }
369
+ case "objectCreationExpression": {
370
+ const typeName = printType(expr.type);
371
+ const args = expr.arguments.map(printExpression).join(", ");
372
+ const init = expr.initializer && expr.initializer.length > 0
373
+ ? ` { ${expr.initializer.map(printExpression).join(", ")} }`
374
+ : "";
375
+ // Omit () when using collection/object initializer with no constructor args
376
+ // (C# allows `new List<T> { ... }` without parentheses)
377
+ const argsSection = expr.initializer && expr.initializer.length > 0 && args.length === 0
378
+ ? ""
379
+ : `(${args})`;
380
+ return `new ${typeName}${argsSection}${init}`;
381
+ }
382
+ case "arrayCreationExpression": {
383
+ // varType element type → implicitly-typed new[] { ... }
384
+ const isImplicit = expr.elementType.kind === "varType";
385
+ const elemType = isImplicit ? "" : ` ${printType(expr.elementType)}`;
386
+ if (expr.initializer && expr.initializer.length > 0) {
387
+ const elems = expr.initializer.map(printExpression).join(", ");
388
+ if (expr.sizeExpression) {
389
+ return `new${elemType}[${printExpression(expr.sizeExpression)}] { ${elems} }`;
390
+ }
391
+ return `new${elemType}[] { ${elems} }`;
392
+ }
393
+ if (expr.sizeExpression) {
394
+ return `new${elemType}[${printExpression(expr.sizeExpression)}]`;
395
+ }
396
+ return `new${elemType}[0]`;
397
+ }
398
+ case "stackAllocArrayCreationExpression":
399
+ return `stackalloc ${printType(expr.elementType)}[${printExpression(expr.sizeExpression)}]`;
400
+ case "assignmentExpression": {
401
+ const left = printExpression(expr.left);
402
+ const right = printExpression(expr.right);
403
+ return `${left} ${expr.operatorToken} ${right}`;
404
+ }
405
+ case "binaryExpression": {
406
+ const prec = getOperatorPrecedence(expr.operatorToken);
407
+ const left = parenthesizeIfNeeded(expr.left, prec, false);
408
+ const right = parenthesizeIfNeeded(expr.right, prec, true);
409
+ return `${left} ${expr.operatorToken} ${right}`;
410
+ }
411
+ case "prefixUnaryExpression": {
412
+ const operand = printUnaryOperand(expr.operand, true);
413
+ // Operators like ++ and -- need no space, but ! and - do if operand starts with same char
414
+ if ((expr.operatorToken === "-" && operand.startsWith("-")) ||
415
+ (expr.operatorToken === "+" && operand.startsWith("+"))) {
416
+ return `${expr.operatorToken} ${operand}`;
417
+ }
418
+ return `${expr.operatorToken}${operand}`;
419
+ }
420
+ case "postfixUnaryExpression":
421
+ return `${printUnaryOperand(expr.operand, false)}${expr.operatorToken}`;
422
+ case "conditionalExpression": {
423
+ const cond = printExpression(expr.condition);
424
+ const whenTrue = printExpression(expr.whenTrue);
425
+ const whenFalse = printExpression(expr.whenFalse);
426
+ return `${cond} ? ${whenTrue} : ${whenFalse}`;
427
+ }
428
+ case "castExpression": {
429
+ const typeName = printType(expr.type);
430
+ const operand = printCastOperand(expr.expression);
431
+ return `(${typeName})${operand}`;
432
+ }
433
+ case "asExpression": {
434
+ const inner = printExpression(expr.expression);
435
+ return `${inner} as ${printType(expr.type)}`;
436
+ }
437
+ case "isExpression": {
438
+ const inner = printExpression(expr.expression);
439
+ const pattern = printPattern(expr.pattern);
440
+ return `${inner} is ${pattern}`;
441
+ }
442
+ case "defaultExpression":
443
+ return expr.type ? `default(${printType(expr.type)})` : "default";
444
+ case "awaitExpression":
445
+ return `await ${printUnaryOperand(expr.expression, true)}`;
446
+ case "lambdaExpression":
447
+ return printLambdaExpression(expr);
448
+ case "interpolatedStringExpression":
449
+ return printInterpolatedString(expr.parts);
450
+ case "throwExpression":
451
+ return `throw ${printExpression(expr.expression)}`;
452
+ case "suppressNullableWarningExpression":
453
+ return `${printPrimaryExpression(expr.expression)}!`;
454
+ case "typeofExpression":
455
+ return `typeof(${printType(expr.type)})`;
456
+ case "switchExpression":
457
+ return printSwitchExpression(expr);
458
+ case "argumentModifierExpression":
459
+ return `${expr.modifier} ${printExpression(expr.expression)}`;
460
+ case "tupleExpression": {
461
+ const elems = expr.elements.map(printExpression).join(", ");
462
+ return `(${elems})`;
463
+ }
464
+ default: {
465
+ const exhaustiveCheck = expr;
466
+ throw new Error(`ICE: Unhandled expression AST kind: ${exhaustiveCheck.kind}`);
467
+ }
468
+ }
469
+ };
470
+ /**
471
+ * Print an expression that appears in a "primary" position
472
+ * (before `.member`, `[index]`, `(args)`, etc.).
473
+ * Wraps in parens if needed.
474
+ */
475
+ const printPrimaryExpression = (expr) => {
476
+ const text = printExpression(expr);
477
+ const prec = getExpressionPrecedence(expr);
478
+ // Primary position requires precedence >= 15 (postfix and primary)
479
+ // or the expression is already a parenthesized/literal/identifier
480
+ if (prec >= 15)
481
+ return text;
482
+ if (expr.kind === "parenthesizedExpression" ||
483
+ expr.kind === "literalExpression" ||
484
+ expr.kind === "identifierExpression" ||
485
+ expr.kind === "defaultExpression" ||
486
+ expr.kind === "typeofExpression" ||
487
+ expr.kind === "interpolatedStringExpression" ||
488
+ expr.kind === "objectCreationExpression" ||
489
+ expr.kind === "arrayCreationExpression") {
490
+ return text;
491
+ }
492
+ return `(${text})`;
493
+ };
494
+ /**
495
+ * Print an expression that appears as a unary operand.
496
+ */
497
+ const printUnaryOperand = (expr, isPrefix) => {
498
+ const text = printExpression(expr);
499
+ const prec = getExpressionPrecedence(expr);
500
+ if (isPrefix) {
501
+ // Prefix unary needs operand to be at least unary precedence
502
+ return prec >= 14 ? text : `(${text})`;
503
+ }
504
+ // Postfix unary needs primary expression
505
+ return prec >= 15 ? text : `(${text})`;
506
+ };
507
+ /**
508
+ * Print an expression that appears as a cast operand.
509
+ * Special rules: unary minus after cast needs parens to avoid ambiguity.
510
+ */
511
+ const printCastOperand = (expr) => {
512
+ const text = printExpression(expr);
513
+ // Cast operand needs at least unary precedence
514
+ if (getExpressionPrecedence(expr) < 14) {
515
+ return `(${text})`;
516
+ }
517
+ // Special case: negative literals after cast need parens
518
+ // (int)-1 is ambiguous: could be cast or subtraction
519
+ if (expr.kind === "prefixUnaryExpression" && expr.operatorToken === "-") {
520
+ return `(${text})`;
521
+ }
522
+ if (expr.kind === "literalExpression" && text.startsWith("-")) {
523
+ return `(${text})`;
524
+ }
525
+ return text;
526
+ };
527
+ const printLambdaExpression = (expr) => {
528
+ const asyncPrefix = expr.isAsync ? "async " : "";
529
+ const params = printLambdaParameters(expr.parameters);
530
+ if (expr.body.kind === "blockStatement") {
531
+ if (expr.bodyIndent != null) {
532
+ // Multi-line block body with flat-block convention (braces + body at same indent)
533
+ return `${asyncPrefix}${params} =>\n${printStatementFlatBlock(expr.body, expr.bodyIndent)}`;
534
+ }
535
+ // Inline single-line block body: () => { stmt1; stmt2; }
536
+ const stmts = expr.body.statements
537
+ .map((s) => printStatement(s, ""))
538
+ .join(" ");
539
+ return `${asyncPrefix}${params} => { ${stmts} }`;
540
+ }
541
+ return `${asyncPrefix}${params} => ${printExpression(expr.body)}`;
542
+ };
543
+ const printLambdaParameters = (params) => {
544
+ const sole = params.length === 1 ? params[0] : undefined;
545
+ if (sole && !sole.type && !sole.modifier) {
546
+ return escapeIdentifier(sole.name);
547
+ }
548
+ const parts = params.map((p) => {
549
+ const mod = p.modifier ? `${p.modifier} ` : "";
550
+ return p.type
551
+ ? `${mod}${printType(p.type)} ${escapeIdentifier(p.name)}`
552
+ : `${mod}${escapeIdentifier(p.name)}`;
553
+ });
554
+ return `(${parts.join(", ")})`;
555
+ };
556
+ const printInterpolatedString = (parts) => {
557
+ const inner = parts
558
+ .map((part) => {
559
+ if (part.kind === "text")
560
+ return part.text;
561
+ const exprText = printExpression(part.expression);
562
+ // Wrap in parens if the expression text contains ':' to prevent
563
+ // C# from interpreting it as a format specifier delimiter.
564
+ // Common case: global::Namespace.Type, ternary a ? b : c
565
+ const safeText = exprText.includes(":") ? `(${exprText})` : exprText;
566
+ return part.formatClause
567
+ ? `{${safeText}:${part.formatClause}}`
568
+ : `{${safeText}}`;
569
+ })
570
+ .join("");
571
+ return `$"${inner}"`;
572
+ };
573
+ const printSwitchExpression = (expr) => {
574
+ const gov = printExpression(expr.governingExpression);
575
+ const arms = expr.arms.map(printSwitchExpressionArm).join(", ");
576
+ return `${gov} switch { ${arms} }`;
577
+ };
578
+ const printSwitchExpressionArm = (arm) => {
579
+ const pattern = printPattern(arm.pattern);
580
+ const whenClause = arm.whenClause
581
+ ? ` when ${printExpression(arm.whenClause)}`
582
+ : "";
583
+ const result = printExpression(arm.expression);
584
+ return `${pattern}${whenClause} => ${result}`;
585
+ };
586
+ // ============================================================
587
+ // Pattern Printer
588
+ // ============================================================
589
+ export const printPattern = (pattern) => {
590
+ switch (pattern.kind) {
591
+ case "typePattern":
592
+ return printType(pattern.type);
593
+ case "declarationPattern":
594
+ return `${printType(pattern.type)} ${escapeIdentifier(pattern.designation)}`;
595
+ case "varPattern":
596
+ return `var ${escapeIdentifier(pattern.designation)}`;
597
+ case "constantPattern":
598
+ return printExpression(pattern.expression);
599
+ case "discardPattern":
600
+ return "_";
601
+ case "negatedPattern":
602
+ return `not ${printPattern(pattern.pattern)}`;
603
+ default: {
604
+ const exhaustiveCheck = pattern;
605
+ throw new Error(`ICE: Unhandled pattern AST kind: ${exhaustiveCheck.kind}`);
606
+ }
607
+ }
608
+ };
609
+ // ============================================================
610
+ // Statement Printer
611
+ // ============================================================
612
+ export const printStatement = (stmt, indent) => {
613
+ switch (stmt.kind) {
614
+ case "blockStatement":
615
+ return printBlockStatement(stmt, indent);
616
+ case "localDeclarationStatement": {
617
+ const mods = stmt.modifiers.length > 0 ? `${stmt.modifiers.join(" ")} ` : "";
618
+ const typeStr = printType(stmt.type);
619
+ const decls = stmt.declarators
620
+ .map((d) => d.initializer
621
+ ? `${escapeIdentifier(d.name)} = ${printExpression(d.initializer)}`
622
+ : escapeIdentifier(d.name))
623
+ .join(", ");
624
+ return `${indent}${mods}${typeStr} ${decls};`;
625
+ }
626
+ case "localFunctionStatement": {
627
+ const mods = stmt.modifiers.length > 0 ? `${stmt.modifiers.join(" ")} ` : "";
628
+ const ret = printType(stmt.returnType);
629
+ const typeParams = stmt.typeParameters && stmt.typeParameters.length > 0
630
+ ? `<${stmt.typeParameters.join(", ")}>`
631
+ : "";
632
+ const params = stmt.parameters.map(printParameter).join(", ");
633
+ const body = printBlockStatement(stmt.body, indent);
634
+ return `${indent}${mods}${ret} ${escapeIdentifier(stmt.name)}${typeParams}(${params})\n${body}`;
635
+ }
636
+ case "expressionStatement":
637
+ return `${indent}${printExpression(stmt.expression)};`;
638
+ case "ifStatement":
639
+ return printIfStatement(stmt, indent);
640
+ case "whileStatement": {
641
+ const cond = printExpression(stmt.condition);
642
+ const body = printStatement(stmt.body, indent);
643
+ return `${indent}while (${cond})\n${body}`;
644
+ }
645
+ case "forStatement":
646
+ return printForStatement(stmt, indent);
647
+ case "foreachStatement": {
648
+ const awaitStr = stmt.isAwait ? "await " : "";
649
+ const typeStr = printType(stmt.type);
650
+ const ident = escapeIdentifier(stmt.identifier);
651
+ const collection = printExpression(stmt.expression);
652
+ const body = printStatement(stmt.body, indent);
653
+ return `${indent}${awaitStr}foreach (${typeStr} ${ident} in ${collection})\n${body}`;
654
+ }
655
+ case "switchStatement":
656
+ return printSwitchStatement(stmt, indent);
657
+ case "tryStatement":
658
+ return printTryStatement(stmt, indent);
659
+ case "throwStatement":
660
+ return stmt.expression
661
+ ? `${indent}throw ${printExpression(stmt.expression)};`
662
+ : `${indent}throw;`;
663
+ case "returnStatement":
664
+ return stmt.expression
665
+ ? `${indent}return ${printExpression(stmt.expression)};`
666
+ : `${indent}return;`;
667
+ case "breakStatement":
668
+ return `${indent}break;`;
669
+ case "continueStatement":
670
+ return `${indent}continue;`;
671
+ case "emptyStatement":
672
+ return `${indent};`;
673
+ case "yieldStatement":
674
+ if (stmt.isBreak) {
675
+ return `${indent}yield break;`;
676
+ }
677
+ return stmt.expression
678
+ ? `${indent}yield return ${printExpression(stmt.expression)};`
679
+ : `${indent}yield return;`;
680
+ default: {
681
+ const exhaustiveCheck = stmt;
682
+ throw new Error(`ICE: Unhandled statement AST kind: ${exhaustiveCheck.kind}`);
683
+ }
684
+ }
685
+ };
686
+ const printBlockStatement = (block, indent) => {
687
+ const innerIndent = indent + " ";
688
+ const stmts = block.statements
689
+ .map((s) => printStatement(s, innerIndent))
690
+ .join("\n");
691
+ return `${indent}{\n${stmts}\n${indent}}`;
692
+ };
693
+ const printIfStatement = (stmt, indent) => {
694
+ const cond = printExpression(stmt.condition);
695
+ const thenBody = printStatement(stmt.thenStatement, indent);
696
+ if (!stmt.elseStatement) {
697
+ return `${indent}if (${cond})\n${thenBody}`;
698
+ }
699
+ // Else-if chain: don't add extra indentation
700
+ if (stmt.elseStatement.kind === "ifStatement") {
701
+ const elseIfText = printIfStatement(stmt.elseStatement, indent);
702
+ // Strip the indent from the else-if since we're adding "else " prefix
703
+ const elseIfBody = elseIfText.slice(indent.length);
704
+ return `${indent}if (${cond})\n${thenBody}\n${indent}else ${elseIfBody}`;
705
+ }
706
+ const elseBody = printStatement(stmt.elseStatement, indent);
707
+ return `${indent}if (${cond})\n${thenBody}\n${indent}else\n${elseBody}`;
708
+ };
709
+ const printForStatement = (stmt, indent) => {
710
+ const parts = [];
711
+ // Initializer
712
+ if (stmt.declaration) {
713
+ const typeStr = printType(stmt.declaration.type);
714
+ const decls = stmt.declaration.declarators
715
+ .map((d) => d.initializer
716
+ ? `${escapeIdentifier(d.name)} = ${printExpression(d.initializer)}`
717
+ : escapeIdentifier(d.name))
718
+ .join(", ");
719
+ parts.push(`${typeStr} ${decls}`);
720
+ }
721
+ else if (stmt.initializers && stmt.initializers.length > 0) {
722
+ parts.push(stmt.initializers.map(printExpression).join(", "));
723
+ }
724
+ else {
725
+ parts.push("");
726
+ }
727
+ // Condition
728
+ parts.push(stmt.condition ? printExpression(stmt.condition) : "");
729
+ // Incrementors
730
+ parts.push(stmt.incrementors.map(printExpression).join(", "));
731
+ const header = parts.join("; ");
732
+ const body = printStatement(stmt.body, indent);
733
+ return `${indent}for (${header})\n${body}`;
734
+ };
735
+ const printSwitchStatement = (stmt, indent) => {
736
+ const expr = printExpression(stmt.expression);
737
+ const innerIndent = indent + " ";
738
+ const sections = stmt.sections
739
+ .map((s) => printSwitchSection(s, innerIndent))
740
+ .join("\n");
741
+ return `${indent}switch (${expr})\n${indent}{\n${sections}\n${indent}}`;
742
+ };
743
+ const printSwitchSection = (section, indent) => {
744
+ const labels = section.labels
745
+ .map((l) => printSwitchLabel(l, indent))
746
+ .join("\n");
747
+ const stmtIndent = indent + " ";
748
+ const stmts = section.statements
749
+ .map((s) => printStatement(s, stmtIndent))
750
+ .join("\n");
751
+ return `${labels}\n${stmts}`;
752
+ };
753
+ const printSwitchLabel = (label, indent) => {
754
+ switch (label.kind) {
755
+ case "caseSwitchLabel":
756
+ return `${indent}case ${printExpression(label.value)}:`;
757
+ case "casePatternSwitchLabel": {
758
+ const pattern = printPattern(label.pattern);
759
+ const when = label.whenClause
760
+ ? ` when ${printExpression(label.whenClause)}`
761
+ : "";
762
+ return `${indent}case ${pattern}${when}:`;
763
+ }
764
+ case "defaultSwitchLabel":
765
+ return `${indent}default:`;
766
+ }
767
+ };
768
+ const printTryStatement = (stmt, indent) => {
769
+ const tryBody = printBlockStatement(stmt.body, indent);
770
+ const catches = stmt.catches
771
+ .map((c) => printCatchClause(c, indent))
772
+ .join("\n");
773
+ const finallyStr = stmt.finallyBody
774
+ ? `\n${indent}finally\n${printBlockStatement(stmt.finallyBody, indent)}`
775
+ : "";
776
+ return `${indent}try\n${tryBody}\n${catches}${finallyStr}`;
777
+ };
778
+ const printCatchClause = (clause, indent) => {
779
+ const body = printBlockStatement(clause.body, indent);
780
+ if (!clause.type) {
781
+ return `${indent}catch\n${body}`;
782
+ }
783
+ const typeName = printType(clause.type);
784
+ const ident = clause.identifier
785
+ ? ` ${escapeIdentifier(clause.identifier)}`
786
+ : "";
787
+ const filter = clause.filter
788
+ ? ` when (${printExpression(clause.filter)})`
789
+ : "";
790
+ return `${indent}catch (${typeName}${ident})${filter}\n${body}`;
791
+ };
792
+ export const printParameter = (param) => {
793
+ const attrPrefix = param.attributes && param.attributes.length > 0
794
+ ? param.attributes
795
+ .map((a) => {
796
+ const targetPrefix = a.target ? `${a.target}: ` : "";
797
+ const args = a.arguments && a.arguments.length > 0
798
+ ? `(${a.arguments.map(printExpression).join(", ")})`
799
+ : "";
800
+ return `[${targetPrefix}${printType(a.type)}${args}]`;
801
+ })
802
+ .join("") + " "
803
+ : "";
804
+ const mods = param.modifiers && param.modifiers.length > 0
805
+ ? `${param.modifiers.join(" ")} `
806
+ : "";
807
+ const typeName = printType(param.type);
808
+ const name = escapeIdentifier(param.name);
809
+ const defaultVal = param.defaultValue
810
+ ? ` = ${printExpression(param.defaultValue)}`
811
+ : "";
812
+ return `${attrPrefix}${mods}${typeName} ${name}${defaultVal}`;
813
+ };
814
+ // ============================================================
815
+ // Declaration Printer
816
+ // ============================================================
817
+ export const printMember = (member, indent) => {
818
+ switch (member.kind) {
819
+ case "fieldDeclaration": {
820
+ const attrs = printAttributes(member.attributes, indent);
821
+ const mods = member.modifiers.length > 0 ? `${member.modifiers.join(" ")} ` : "";
822
+ const typeName = printType(member.type);
823
+ const name = escapeIdentifier(member.name);
824
+ const init = member.initializer
825
+ ? ` = ${printExpression(member.initializer)}`
826
+ : "";
827
+ return `${attrs}${indent}${mods}${typeName} ${name}${init};`;
828
+ }
829
+ case "propertyDeclaration": {
830
+ const attrs = printAttributes(member.attributes, indent);
831
+ const mods = member.modifiers.length > 0 ? `${member.modifiers.join(" ")} ` : "";
832
+ const typeName = printType(member.type);
833
+ const name = escapeIdentifier(member.name);
834
+ if (member.isAutoProperty) {
835
+ const getStr = member.hasGetter ? "get; " : "";
836
+ const setStr = member.hasInit
837
+ ? "init; "
838
+ : member.hasSetter
839
+ ? "set; "
840
+ : "";
841
+ const accessors = ` { ${getStr}${setStr}}`;
842
+ const init = member.initializer
843
+ ? ` = ${printExpression(member.initializer)};`
844
+ : "";
845
+ return `${attrs}${indent}${mods}${typeName} ${name}${accessors}${init}`;
846
+ }
847
+ // Explicit property accessors
848
+ const bodyIndent = indent + " ";
849
+ const accessorIndent = bodyIndent + " ";
850
+ const lines = [];
851
+ lines.push(`${attrs}${indent}${mods}${typeName} ${name}`);
852
+ lines.push(`${bodyIndent}{`);
853
+ if (member.getterBody) {
854
+ lines.push(`${bodyIndent}get`);
855
+ lines.push(printBlockStatement(member.getterBody, accessorIndent));
856
+ }
857
+ if (member.setterBody) {
858
+ lines.push(`${bodyIndent}set`);
859
+ lines.push(printBlockStatement(member.setterBody, accessorIndent));
860
+ }
861
+ lines.push(`${bodyIndent}}`);
862
+ return lines.join("\n");
863
+ }
864
+ case "methodDeclaration": {
865
+ const attrs = printAttributes(member.attributes, indent);
866
+ const mods = member.modifiers.length > 0 ? `${member.modifiers.join(" ")} ` : "";
867
+ const ret = printType(member.returnType);
868
+ const typeParams = printTypeParameters(member.typeParameters);
869
+ const params = member.parameters.map(printParameter).join(", ");
870
+ const constraints = printConstraints(member.constraints, indent);
871
+ if (member.expressionBody) {
872
+ return `${attrs}${indent}${mods}${ret} ${escapeIdentifier(member.name)}${typeParams}(${params})${constraints} => ${printExpression(member.expressionBody)};`;
873
+ }
874
+ if (member.body) {
875
+ return `${attrs}${indent}${mods}${ret} ${escapeIdentifier(member.name)}${typeParams}(${params})${constraints}\n${printBlockStatement(member.body, indent)}`;
876
+ }
877
+ // Abstract/interface method (no body)
878
+ return `${attrs}${indent}${mods}${ret} ${escapeIdentifier(member.name)}${typeParams}(${params})${constraints};`;
879
+ }
880
+ case "constructorDeclaration": {
881
+ const attrs = printAttributes(member.attributes, indent);
882
+ const mods = member.modifiers.length > 0 ? `${member.modifiers.join(" ")} ` : "";
883
+ const params = member.parameters.map(printParameter).join(", ");
884
+ const baseCall = member.baseArguments !== undefined
885
+ ? ` : base(${member.baseArguments.map(printExpression).join(", ")})`
886
+ : "";
887
+ return `${attrs}${indent}${mods}${escapeIdentifier(member.name)}(${params})${baseCall}\n${printBlockStatement(member.body, indent)}`;
888
+ }
889
+ case "delegateDeclaration": {
890
+ const mods = member.modifiers.length > 0 ? `${member.modifiers.join(" ")} ` : "";
891
+ const ret = printType(member.returnType);
892
+ const params = member.parameters.map(printParameter).join(", ");
893
+ return `${indent}${mods}delegate ${ret} ${escapeIdentifier(member.name)}(${params});`;
894
+ }
895
+ default: {
896
+ const exhaustiveCheck = member;
897
+ throw new Error(`ICE: Unhandled member AST kind: ${exhaustiveCheck.kind}`);
898
+ }
899
+ }
900
+ };
901
+ export const printTypeDeclaration = (decl, indent) => {
902
+ switch (decl.kind) {
903
+ case "classDeclaration":
904
+ case "structDeclaration":
905
+ case "interfaceDeclaration": {
906
+ const keyword = decl.kind === "classDeclaration"
907
+ ? "class"
908
+ : decl.kind === "structDeclaration"
909
+ ? "struct"
910
+ : "interface";
911
+ const attrs = printAttributes(decl.attributes, indent);
912
+ const mods = decl.modifiers.length > 0 ? `${decl.modifiers.join(" ")} ` : "";
913
+ const typeParams = printTypeParameters(decl.typeParameters);
914
+ const baseTypes = [];
915
+ if (decl.kind === "classDeclaration" && decl.baseType) {
916
+ baseTypes.push(printType(decl.baseType));
917
+ }
918
+ baseTypes.push(...decl.interfaces.map(printType));
919
+ const baseClause = baseTypes.length > 0 ? ` : ${baseTypes.join(", ")}` : "";
920
+ const constraints = printConstraints(decl.constraints, indent);
921
+ const innerIndent = indent + " ";
922
+ const members = decl.members
923
+ .map((m) => printMember(m, innerIndent))
924
+ .join("\n\n");
925
+ return `${attrs}${indent}${mods}${keyword} ${escapeIdentifier(decl.name)}${typeParams}${baseClause}${constraints}\n${indent}{\n${members}\n${indent}}`;
926
+ }
927
+ case "enumDeclaration": {
928
+ const attrs = printAttributes(decl.attributes, indent);
929
+ const mods = decl.modifiers.length > 0 ? `${decl.modifiers.join(" ")} ` : "";
930
+ const innerIndent = indent + " ";
931
+ const members = decl.members
932
+ .map((m) => printEnumMember(m, innerIndent))
933
+ .join(",\n");
934
+ return `${attrs}${indent}${mods}enum ${escapeIdentifier(decl.name)}\n${indent}{\n${members}\n${indent}}`;
935
+ }
936
+ default: {
937
+ const exhaustiveCheck = decl;
938
+ throw new Error(`ICE: Unhandled type declaration AST kind: ${exhaustiveCheck.kind}`);
939
+ }
940
+ }
941
+ };
942
+ const printEnumMember = (member, indent) => member.value
943
+ ? `${indent}${escapeIdentifier(member.name)} = ${printExpression(member.value)}`
944
+ : `${indent}${escapeIdentifier(member.name)}`;
945
+ const printTypeParameters = (typeParams) => {
946
+ if (!typeParams || typeParams.length === 0)
947
+ return "";
948
+ return `<${typeParams.map((tp) => tp.name).join(", ")}>`;
949
+ };
950
+ const printConstraints = (constraints, indent) => {
951
+ if (!constraints || constraints.length === 0)
952
+ return "";
953
+ const printConstraint = (constraint) => {
954
+ switch (constraint.kind) {
955
+ case "typeConstraint":
956
+ return printType(constraint.type);
957
+ case "classConstraint":
958
+ return "class";
959
+ case "structConstraint":
960
+ return "struct";
961
+ case "constructorConstraint":
962
+ return "new()";
963
+ default: {
964
+ const exhaustiveCheck = constraint;
965
+ throw new Error(`ICE: Unhandled type parameter constraint kind: ${exhaustiveCheck.kind}`);
966
+ }
967
+ }
968
+ };
969
+ return constraints
970
+ .map((c) => `\n${indent} where ${escapeIdentifier(c.typeParameter)} : ${c.constraints
971
+ .map(printConstraint)
972
+ .join(", ")}`)
973
+ .join("");
974
+ };
975
+ export const printAttributes = (attrs, indent) => {
976
+ if (attrs.length === 0)
977
+ return "";
978
+ return attrs
979
+ .map((a) => {
980
+ const targetPrefix = a.target ? `${a.target}: ` : "";
981
+ const args = a.arguments && a.arguments.length > 0
982
+ ? `(${a.arguments.map(printExpression).join(", ")})`
983
+ : "";
984
+ return `${indent}[${targetPrefix}${printType(a.type)}${args}]\n`;
985
+ })
986
+ .join("");
987
+ };
988
+ // ============================================================
989
+ // Compilation Unit Printer
990
+ // ============================================================
991
+ export const printCompilationUnit = (unit) => {
992
+ const parts = [];
993
+ if (unit.header) {
994
+ parts.push(unit.header);
995
+ }
996
+ const usings = unit.usings
997
+ .map((u) => `using ${escapeQualifiedName(u.namespace, false)};`)
998
+ .join("\n");
999
+ if (usings) {
1000
+ parts.push(usings);
1001
+ parts.push("");
1002
+ }
1003
+ const members = unit.members
1004
+ .map((m) => {
1005
+ if (m.kind === "namespaceDeclaration") {
1006
+ return printNamespaceDeclaration(m);
1007
+ }
1008
+ return printTypeDeclaration(m, "");
1009
+ })
1010
+ .join("\n\n");
1011
+ if (members) {
1012
+ parts.push(members);
1013
+ }
1014
+ return parts.join("\n");
1015
+ };
1016
+ const printNamespaceDeclaration = (ns) => {
1017
+ const name = escapeQualifiedName(ns.name, false);
1018
+ const members = ns.members
1019
+ .map((m) => printTypeDeclaration(m, " "))
1020
+ .join("\n\n");
1021
+ return `namespace ${name}\n{\n${members}\n}`;
1022
+ };
1023
+ // ============================================================
1024
+ // Flat Block Printer
1025
+ // ============================================================
1026
+ /**
1027
+ * Print a statement with "flat block" convention:
1028
+ * block braces and inner statements share the same indent level.
1029
+ *
1030
+ * Used by the static container's __TopLevel method and other contexts
1031
+ * where block bodies need Tsonic's flat-block formatting (braces at same
1032
+ * indent as inner statements, not C#-standard nested convention).
1033
+ *
1034
+ * For compound statements (if/while/for/foreach/switch/try), body blocks
1035
+ * are printed at indent+4 with flat block convention (braces and inner
1036
+ * statements at the same level).
1037
+ */
1038
+ export const printStatementFlatBlock = (stmt, indent) => {
1039
+ const bodyIndent = indent + " ";
1040
+ switch (stmt.kind) {
1041
+ case "blockStatement": {
1042
+ const inner = stmt.statements
1043
+ .map((s) => printStatementFlatBlock(s, indent))
1044
+ .join("\n");
1045
+ return `${indent}{\n${inner}\n${indent}}`;
1046
+ }
1047
+ case "ifStatement": {
1048
+ const cond = printExpression(stmt.condition);
1049
+ const thenBody = printStatementFlatBlock(stmt.thenStatement, bodyIndent);
1050
+ if (!stmt.elseStatement) {
1051
+ return `${indent}if (${cond})\n${thenBody}`;
1052
+ }
1053
+ // Else-if chain
1054
+ if (stmt.elseStatement.kind === "ifStatement") {
1055
+ const elseIfText = printStatementFlatBlock(stmt.elseStatement, indent);
1056
+ const elseIfBody = elseIfText.slice(indent.length);
1057
+ return `${indent}if (${cond})\n${thenBody}\n${indent}else ${elseIfBody}`;
1058
+ }
1059
+ const elseBody = printStatementFlatBlock(stmt.elseStatement, bodyIndent);
1060
+ return `${indent}if (${cond})\n${thenBody}\n${indent}else\n${elseBody}`;
1061
+ }
1062
+ case "whileStatement": {
1063
+ const cond = printExpression(stmt.condition);
1064
+ const body = printStatementFlatBlock(stmt.body, bodyIndent);
1065
+ return `${indent}while (${cond})\n${body}`;
1066
+ }
1067
+ case "forStatement": {
1068
+ const parts = [];
1069
+ if (stmt.declaration) {
1070
+ const typeStr = printType(stmt.declaration.type);
1071
+ const decls = stmt.declaration.declarators
1072
+ .map((d) => d.initializer
1073
+ ? `${escapeIdentifier(d.name)} = ${printExpression(d.initializer)}`
1074
+ : escapeIdentifier(d.name))
1075
+ .join(", ");
1076
+ parts.push(`${typeStr} ${decls}`);
1077
+ }
1078
+ else if (stmt.initializers && stmt.initializers.length > 0) {
1079
+ parts.push(stmt.initializers.map(printExpression).join(", "));
1080
+ }
1081
+ else {
1082
+ parts.push("");
1083
+ }
1084
+ parts.push(stmt.condition ? printExpression(stmt.condition) : "");
1085
+ parts.push(stmt.incrementors.map(printExpression).join(", "));
1086
+ const header = parts.join("; ");
1087
+ const body = printStatementFlatBlock(stmt.body, bodyIndent);
1088
+ return `${indent}for (${header})\n${body}`;
1089
+ }
1090
+ case "foreachStatement": {
1091
+ const awaitStr = stmt.isAwait ? "await " : "";
1092
+ const typeStr = printType(stmt.type);
1093
+ const ident = escapeIdentifier(stmt.identifier);
1094
+ const collection = printExpression(stmt.expression);
1095
+ const body = printStatementFlatBlock(stmt.body, bodyIndent);
1096
+ return `${indent}${awaitStr}foreach (${typeStr} ${ident} in ${collection})\n${body}`;
1097
+ }
1098
+ case "switchStatement": {
1099
+ const expr = printExpression(stmt.expression);
1100
+ const sections = stmt.sections
1101
+ .map((s) => {
1102
+ const labels = s.labels
1103
+ .map((l) => printSwitchLabel(l, bodyIndent))
1104
+ .join("\n");
1105
+ const stmtInd = bodyIndent + " ";
1106
+ const sectionStmts = s.statements
1107
+ .map((st) => printStatementFlatBlock(st, stmtInd))
1108
+ .join("\n");
1109
+ return `${labels}\n${sectionStmts}`;
1110
+ })
1111
+ .join("\n");
1112
+ return `${indent}switch (${expr})\n${indent}{\n${sections}\n${indent}}`;
1113
+ }
1114
+ case "tryStatement": {
1115
+ // Try/catch/finally bodies are at the SAME indent as the keyword
1116
+ // (the old text emitter did NOT call indent() for try/catch bodies)
1117
+ const tryBody = printStatementFlatBlock(stmt.body, indent);
1118
+ const catches = stmt.catches
1119
+ .map((c) => {
1120
+ const catchBody = printStatementFlatBlock(c.body, indent);
1121
+ if (!c.type) {
1122
+ return `${indent}catch\n${catchBody}`;
1123
+ }
1124
+ const typeName = printType(c.type);
1125
+ const ident = c.identifier
1126
+ ? ` ${escapeIdentifier(c.identifier)}`
1127
+ : "";
1128
+ const filter = c.filter ? ` when (${printExpression(c.filter)})` : "";
1129
+ return `${indent}catch (${typeName}${ident})${filter}\n${catchBody}`;
1130
+ })
1131
+ .join("\n");
1132
+ const finallyStr = stmt.finallyBody
1133
+ ? `\n${indent}finally\n${printStatementFlatBlock(stmt.finallyBody, indent)}`
1134
+ : "";
1135
+ return `${indent}try\n${tryBody}\n${catches}${finallyStr}`;
1136
+ }
1137
+ case "localFunctionStatement": {
1138
+ const mods = stmt.modifiers.length > 0 ? `${stmt.modifiers.join(" ")} ` : "";
1139
+ const ret = printType(stmt.returnType);
1140
+ const typeParams = stmt.typeParameters && stmt.typeParameters.length > 0
1141
+ ? `<${stmt.typeParameters.join(", ")}>`
1142
+ : "";
1143
+ const params = stmt.parameters.map(printParameter).join(", ");
1144
+ const body = printBlockStatement(stmt.body, indent);
1145
+ return `${indent}${mods}${ret} ${escapeIdentifier(stmt.name)}${typeParams}(${params})\n${body}`;
1146
+ }
1147
+ default:
1148
+ return printStatement(stmt, indent);
1149
+ }
1150
+ };
1151
+ //# sourceMappingURL=printer.js.map